Solving Invisible Geometry
Often when creating 3D code you seem to have all the code compiling correctly but you are still not able to see anything. There are a number of reasons that this may happen so I have created this check list for you to work through to resolve the problem:
- The very first thing you must do is check the debug output in Viz to make sure Direct3D is not sending you messages telling you what the problem is. To get this information you must be running DirectX in debug mode and using F5 (in Viz) and not the exclamation mark to run your code. A common message might be about a missing texture. I have updated my notes on checking hr values, see here
- Check your model is not out of view - this is the number one reason I have found for people not seeing their geometry. Make sure the camera is pointed at 0,0,0 and your model is positioned at 0,0,0 and is not too big. e.g. 1 by 1 by 1 is fine as a test. Remember z is into the world so position your camera back a bit e.g. 0,1,-3 and looking down z e.g. 0,0,1.
- Correct Winding - you must define your triangles by specifying vertex in clockwise order. This is essential because internally Direct3D knows that if the winding is counter clockwise the triangle must be facing away from the camera and so does not need rendering. Normally this is great as it speeds things up but if you have accidentally defined your vertex in the wrong order it will mean you will see nothing. Remember to define the clockwise order in terms of looking at the face head on. If baffled create an object out of paper and label it, then rotate it to see the correct vertex order.
- The DrawIndexedPrimitive call - make sure you are passing it the correct number of vertices and indices.
- Lighting - in order to see anything you must have the lights turned on (see exception below)! Make sure you have enabled lighting by calling gD3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE). You should also raise the level of your ambient light to see if the geometry is just too dark to see, this sets maximum ambient light: gD3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(255,255,255)); See the notes on lighting and on render states.
- Lighting - if you have a colour as part of your vertex format then you actually need to turn lighting off.
- Material - if your material is set to reflect no light you will not see your geometry. As a test set the diffuse and ambient colour components to their maximum. See the notes on materials.
- Near and far clipping planes - when you set up your projection matrix you define the range of world values you want to see. Anything closer than the near clipping plane will be invisible and anything further than the far clipping plane will be invisible. So for example if you have defined your clipping planes as being from 1.0 to 100 and your geometry is position at 200 (z) you will not see it as it is being clipped.
- Matrices - when you draw geometry you will have specified a projection matrix, a view matrix and a world matrix. Either one of these set incorrectly may cause the geometry to be off the screen. One point worth noting is that if you are rendering a number of entities and have forgotten to set the world matrix each time, the previous world matrix setting is used. You should generally: set the projection matrix once when initialising your game, set the view matrix only when the camera changes position and set the world matrix for positioning each object in your world. See the notes on matrices.
- Z Buffer - normally an incorrectly specified Z buffer will not cause invisible geometry but may cause horrible effects. Make sure you have turned the z buffer on and also that you are clearing it. See the notes on the z buffer
- All Direct3D calls that take an angle require the angle to be in radians not degrees which could be your problem. To convert see this answer.
- Check the return codes of all calls. You need to get used to doing this, if a return code fails it allows you to track the problem down to a single line of code.
- If all else fails use the debugger to step through your code line by line to make sure it is behaving as expected. See debugger keys for using the debugger in Viz.