• FEATURED

View more

View more

View more

Image of the Day Submit

IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Check contents of a Vertex Buffer

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

27 replies to this topic

#1AussieSpoon  Members

Posted 13 January 2013 - 07:33 PM

Hello,

I am tringing to make a 2D sprite engine that uses a dynamic Vertex Buffer, but I can't tell if the way I'm adding vertex data to is is working. So I was wondering if there is any way I can use the Visual Studio 2010 debugger to find the value of each vetex in the Vertex buffer (to see if its being stored correctly)?

Just in case here is how I'm creating it:


//Called once during initialization
if(FAILED( g_pd3dDevice->CreateVertexBuffer( s_nBatchSize * 4 * sizeof( SpriteVertex ), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
D3DFVF_SPRITEVERTEX, D3DPOOL_DEFAULT, &m_pVB, NULL ) ) )

Here is how I'm putting data into it every frame:

SpriteVertex* pVertex;
m_pVB->Lock(nRenderOffset, nSpritesToLock*4, (void**)&pVertex, 0);

//Use these variables to set the 4 verticies for each sprite (quad)
//Set vertex 1
pVertex->vPos = D3DXVECTOR3(vPos.x - 0.5f, vPos.y - 0.5f, fDepth);
pVertex->Colour = tColour;
pVertex->u1 = pTexture->GetTextureUMin();
pVertex->v1 = pTexture->GetTextureVMin();
pVertex++;
//Set vertex 2
pVertex->vPos = D3DXVECTOR3(vPos.x+vSize.x - 0.5f, vPos.y - 0.5f, fDepth);
pVertex->Colour = tColour;
pVertex->u1 = pTexture->GetTextureUMax();
pVertex->v1 = pTexture->GetTextureVMin();
pVertex++;
//Set vertex 3
pVertex->vPos = D3DXVECTOR3(vPos.x - 0.5f, vPos.y+vSize.y - 0.5f, fDepth);
pVertex->Colour = tColour;
pVertex->u1 = pTexture->GetTextureUMin();
pVertex->v1 = pTexture->GetTextureVMax();
pVertex++;
//Set vertex
pVertex->vPos = D3DXVECTOR3(vPos.x+vSize.x - 0.5f, vPos.y+vSize.y - 0.5f, fDepth);
pVertex->Colour = tColour;
pVertex->u1 = pTexture->GetTextureUMax();
pVertex->v1 = pTexture->GetTextureVMax();
pVertex++;
}

m_pVB->Unlock();

This is using something Evil Steve posted here

#2Jason Z  Members

Posted 13 January 2013 - 08:29 PM

I'm not sure of the corresponding action in the graphics debugger (you mean VS2012, right?) but in PIX you could take a frame snapshot, and then go back through and analyze the contents of any resource that was used during that frame.  I think this should also be possible in the new version - but to be honest I haven't had a chance to use the new version yet...

Are you seeing behavior that makes you think it isn't working correctly?  You should be able to build some test code and see if the corresponding rendered output is correct given a specific input pattern.  Sometimes that is the best way I can find to test out my graphics related code.

Jason Zink :: DirectX MVP

Direct3D 11 engine on CodePlex: Hieroglyph 3

Games: Lunar Rift

#3AussieSpoon  Members

Posted 14 January 2013 - 12:58 AM

Are you seeing behavior that makes you think it isn't working correctly?

Well all the values are what they should be, but I'm just having trouble finding what part of the process isn't working. Nothing draws to the screen when I call drawIndexedPrimitive but the code is too big to put up here (I think)

The only way I have used VB's previously was by creating an array then using memcpy(); but I don't see how I can create an array out of the for loop I had above?

#4L. Spiro  Members

Posted 14 January 2013 - 05:42 AM

Put up a screenshot of all the PIX state values at the time of rendering.
Check the obvious: Is your viewport correct? Are your near/far planes correct? Is your culling correct? Is your depth negative when it should be positive or vice-versa? Is your world-view-project matrix orthogonal and correct? Is it of the correct handedness?

Post a PIX screenshot or 2 containing all of these values at the time of render.

L. Spiro

#5Jason Z  Members

Posted 14 January 2013 - 06:00 AM

Put up a screenshot of all the PIX state values at the time of rendering.
Check the obvious: Is your viewport correct? Are your near/far planes correct? Is your culling correct? Is your depth negative when it should be positive or vice-versa? Is your world-view-project matrix orthogonal and correct? Is it of the correct handedness?

Post a PIX screenshot or 2 containing all of these values at the time of render.

L. Spiro

This, plus are there other 'normal' draw calls that are working properly?  Or are none of them working as you expected?

Jason Zink :: DirectX MVP

Direct3D 11 engine on CodePlex: Hieroglyph 3

Games: Lunar Rift

#6NightCreature83  Members

Posted 14 January 2013 - 06:07 AM

If nothing draws make a PIX capture.
Find your drawcall for the sprite buffer then look at the mesh tab
In the mesh tab select the post VS tab and check whether the values there valid.
Also in the views above these tabs you can see what the vertex buffer looks like pre VS, post VS and what's in the viewport.

If stuff isn't showing up in the viewport then most likely one of your transforms or camera position is wrong or like mentioned above one of your renderderstates.
Also by clicking on one of the vertex numbers in the list you can debug the vertex or geometry shader associated with this draw call.

Edited by NightCreature83, 14 January 2013 - 06:10 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

#7AussieSpoon  Members

Posted 14 January 2013 - 06:28 AM

Put up a screenshot of all the PIX state values at the time of rendering.
Check the obvious: Is your viewport correct? Are your near/far planes correct? Is your culling correct? Is your depth negative when it should be positive or vice-versa? Is your world-view-project matrix orthogonal and correct? Is it of the correct handedness?

Post a PIX screenshot or 2 containing all of these values at the time of render.

L. Spiro

I've never used PIX, I have the SDK but have no idea how to use it? Do you mind explaining?

Yeah I havn't really touched the matrices, Stupid as this sounds I am just using the SetupMatracis();  from one of the SDK Tutorials, So it might be this.

How do I ensure the world view projection Matrix is Orthogonal and the correct handedness?

Currently I just have:

    D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
D3DXMatrixRotationX( &matWorld, timeGetTime() / 1000.0f );
g_pd3dDevice->SetTransform( D3DTS_WORLD,  &matWorld );

D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -70.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 800.0f / 600.0f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

All my depths are 0 (by default) , is this a problem?

I have :

g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

So I think it might be my matrices, so how do I ensure the world view projection Matrix is Orthogonal and the correct handedness?

Thanks

#8L. Spiro  Members

Posted 14 January 2013 - 06:36 AM

I've never used PIX, I have the SDK but have no idea how to use it? Do you mind explaining?
I just did: http://www.gamedev.net/topic/637219-particles-engine-and-slow-fps/#entry5021364

Also, your call to D3DXMatrixRotationX() is incorrect. It should be D3DXMatrixRotationZ().
Also your matrix is not orthogonal. Replace D3DXMatrixPerspectiveFovLH() with D3DXMatrixOrthoLH() or D3DXMatrixOrthoOffCenterLH().

L. Spiro

Edited by L. Spiro, 14 January 2013 - 06:38 AM.

#9AussieSpoon  Members

Posted 14 January 2013 - 07:07 AM

See below

Edited by AussieSpoon, 14 January 2013 - 07:19 AM.

#10L. Spiro  Members

Posted 14 January 2013 - 07:25 AM

Running under Microsoft® Visual Studio® causes the working directory to be changed to that of the project. For now you should just manually override that via SetCurrentDirectory() at run-time so that the directories will be the same regardless of from where you start the application.

Since you didn’t actually step into Frame 150 or Frame 67 there is no information contained in either of your screen shots. Fix the resource problem first and try again—this time actually go to a render call.

L. Spiro

#11AussieSpoon  Members

Posted 14 January 2013 - 07:27 AM

Ok I think I did this right,

and:

and:

The values do seem right so I'm not sure, what else is potentially wrong

Thanks

EDIT: Actually my index buffer has incorrect values, the array values I create are correct , then I just memcpy the array to a pointer. But the index buffer is wrong, so I will work on that

Edited by AussieSpoon, 14 January 2013 - 07:36 AM.

#12NightCreature83  Members

Posted 14 January 2013 - 09:51 AM

If you actually browse to your drawcall you can get a lot more detailed information about the vertex buffer, by doing what you are currently doing you will only see the input buffer not the transformed one after the VS has run. And it can well be that your input buffer is correct but the output of the vertex shader isn't, I am assuming you are using a vertex shader here. Even if you are not using a vertex shader looking at when the drawcall is submitted will give you an idea of whether your transforms are correctly transforming your vertices in the buffer. Also it will tell you whether they are within the viewport or not which can also affect what you see on screen.
So just hit the plus on that frame you captured and look through the drawcalls till you find something that is rendering with that vertex buffer. By the way if you extend the list of a frame it will show you which commands your are actually sending to the D3D runtime from your application. Hit F1 in pix and look for this subject in the help file "View Buffer Data" checking out subject "View Mesh Data" is also a good idea. You can find this in the DirectX Software Development Kit help file under:

-DirectX Software Development Kit
-Tools
-DirectX Performance Tools
-PIX
-Tutorials and Samples


Edited by NightCreature83, 14 January 2013 - 09:57 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

#13L. Spiro  Members

Posted 14 January 2013 - 12:47 PM

This is what I had in mind by a screenshot of PIX with actual information in it.

L. Spiro

#14AussieSpoon  Members

Posted 14 January 2013 - 08:12 PM

1st Draw Call (Pre VS):

1st Draw Call (Post VS):

2nd (Last) Draw Call (Both PreVS and Post VS are the same):

Device info:

The first Draw indexed primitive seems to have correct Position (not sure why there are 4 though) and Text Co-ord values but no colour values. (Am I reading that right?)

Then the 2nd draw call look completely wrong.

And I'm not sure what to look at for the device.

#15L. Spiro  Members

Posted 14 January 2013 - 11:56 PM

One problem at a time.

Do you think there is anything you can glean from that second draw call?

Why would the input buffer have positions all-0’s and the index buffer be fubar…?

L. Spiro

#16AussieSpoon  Members

Posted 15 January 2013 - 02:08 AM

Do you think there is anything you can glean from that second draw call?

Why would the input buffer have positions all-0’s and the index buffer be fubar…?

From what I can tell (since I've never used this before).

(Assumuming Prim = Primative ie. 1 triangle, VTX = Vertex and IDX = index)

Then the index buffer has the correct values, and the VB is using them the way I want. But the values of each Vertex are worng, also there is a 4th value for position and I'm not sure why. I'm using D3DXVECTOR3 so not sure if that has an extra value I am unaware of?

So I somehow have to find what is changing the values in the VB, right?

Thanks

#17NightCreature83  Members

Posted 15 January 2013 - 02:33 AM

You will always see 4 values in the position, internally setting a vector 4 is faster on most hardware then setting a vector 3, and thats why you see that fourth value.

It seems that you are overwriting your index buffer in between your draw calls, you might want to have a careful look at how you fill these. Also in the SetStreamSource call for the second draw is using an offset of 36 instead of 24 like the first one, why is this as that might be why you are skipping 2 verts at a time. Have a look at your vertex declarations in PIX as they will tell you what your stride size should be

Edited by NightCreature83, 15 January 2013 - 02:35 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

#18AussieSpoon  Members

Posted 15 January 2013 - 03:13 AM

It seems that you are overwriting your index buffer in between your draw calls, you might want to have a careful look at how you fill these. Also in the SetStreamSource call for the second draw is using an offset of 36 instead of 24 like the first one, why is this as that might be why you are skipping 2 verts at a time. Have a look at your vertex declarations in PIX as they will tell you what your stride size should be

My index buffer is only filled once, (During initialization)

Here is how I fill it

//Creation
if(FAILED( g_pd3dDevice->CreateIndexBuffer(s_nBatchSize * 6, 0,
D3DFMT_INDEX32, D3DPOOL_DEFAULT ,&m_pIB, NULL)))

//Filling only done once
// Lock the index buffer
VOID* pIndices;
m_pIB->Lock(0, s_nBatchSize * 6, (void**)&pIndices, 0);

uINT indices[s_nBatchSize * 6];//Because for a quad you need 4 verts and 6 indicies
uINT indexCounter = 0;//used to store a value that helps set the correct indicie value
for(uINT i = 0; i < s_nBatchSize * 6; i += 6)
{
//Set 6 values that use 4 verticies
//0, 1, 2  Triangle 1
indices[i + 0] = (indexCounter * 4 + 0);
indices[i + 1] = (indexCounter * 4 + 1);
indices[i + 2] = (indexCounter * 4 + 2);
//2, 1, 3  Triangle 2
indices[i + 3] = (indexCounter * 4 + 2);
indices[i + 4] = (indexCounter * 4 + 1);
indices[i + 5] = (indexCounter * 4 + 3);

//Increase the index counter to get the right values
++indexCounter;
}

memcpy(pIndices, indices, sizeof(indices) / sizeof(indices[0]));//sizeof(indices) / sizeof(indices[0]) = number of elements in the array

// Unlock it
m_pIB->Unlock();


Does that look right?

"second draw is using an offset of 36 instead of 24"

I can't figure this out, I don't know where the first one is coming from, it only gets called once per frame atm, so I have no idea what is calling it

g_pd3dDevice->SetStreamSource(0, m_pVB, nRenderOffset, sizeof( SpriteVertex ));

Interestingly though, sizeof (SpriteVetex) = 36 but when I put 24 in there instead I ACTUALLY SEE A SPRITE RENDERED  I'm not sure what this means though.

One thing I just want check though as I am unfimiliar with them is my Vertex Declaration.

//VERTEX
struct SpriteVertex
{
D3DXVECTOR3		vPos;
D3DXCOLOR		Colour;
uINT			u1, v1;
};

//VERTEX DECLARATION

D3DVERTEXELEMENT9 Sprite_Decl[] =
{
{0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
{0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END() // this macro is needed as the last item!
};

Thanks

#19NightCreature83  Members

Posted 15 January 2013 - 03:46 AM

D3DXCOLOR looks like this: http://msdn.microsoft.com/en-us/library/windows/desktop/bb172730%28v=vs.85%29.aspx

struct D3DXCOLOR
{
float r,g,b,a;
}

Which means it's 16 bytes big so you have D3DXVector3 = 12 bytes + D3DXCOLOR = 16 + uint = 4 bytes * 2 = 36 bytes, which happens to be the same thing sizeof(SpriteVertex) will return. Your vertex declaration however tells D3D that the color value is only a DWORD big which is 4 bytes.
If you define your SpriteVertex as:

struct SpriteVertex
{
D3DXVector3 position;
DWORD color;//This is the same as D3DCOLOR
unsigned int u, v;
}

This will match your vertex declaration and will make your sprite buffer work again, there are helper functions in D3DX that allow you to transform a 4 float value into a dword(http://msdn.microsoft.com/en-us/library/windows/desktop/bb172518%28v=vs.85%29.aspx).

Edited by NightCreature83, 15 January 2013 - 03:53 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

#20AussieSpoon  Members

Posted 15 January 2013 - 05:38 AM

This will match your vertex declaration and will make your sprite buffer work again, there are helper functions in D3DX that allow you to transform a 4 float value into a dword(http://msdn.microsoft.com/en-us/library/windows/desktop/bb172518%28v=vs.85%29.aspx).

I'm kind of confused by this.

Is it ok to write:

DWORD tColour = (*itCurr)->GetColour();//GetColour(): returns a D3DXCOLOR
//Then to change a vertex's color:
pVertex[VertexCounter].Colour = tColour;

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.