Jump to content
  • Advertisement
Sign in to follow this  
yaroslavd

Meshes and the Programmable Pipeline

This topic is 4496 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys. I'm using C# and MDX. In my last project I used the fixed-function pipeline and the Mesh helper class, using Mesh.DrawSubset() to draw the Mesh. Now, however, I am using shaders and Mesh.DrawSubset() doesn't seem to work. I'm thinking this is because Mesh expects values like World and View in order to draw, when, of course, I'm not setting these, as I am doing all the transformations in a shader. I tried to draw the Vertex Buffer using this code:
obj.Shader.Effect.BeginPass(i);
_device.BeginScene();
_device.VertexFormat =
  obj.Mesh.VertexFormat;
_device.SetStreamSource(
  0, obj.Mesh.VertexBuffer,
  0, CustomVertex.PositionNormal.StrideSize);
_device.DrawPrimitives(
  PrimitiveType.TriangleStrip, 0, obj.Mesh.NumberFaces);
_device.EndScene();
obj.Shader.Effect.EndPass();

But I don't really know what I'm doing, I've always just used Mesh.DrawSubset(). The above code "sort of" works. I can see random vertices floating around and can tell that they are colored appropriately by the shader. However, the Mesh is a sphere and that is not at all what is drawn. What is drawn is literally a couple of specks in random places. So what can I do to draw a Mesh, or do I have to use an explicit vertex buffer and stuff?

Share this post


Link to post
Share on other sites
Advertisement
Just a guess since I don't deal with managed directx, but I'm fairly sure that meshes use index buffers as well, so you should set the index stream and use DrawIndexedPrimative.

Share this post


Link to post
Share on other sites
Hmm... Thanks. I tried this now:


obj.Shader.Effect.BeginPass(i);
_device.BeginScene();
//obj.Mesh.DrawSubset(0);
_device.VertexFormat =
obj.Mesh.VertexFormat;
_device.SetStreamSource(
0, obj.Mesh.VertexBuffer,
0, CustomVertex.PositionNormal.StrideSize);
_device.Indices = obj.Mesh.IndexBuffer;
_device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, obj.Mesh.NumberVertices, 0, obj.Mesh.NumberFaces);
_device.EndScene();
obj.Shader.Effect.EndPass();



Now I see nothing but black (the clear color).

Share this post


Link to post
Share on other sites
Tried setting the Lighting to false, didn't work. Tried changing the clear color to white, didn't work (well, the screen was clearing white alright, but the mesh wasn't drawn). And I didn't find a Material property (or anything similar) in Mesh.

Share this post


Link to post
Share on other sites
Well, I got it working in unmanaged, maybe you can compare and see what your doing wrong.


D3DDevice->SetRenderState(D3DRS_LIGHTING, false);

D3DDevice->BeginScene();

IDirect3DIndexBuffer9 *pIB;
pMesh->GetIndexBuffer(&pIB);
IDirect3DVertexBuffer9 *pVB;
pMesh->GetVertexBuffer(&pVB);

D3DDevice->SetIndices(pIB);
D3DDevice->SetStreamSource(0, pVB, 0, pMesh->GetNumBytesPerVertex());
D3DDevice->SetFVF(pMesh->GetFVF());
D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, pMesh->GetNumVertices(), 0, pMesh->GetNumFaces());
//pMesh->DrawSubset(0);
D3DDevice->EndScene();






Does it work if your not using your shader?

Share this post


Link to post
Share on other sites
The implementation of Mesh.DrawSubset() is similar to this:

1) Find the attributerange with the attribute ID you specify
2) Set the index buffer to the mesh index buffer
3) Set stream source 0 to the mesh vertex buffer
4) Set vertex declaration to mesh vertex declaration
5) Call DrawIndexedPrimitive() with the attributerange from 1

That's really all there's to it. It doesn't change any transformation state (the matrices you speak of), nor does it change any rendering state (materials, textures, etc).

If you see nothing when you draw the mesh now, but it worked before, then your shaders are wrong, or the data for the shaders is wrong. There's some small chance that things like the depth range or blending is wrong, too, but that should be easily checked.

To debug the "nothing draws" problems, I've taken to running the program in Pix, and capturing a frame. Then I find the DrawIndexedPrimitive() call, click the "render" tab, then click the device pointer in the command stream. This lets me inspect the entire device state, which will typically lead me to what the reason is it doesn't draw. It'll also allow me to inspect the vertex and index buffers, as well as the shaders -- pretty slick!

Share this post


Link to post
Share on other sites
Thanks. StormArmageddon, that's basically the code I tried using and nothing was drawing. HPplus, I tried drawing without the effect, with the same result. Also, the shader worked perfectly in FX Composer. Could it be the problem that the camera is inside the mesh? Basically, the camera is inside this spherical "arena" and both are centered at the origin.

Edit: I just ran the program through PIX, like you advised, and although this was my first time using the program, I was able to find that it is called DrawPrimitives 0 times. Interesting.

Share this post


Link to post
Share on other sites
Ok, I tried playing around with drawing the buffer directly and it "sort of" worked. I didn't look like I wanted it to, but with certain types of Primitives I tried it actually looked like a circle sometimes. Of course, sometimes when I played around with it, it made my system crash and corrupted the user config files, so I'm reluctant to do that again. I also started clearing the ZBuffer in addition to the Target, which enabled me to see the lines better. However, Mesh.DrawSubset(0) still doesn't display anything no matter how much I move/rotate the camera.

Edit, Mesh.DrawSubset(0) works. I am only able to see it when I move the camera way outward and then look back towards the center. However, it displays as some sort of cone-like figure instead of a circle. Hmmm...

[Edited by - yaroslavd on July 28, 2006 2:12:05 PM]

Share this post


Link to post
Share on other sites
If it shows up when you move the camera out a bunch it may have something to do with your projection and view matrixes. This is how the DX SDK samples set them up:


D3DXVECTOR3 eye(0.0, 0.0, -2*g_fObjectRadius);
D3DXVECTOR3 at(0.0, 0.0, 0.0);
D3DXVECTOR3 up(0.0, 1.0, 0.0);

D3DXMATRIX view;
D3DXMatrixLookAtLH(&view, &eye, &at, &up);

D3DXMATRIX project;
D3DXMatrixPerspectiveFovLH(&project, D3DX_PI/4, (float)x/y, g_fObjectRadius/64.0f, g_fObjectRadius*200.0f);



Try adjusting g_fObjectRadius and see if you can get it to show up.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!