Skip to main content
gamedev.net
🔒 Locked

Check contents of a Vertex Buffer

Started by AussieSpoon Jan 14, 2013 at 1:33 AM 26 replies 4.8k views
Original Post
AussieSpoon
AussieSpoon

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

Jason Z
Jason Z

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 Direct3D Books: 
AussieSpoon
AussieSpoon

[quote name='Jason Z' timestamp='1358130572' post='5021254']
Are you seeing behavior that makes you think it isn't working correctly?
[/quote]

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?

L. Spiro
L. Spiro
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 restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid
Jason Z
Jason Z
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 Direct3D Books: 
NightCreature83
NightCreature83
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.
AussieSpoon
AussieSpoon
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

L. Spiro
L. Spiro
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
I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid
L. Spiro
L. Spiro
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
I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid
AussieSpoon
AussieSpoon

Ok I think I did this right,

z41iW.jpg?1

and:

h5HO1.jpg?1

and:

41Pzq.jpg?1

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

NightCreature83
NightCreature83

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
L. Spiro
L. Spiro

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

[attachment=13231:Part1.png]

[attachment=13232:Part2.png]

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid
AussieSpoon
AussieSpoon

1st Draw Call (Pre VS):

jFjGQ.jpg?1

1st Draw Call (Post VS):

Wre2X.jpg?1

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

hvOtN.jpg?1

Device info:

BxFjF.jpg?1

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.

L. Spiro
L. Spiro

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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid
AussieSpoon
AussieSpoon
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

NightCreature83
NightCreature83
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
AussieSpoon
AussieSpoon
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.

Do these two add up?:


//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

NightCreature83
NightCreature83

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).

AussieSpoon
AussieSpoon
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;

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.