Check contents of a Vertex Buffer

Started by
26 comments, last by AussieSpoon 11 years, 3 months ago

Yes because D3DXCOLOR defines a cast operator through which it can do this automatically. You just can't use sizeof(SpriteVertex) if you keep storing a D3DXCOLOR in there as the vertexdeclaration and stride won't match up.
Also you should find the D3D control panel and turn the debug layer on with messages set to warning, you will get warnings about this stuff in your output log this way. In the start menu folder where you found pix there is also something called DirectX Control panel launch that application and change the settings under Direct3D 9 tab to use the debug Version of the runtime. Move the slider, under the heading Debug Output Level, to one tick before More, click apply.

You also have to modify your vertex declaration to this when using only a dword to store your color values:


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

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

Advertisement

Hmmmm I did the control panel thing but I get no additional errors.

I've fixed the declaration like you said but I still can't see anything. But I am getting crazy values for my vertices

Zi988.jpg?1

Still getting the same problem where I don't know why Draw indexed prim is being called twice and the pre-VS had good values but the post VS-Doesn't

You wouldn't happen to have any other ideas?

Thanks

EDIT: According to PIX I have 2 Vertex Buffer and Index objects but I only create 1, could this be a problem? (Not sure how). The VB and IB (pointers) are members of a custom class


//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!
};




Look at what you did (aside from the color and alignment problems that should already be fixed).
Your structure has integers for the UV coordinates but you told Direct3D that you have 2 floats. UV coordinates are typically floating-point values often between 0.0f and 1.0f. Fix your structure and any logic you were using to put values into those.


Now look back at your screen shots.
Firstly, the index buffer is not correct on the second draw. A triangle is 3 unique points. Your index buffer specifies only 2 unique points for every triangle, meaning every triangle is degenerate no matter what position values they had.


Secondly, look at the ranges of the indices.
You are using the same vertex buffer for both calls.
Fine.
Look at the index buffer. The vertex buffer elements 95-99 are valid. The vertex buffer elements 0-?? are not.
It is fairly clear you did not initialize the whole vertex buffer. You handled some of the vertices but not the rest.


I've fixed the declaration like you said but I still can't see anything. But I am getting crazy values for my vertices
If you have ever used a debugger before you would easily recognize the pattern of bytes there. 0xDD and 0xCD are what the debugger fills over memory in certain cases.
If you see 0xCD, it means something was not initialized.
If you see 0xDD, it means the memory was freed/deleted.

The problem is obvious. You have deleted that memory.
the pre-VS had good values but the post VS-Doesn't
Are you talking about the values in that screenshot? If so, I can guarantee the PreVS values are not good.
Still getting the same problem where I don't know why Draw indexed prim is being called twice
Again, have you ever used a debugger? Do you know what “breakpoints” are?
I am not going to spoon-feed you this. You need to learn a few very very fundamental and basic debugging skills in order to help yourself.
The most basic debugging skills would have solved the problem I mentioned first in this post as well. The screenshots made it obvious what the problem was, and a few breakpoints, some single-stepping, and 10 minutes of code-checking would have exposed the underlying issue.

I am not going to spoon-feed you this.
Google keywords: “Microsoft Visual Studio Debugger”, “Breakpoints”, “Single-Stepping”, and any combination of these.


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

[quote name='L. Spiro' timestamp='1358275396' post='5021878']
Firstly, the index buffer is not correct on the second draw. A triangle is 3 unique points.
[/quote]

I understand that but a sprite is a quad and from what I thought you need 4 unique points for a quad? (Hence having only haveing 2 for each triangle). So using what you are saying each index's value should equal what number it is in the buffer?


for(uINT i = 0; i < s_nBatchSize * 6; i++)
{
 index[i] = i;}

[quote name='L. Spiro' timestamp='1358275396' post='5021878']
It is fairly clear you did not initialize the whole vertex buffer
[/quote]

This is true, I currently have a large index buffer and only lock what is needed at rendering (only 2 sprites atm)

Should I initialize every Vertex's value of the VB to 0 on creation? Is there an easy way to do this?

I can only think of something like:


	if(FAILED( g_pd3dDevice->CreateVertexBuffer( s_nBatchSize * 4 * sizeof( SpriteVertex ), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 
												 0, D3DPOOL_DEFAULT, &m_pVB, NULL ) ) )
	{
		m_pVB = 0;//Prints error msg
	}

	//Initialize VB to 0
	SpriteVertex* pVertex;
	m_pVB->Lock(0, 0, (void**)&pVertex, 0);

	for(uINT i = 0; i < s_nBatchSize * 4 + 1 ; i++)
	{
		pVertex[i].vPos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
		pVertex[i].Colour = 0;
		pVertex[i].u1 = 0;
		pVertex[i].v1 = 0;
	}

	m_pVB->Unlock();

(Yeah I have debugged before, but still a novice) Ok, not sure how I missed it but, is see that the position of the 4 vertices all have the same value (The pos of the current sprite). I think I have rectified this problem:


//pVertex[VertexCounter + 0].
			pVertex[VertexCounter].vPos = D3DXVECTOR3(vPos.x, vPos.y, fDepth);//NOT SURE ABOUT
			pVertex[VertexCounter].Colour = tColour;
			pVertex[VertexCounter].u1 = pTexture->GetTextureUMin();
			pVertex[VertexCounter].v1 = pTexture->GetTextureVMin();
			VertexCounter++;
			//Set vertex 2
			pVertex[VertexCounter].vPos = D3DXVECTOR3(vPos.x + pTexture->GetDrawArea().right, vPos.y, fDepth);
			pVertex[VertexCounter].Colour = tColour;
			pVertex[VertexCounter].u1 = pTexture->GetTextureUMax();
			pVertex[VertexCounter].v1 = pTexture->GetTextureVMin();
			VertexCounter++;
			//Set vertex 3
			pVertex[VertexCounter].vPos = D3DXVECTOR3(vPos.x, vPos.y + pTexture->GetDrawArea().bottom, fDepth);
			pVertex[VertexCounter].Colour = tColour;
			pVertex[VertexCounter].u1 = pTexture->GetTextureUMin();
			pVertex[VertexCounter].v1 = pTexture->GetTextureVMax();
			VertexCounter++;
			//Set vertex 4
			pVertex[VertexCounter].vPos = D3DXVECTOR3(vPos.x + pTexture->GetDrawArea().right, vPos.y + pTexture->GetDrawArea().bottom, fDepth);
			pVertex[VertexCounter].Colour = tColour;
			pVertex[VertexCounter].u1 = pTexture->GetTextureUMax();
			pVertex[VertexCounter].v1 = pTexture->GetTextureVMax();
			VertexCounter++;

Was that it?

Still unsure on how I am loosing data, do I need to :


memcpy(pVertex, indices, sizeof(indices) / sizeof(indices[0]));

?

Thanks

I understand that but a sprite is a quad and from what I thought you need 4 unique points for a quad?

This basically means you don’t understand anything your code is doing.
Your idea is that a quad is just a single 4-point primitive, but your code says a quad is a D3DPT_TRIANGLELIST with 2 triangles (3-point primitives) in it in the shape of a quadrilateral.
In other words, you copied and pasted from some tutorial without understanding any of it.

This is true, I currently have a large index buffer and only lock what is needed at rendering (only 2 sprites atm)

Which means only 1 of 2 things: Either you aren’t updating the correct parts or you aren’t using the correct parts.
Simple debugging techniques will tell you which is the case.

Should I initialize every Vertex's value of the VB to 0 on creation? Is there an easy way to do this?

I can only think of something like:


	if(FAILED( g_pd3dDevice->CreateVertexBuffer( s_nBatchSize * 4 * sizeof( SpriteVertex ), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 
												 0, D3DPOOL_DEFAULT, &m_pVB, NULL ) ) )
	{
		m_pVB = 0;//Prints error msg
	}

	//Initialize VB to 0
	SpriteVertex* pVertex;
	m_pVB->Lock(0, 0, (void**)&pVertex, 0);

	for(uINT i = 0; i < s_nBatchSize * 4 + 1 ; i++)
	{
		pVertex[i].vPos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
		pVertex[i].Colour = 0;
		pVertex[i].u1 = 0;
		pVertex[i].v1 = 0;
	}

	m_pVB->Unlock();

That is correct (except s_nBatchSize * 4 + 1) for initializing the whole buffer with 0’s, however looking at your 2nd screenshot the invalid region is already filled with 0’s.
Meaning although this is a good idea it won’t solve your problem.


Was that it?

Still unsure on how I am loosing data, do I need to :


memcpy(pVertex, indices, sizeof(indices) / sizeof(indices[0]));

That will only copy less data than before.


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

[quote name='L. Spiro' timestamp='1358327617' post='5022102']
Your idea is that a quad is just a single 4-point primitive, but your code says a quad is a D3DPT_TRIANGLELIST with 2 triangles (3-point primitives) in it in the shape of a quadrilateral.
[/quote]

No, what I meant was my quad is made up of 2 primitives with each one having 3 indices and 2 of those being unique. , Is this wrong? Should I be using a different method?

I finally got my (last) draw call to not have messed up values. But you were saying my indexes are incorrect? So perhaps that is why I can't see anything?

wwojR.jpg?1

Thanks

Your indices are correct now.

Look at them now: 012 213 etc.

Look at them before: 001 020 etc.

See how these are not the same values? Before = wrong. You changed something and now it is fixed. Move on.

Now you claim to still be unable to see anything, but you have obviously eliminated vertex and index buffers as possible suspects. That means the device state is the problem.

I have already told you how to view the device state. I expect you to be able to click a few tabs and look around through it on your own.

If you see the first sprite and not the second, check the device state between the 2 draw calls and see what is different. Depth-testing? Culling? I already gave you a comprehensive list of things to check in my first reply to this thread.

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

Whoops, embarrassingly, it was working once I fixed the VB, but the only visible part of the image was alpha (you were right to say "claim"). So now I just have to move the camera and fix up the matrices.

Thanks heaps for your help, much appreciated.

This topic is closed to new replies.

Advertisement