What is the Xbox360's D3DRS_VIEWPORTENABLE equivalent on WinXP D3D9? - graphics

I am maintaining a multiplatform codebase for Xbox360 and WinXP. I am seeing an issue on the XP side that appears to be related to D3DRS_VIEWPORTENABLE on the Xbox360 version not having an equivalent on WinXP D3D9. This article had an interesting idea, but the only way to construct an identity matrix is to supply negative numbers to D3DVIEWPORT9::X and D3DVIEWPORT9::Height, but they are unsigned numbers. (I tried to put in negative numbers anyway, but nothing interesting happened.)
So, how does one emulate the behavior of D3DRS_VIEWPORTENABLE under WinXP/D3D9?
(For clarity, the result I'm seeing is that a 2d screen-aligned quad works fine on Xbox360 but is offset/stretched on WinXP. In fact, the (0, 0) starts in the center of the screen on WinXP instead of in the lower-left corner like on the Xbox360 as a result of applying the viewport transform.)
Update: I didn't have an Xbox360 devkit at the time I wrote up this question, but I've since gotten one. I commented out the disabling of the D3DRS_VIEWPORTENABLE state, and the exact same behavior resulted on the Xbox360 as on the WinXP build. So, there must be some DirectX magic to bridge the gap here for emulating D3DRS_VIEWPORTENABLE being turned off on WinXP.

Instead of thinking about how you could put negatives into the viewport matrix think about it from the projection matrix.
The viewport matrix is applied directly after the projection matrix. So if you imagine setting the viewport to identity and the multiply it with the wvp (world-view-projection) matrix. ie
world * view * projection * viewport
You can now set the viewport to anything you want.
Of course this isn't actually the best way to attack the problem either. Some drivers will probably make optimisations based upon entries in t e viewport (they may not actually do a matrix multiply, for one). I wouldn't personally use the above system I can foresee too many issues coming from it.
So where does that leave you?
Well actually its still pretty simple. If you multiply the projection matrix by a matrix that is the inverse of the viewport matrix then you will find that when the viewport "matrix" is applied they cancel each other out and you are left with the direct output of the projection. The viewport has now been, effectively, "disabled".

Related

Can I correct wrong focal point of the projector by software?

Is there a way to set multiple focal lengths with one projector and software?
As shown in the following illustration, the image from one projector is partially in focus and partially out of focus.
Assuming that the screen output from the projector is viewed with the camera again, is there a way to correct the part out of focus with software?
No this is not doable by SW only.
Because you would need to change the direction of light coming out from the projector's emitter so that after passing the optics will focus further away and SW can affect only Color change...
What you need is to tweak the projector optics changing the focal length of lenses. You can do that by adding another lens in front of projector (with the right focal length in the right distance). My bet you need concave lens (negative focal length) however You need to make sure the cooling of the projector itself will not be affected so it must not reflect too much light back, and also take in mind this will most likely create some color focusing problems. I would simply test this with holding such a lens in hand and see what happens with the image focus while moveing it ... however I got quite a lot of lenses at my disposal which I assume most people do not have.
However you can test this in SW by using any optic lab SW or even write you own and simulate the projector there ... after obtaining the proper parameters for your new lens you can purchase it at any optics (where eye glasses are made/sold) unless the focal length is not too weird...
Another option is to tweak the projectors lens system which is most likely a teleobjective so if you can slightly tweak the distance range between the lens mechanically which could do the trick however the lens movement range usually corresponds to their diameters and apertures so its possible such change will cut of some parts of screen (on the outer borders). Also this usually means loss of warranty as you need to mess up with the device itself and also if not done properly you could damage the lenses for good so I do not advise to do this unless really necessary.

Increasing OpenGL's far clip plane distance

I'm trying to make a C++ OpenGL representation of our Solar System as a way to teach myself OpenGL, so please keep your answers simple.
The problem I have is that planets are very far away, so everything else is beyond the clipping plane when viewing from any given planet. How do I move the clipping of C++ OpenGL 3.1 plane to, say, 2000000000? I'd prefer a simple code snippet if you can.
I've looked up SO and forum posts about this, but they're either so old that nothing applies (using legacy APIs or just dead links), or so complex that I can't work out what they're saying.
Clipping planes are defined by the perspective projection matrix.
If you use glFrustum, change the last argument passed to it to 2000000000.0.
If you use your own matrix, set 10th element of your matrix array to:
(2000000000.0+nearClippingPlane)/(nearClippingPlane-2000000000.0)
(the formula is (far+near)/(near-far))
and 14th to:
(-4000000000.0*nearClippingPlane)/(2000000000.0-nearClippingPlane)
(the formula is (-2.0*near*far)/(far-near))
2000000000 is very big value, however, so Z-fighting may occur if you add details such as mountains.

Z-fighting Direct3D9, only with dynamic buffer

I lock and fill a vertex buffer every frame in Direct3d9 with data from my blendshape code. My shading uses two steps, so I render once with one shader, then draw an additive blend with my other shader.
For reasons beyond me, the data in my vertex buffer is (apparently) slightly different between those two drawing calls, because I have flickering z-fighting where the second pass sometimes renders 'behind' the first.
This is all done in one thread, and the buffer is unlocked a long time before the render calls. Additionally, no changes to any shader instruction take place, so the data should be exactly the same in both calls. If the blendshape happens not to change, no z-fighting takes place.
For now I 'push' the depth a little in my shader, but this is a very inelegant solution.
Why might this data be changed? Why may DirectX make changes to the data in my buffer after I unlock it? Can I force it not to change it?
1st. Are you sure the data is really changed by D3D, or this is just assumption? I'm sure D3D doesn't change your data
2nd. As you said, you have two different shaders drawing your geometry. They mave have different transformation operations. Or because of optimization the transformation in your shaders could be different, thats why your transformed vertices may differ slightly (but enough for z-fighting). I suggest using two passes in one shader/technique.
Or if your still want to use two shaders, you better use shared code for transformation and other identitcal operation.
I can sure that the D3D runtime will not change any data you passed in by a vertex buffer, I did the same thing like you when render two layers terrain, no Z-fighting. But there are indeed some render states will change it while rasterizing the triangles into pixels, they're D3DRS_DEPTHBIAS and D3DRS_SLOPESCALEDEPTHBIAS in D3D9, or the equal values in D3D10_RASTERIZER_DESC structure. If these render states were changed, you should check them.
You also need to be sure that all of the transform matrices or other constants which do calculation with position in the shader are precisely equal, otherwise there will be z-fighting.
I suggest you use some graphic debugging tools to check it. You can use PIX, or PerfHUD or Nsight if you were using NVIDIA card.
I'm sorry for my poor English, it must be hard to understand. But I wish this could help you, thanks.

Best looking texture mapping for characters (NPCs, Enemies).

I'm making "dungeon master-like" game where corridors and objects will be models. I have everything completed, but the graphic part of the game missing. I also made test levels without texture.
I would like to know which texture mapping would be the best for a realistic look.
I was thinking about parallax mapping for walls and doors, normal mapping for objects like treasure and boxes.
What mapping should I choose for enemies, npcs?
I have never worked with HLSL before, so I want to be sure that I'll go straight ahead for my goal because I expect another hard work there.
The mapping to use depends on your tastes. But first of all implement diffuse color mapping and per pixel lights. When that is working add normal mapping. If still not satisfied, add parallax mapping.
Even better results than the combination of normal and parallax mapping can be achieved using DirectX 11 Tesselation and displacement mapping. But this is much more GPU intensive and may not work on older hardware.

Polygon Triangulation with Holes

I am looking for an algorithm or library (better) to break down a polygon into triangles. I will be using these triangles in a Direct3D application. What are the best available options?
Here is what I have found so far:
Ben Discoe's notes
FIST: Fast Industrial-Strength Triangulation of Polygons
I know that CGAL provides triangulation but am not sure if it supports holes.
I would really appreciate some opinions from people with prior experience in this area.
Edit: This is a 2D polygon.
To give you some more choices of libraries out there:
Polyboolean. I never tried this one, but it looks promising: http://www.complex-a5.ru/polyboolean/index.html
General Polygon Clipper. This one works very well in practice and does triangulation as well as clipping and holes holes: http://www.cs.man.ac.uk/~toby/alan/software/
My personal recommendation: Use the tesselation from the GLU (OpenGL Utility Library). The code is rock solid, faster than GPC and generates less triangles. You don't need an initialized OpenGL-Handle or anything like this to use the lib.
If you don't like the idea to include OpenGL system libs in a DirectX application there is a solution as well: Just download the SGI OpenGL reference implementation code and lift the triangulator from it. It just uses the OpenGL-Typedef names and a hand full of enums. That's it. You can extract the code and make a stand alone lib in an hour or two.
In general my advice would be to use something that alreay works and don't start to write your own triangulation.
It is tempting to roll your own if you have read about the ear-clipping or sweep-line algorithm, but fact is that computational geometry algorithms are incredible hard to write in a way that they work stable, never crash and always return a meaningful result. Numerical roundoff errors will accumulate and kill you in the end.
I wrote a triangulation algorithm in C for the company I work with. Getting the core algorithm working took two days. Getting it working with all kinds of degenerated inputs took another two years (I wasn't working fulltime on it, but trust me - I spent more time on it than I should have).
Jonathan Shewchuk's Triangle library is phenomenal; I've used it for automating triangulation in the past. You can ask it to attempt to avoid small/narrow triangles, etc., so you come up with "good" triangulations instead of just any triangulation.
CGAL has the tool you need:
Constrained Triangulations
You can simply provide boundaries of your polygon (incuding the boundaries of the holes) as constraints (the best would be that you insert all vertices, and then specify the constraints as pairs of Vertex_handles).
You can then tag the triangles of the triangulation by any traversal algorithm: start with a triangle incident to the infinite vertex and tag it as being outside, and each time you cross a constraint, switch to the opposite tag (inside if you were previously tagging the triangles as outsider, outside if you were tagging triangles as insider before).
I have found the poly2tri library to be exactly what I needed for triangulation. It produces a much cleaner mesh than other libraries I've tried (including libtess), and it does support holes as well. It's been converted to a bunch of languages. The license is New BSD, so you can use it in any project.
Poly2tri library on Google Code
try libtess2
https://code.google.com/p/libtess2/downloads/list
based on the original SGI GLU tesselator (with liberal licensing). Solves some memory management issues around lots of small mallocs.
You can add the holes relatively easily yourself. Basically triangulate to the convex hull of the input points, as per CGAL, and then delete any triangle whose incentre lies inside any of the hole polygons (or outside any of the external boundaries). When dealing with lots of holes in a large dataset, masking techniques may be used to significantly speed this process up.
edit: A common extension to this technique is to weed weak triangles on the hull, where the longest edge or smallest internal angle exceeds a given value. This will form a better concave hull.
I have implemented a 3D polygon triangulator in C# using the ear clipping method. It is easy to use, supports holes, is numerically robust, and supports aribtrary (not self-intersecting) convex/non-convex polygons.
This is a common problem in finite element analysis. It's called "automatic mesh generation". Google found this site with links to commercial and open source software. They usually presume some kind of CAD representation of the geometry to start.
Another option (with a very flexible license) is to port the algorithm from VTK:
vtkDelaunay2D
This algorithm works fairly well. Using it directly is possible, but requires links to VTK, which may have more overhead than you want (although it has many other nice features, as well).
It supports constraints (holes/boundaries/etc), as well as triangulating a surface that isn't necessarily in the XY plane. It also supports some features I haven't seen elsewhere (see the notes on Alpha values).

Resources