Sign in to follow this  

strange problem with vertex buffer...

This topic is 4176 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 everyone :) Sorry for presenting what is likely to be a silly problem of mine such as a memory leak... but since I checked for several hours now in a not-so-complex code, maybe I haven't seen another thing.
struct RHWVERTEX
{
    FLOAT x, y, z, rhw; // The position for the vertex
    DWORD color;        // The vertex color
    FLOAT tu, tv;       // The texture coordinates
};
#define D3DFVF_RHWVERTEX (D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_XYZRHW)

LPDIRECT3DVERTEXBUFFER9 lpVB = NULL;

// -----------------

RHWVERTEX tVertexTable[8];

// first quad
tVertexTable[0].tu = 0.0f;  tVertexTable[0].tv = 0.0f;
tVertexTable[0].x = 0;      tVertexTable[0].y = 0;
tVertexTable[0].z = 0;      tVertexTable[0].color = 0xFFFFFFFF;

tVertexTable[1].tu = 1.0f;  tVertexTable[1].tv = 0.0f;
tVertexTable[1].x = 1024;   tVertexTable[1].y = 0;
tVertexTable[1].z = 0;      tVertexTable[1].color = 0xFFFFFFFF;

tVertexTable[2].tu = 0.0f;  tVertexTable[2].tv = 1.0f;
tVertexTable[2].x = 0;      tVertexTable[2].y = 1024;
tVertexTable[2].z = 0;      tVertexTable[2].color = 0xFFFFFFFF;

tVertexTable[3].tu = 1.0f;  tVertexTable[3].tv = 1.0f;
tVertexTable[3].x = 1024;   tVertexTable[3].y = 1024;
tVertexTable[3].z = 0;      tVertexTable[3].color = 0xFFFFFFFF;

// second  quad
tVertexTable[4].tu = 0.0f;  tVertexTable[4].tv = 0.0f;
tVertexTable[4].x = 0;      tVertexTable[4].y = 0;
tVertexTable[4].z = 0;      tVertexTable[4].color = 0xFFFFFFFF;

tVertexTable[5].tu = 1.0f;  tVertexTable[5].tv = 0.0f;
tVertexTable[5].x = 1024;   tVertexTable[5].y = 0;
tVertexTable[5].z = 0;      tVertexTable[5].color = 0xFFFFFFFF;

tVertexTable[6].tu = 0.0f;  tVertexTable[6].tv = 1.0f;
tVertexTable[6].x = 0;      tVertexTable[6].y = 1024;
tVertexTable[6].z = 0;      tVertexTable[6].color = 0xFFFFFFFF;

tVertexTable[7].tu = 1.0f;  tVertexTable[7].tv = 1.0f;
tVertexTable[7].x = 1024;   tVertexTable[7].y = 1024;
tVertexTable[7].z = 0;      tVertexTable[7].color = 0xFFFFFFFF;


Main_Application::GetDevice()->CreateVertexBuffer(8*sizeof(RHWVERTEX), 0, D3DFVF_RHWVERTEX, D3DPOOL_DEFAULT, &lpVB, NULL);
RHWVERTEX* pLockedVB;
lpVB->Lock( 0, 8*sizeof(RHWVERTEX), (void**)&pLockedVB, 0 );
memcpy(pLockedVB, tVertexTable, 8*sizeof(RHWVERTEX));
lpVB->Unlock();

// -----------------

Main_Application::GetDevice()->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
Main_Application::GetDevice()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
Main_Application::GetDevice()->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
Main_Application::GetDevice()->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);

Main_Application::GetDevice()->SetStreamSource(0, lpVB, 0, sizeof(RHWVERTEX));
Main_Application::GetDevice()->SetFVF(D3DFVF_RHWVERTEX);

Main_Application::GetGraphics()->UseTexture(m_iBackgroundTexture); // This calls a SetTexture for stage 0 and works fine...

// -----------------
Main_Application::GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// -----------------







Results : In DEBUG mode everything is fine !! In RELEASE mode : this call to DrawPrimitive here results in only the second half of the texture being displayed. the top-left triangle is... something close to black. If I try to display the second quad with a DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2); instead, It works fine... Really, I've never had something like this before. To sum everything up, second quad (vertices 4 to 7) is OK, first quad (vertices 0 to 3) is half displayed as if vertex 0 was missing.... (but ONLY in Release Mode .. ?!?) Can someone see something wrong in the code above or should I continue to check for memory leaks of some kind ? Many thanks :) [Edited by - TiPiou on August 11, 2006 3:20:22 PM]

Share this post


Link to post
Share on other sites
You never set the RHW for any of your vertices. It's probably just luck that most of the vertices work in release mode.

In debug mode, all variables are cleared to some recognisable pattern (Stack variables get 0xcccccccc). That may work out as a valid RHW value when converted into IEEE float format, and since all the vertices get the same RHW value, they all show up as the same. In release mode, the value of the rhw member is completely undefined.

Share this post


Link to post
Share on other sites
I've never really tried drawing a quad before just a series of triangles but I think the problem is in the DrawPrimitives using Triangle Strips.

If you aren't aware (I'm sure you are though) Triangle Strips work in such a way that you only need 2 vertices to create the next triangle.

So if we take a look at your code and see how it works with trianglestrips.

Quad 1 - Table 0 - x = 0 , y = 0 , z = 0
Quad 1 - Table 1 - x = 1024, y = 0 , z = 0
Quad 1 - Table 2 - x = 0 , y = 1024, z = 0
Quad 1 - Table 3 - x = 1024, y = 1024, z = 0
Quad 2 - Table 4 - x = 0 , y = 0 , z = 0
Quad 2 - Table 5 - x = 1024, y = 0 , z = 0
Quad 2 - Table 6 - x = 0 , y = 1024, z = 0
Quad 2 - Table 7 - x = 1024, y = 1024, z = 0

From that we have the following triangles (if drawn in order as strips)
Main_Application::GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

Triangle 1 - Point 1 - Table 0
Triangle 1 - Point 2 - Table 1
Triangle 1 - Point 3 - Table 2
This would be drawn counter clockwise

Triangle 2 - Point 1 - Table 1
Triangle 2 - Point 2 - Table 2
Triangle 2 - Point 3 - Table 3
This would be drawn clockwise


If you turn off culling these 2 triangles should appear as a square in the top right hand corner of the screen assuming 0,0 is center. By default culling is counter clockwise so one of those triangles will not be drawn.

Triangle 3 - Point 1 - Table 2
Triangle 3 - Point 2 - Table 3
Triangle 3 - Point 3 - Table 4
This would be drawn clockwise

Triangle 4 - Point 1 - Table 3
Triangle 4 - Point 2 - Table 4
Triangle 4 - Point 3 - Table 5
This would be drawn counter clockwise
The quad these 2 triangles make would be in the same position as the first quad and thus would also give the impression that only 1 quad is drawn. Assuming culling is on that is.

Main_Application::GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2);
Triangle 5 - Point 1 - Table 4
Triangle 5 - Point 2 - Table 5
Triangle 5 - Point 3 - Table 6
This would be drawn counter clockwise

Triangle 6 - Point 1 - Table 5
Triangle 6 - Point 2 - Table 6
Triangle 6 - Point 3 - Table 7
This would be drawn clockwise

These 2 triangles would be drawn exactly the same as the first 2 as they are at the same position.

Of course positioning can be done separately to move the drawn triangle/quad to where it is required.

But as you can see here those 8 vertices in fact create 6 triangles when drawn at once. 3 Vertices = 1 Triangle, 4 Vertices = 2 Triangles, 5 Vertices = 3 Triangles, 6 Vertices = 4 Triangles, 7 Vertices = 5 Triangles, 8 Vertices = 6 Triangles.

Using this line instead should draw all the triangles available. But half will draw the other half won't if the culling system isn't turned off or the drawing system isn't adjusted to make culling work when you require it.
Main_Application::GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 6);

Your best option if you want to keep those array values is to use an index buffer and fill it will the array positions for each triangle point to drawn and then use the DrawIndexedPrimitives command to use the index to decide which vertex to draw. You can then arrange the index so that all the triangles are drawn in the same direction by changing which way round the points are drawn.

Hmm, might be worth trying the 0,8 DrawPrimitive route first. It may well work in your codes current format as the triangles are drawing over each other but in different ways. See the result of that drawing and then decide whether you need or want to change to an alternative way of drawing.

TriangleList = 1 Triangle = 3 Points
TriangleStrip = 1st Triangle = 3 Points, Subsequent = +1 Point


Hope that all helped in some way. Or someone else can explain it in a better way.

edit: Of course Evil Steve may have spotted something more relevant so hope I haven't bored you needlessly.

Share this post


Link to post
Share on other sites
evil steve : that was it... many thanks once again !! :)
I hadn't mess with rhw vertices since long ago and I was going totally blind.

Xrystal : I was aware I only need 1 more vertex for each triangle after the next... ;) about your CW / CCW demonstrations, well... that's why my D3DCULL_NONE was for :D

But I disagree with you on one point : Last time I checked such an issue, I pretty well remember that every triangle in a triangle strip was necessarily sent in the opposite direction than the previous, so when using triangle strips, the card was performing by itself a flip of every next triangle.

Anyway, my objective is not obvious in the part of code I provided, and the two same (0,0,1024,1024) quads don't make sense by themselves, I give you that... but they're only a step of my debbuging test, to ensure that the sizes were not involved in the differencies I noticed. Real values are different between the two ;) (0,0,1024,1024) and (0,0,1024,768)

I really need thoses values as they are, and I'm only using them 1 quad by one in a very static way, first to display a texture in a render target of 1024 1024, second to display the result on the 1024 768 screen ;) no complex strip is involved, and I really don't need to bother about culling as they're used for really flat 2D ;)



anyway, thanks for the answers, both of you :)

Share this post


Link to post
Share on other sites
Thanks for that info on the strips. Never used strips myself so I only know what the books/help tell me. Glad what Steve said was the problem :D

Share this post


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