• Advertisement

Archived

This topic is now archived and is closed to further replies.

dx8.1 vertex buffers need be called every frame?

This topic is 5491 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

looking at the simplest d3d sample code (the matrix example of rendering an untransformed triangle) tells me that i dont have to call the following for every frame:
  
VOID* pVertices;
    if( FAILED( m_pVB->Lock( 0, sizeof(m_sVertices), (BYTE**)&pVertices, 0 ) ) )
	{
        return;
	}
	// Copy vertices and Lock() it.

    memcpy( pVertices, m_sVertices, sizeof(m_sVertices) );
    m_pVB->Unlock();
  
But when doing an identical thing with my cube, some of the triangles are not drawn. But when i call the posted code above before i render every frame, then all triangles are drawn nicely. THe problem? I dont want to do the above every single frame. am i missing something? Again, my project is pretty much identical to the rotating triangle example provided by the SDK.

Share this post


Link to post
Share on other sites
Advertisement
basically you are rendering a triange on screen at all times. So the shape is not changing, it''s always a triangle. therefor you do not need to refill the vetex buffer every frame.

What does your vertex buffer creation code look like?

and have you turned culling off?
ie:
pDevice->SetRenderStats( D3DRS_CULL, D3DCULL_NONE );


:::: [ Triple Buffer V2.0 ] ::::

Share this post


Link to post
Share on other sites
thanks for your help.
I am not at my computer right now...so i have no code to show, yet.

But I will talk some more about it.

I turned CULLMODE to CCW since my cube looks very weird without the culling.

And...I refill the buffer every frame because THAT seems to solve my problem - for now.
Basically, if I dont refill the VB every frame, then I get some triangles that are not drawn.
Which is very strange because the first triangle in the triangle list is drawn, but the second one is not, but then other triangles ARE being drawn after the undrawn 2nd triangle.

i know thats confusing, but its only speculation right now.
But im pretty sure its it since I wrote the code from scratch (except all the VB and rendering stuff which i stole from MS).

Share this post


Link to post
Share on other sites
ok, here''s the source (its basically a real simple skybox).

  
#include "CSkybox.h"

//---( CSkybox : Constructor, initialize the skybox )---//

CSkybox::CSkybox( float Scale ) // By default, Scale is 1.0f

{
// Set m_bVBCreated flag to false.

m_bVBCreated = false;

// Set the vertex buffer to NULL.

m_pVB = NULL;

// Setup vertcies: x, y, z, rhw, color, diffuse, specular, tu, tv

CUSTOMVERTEX_UNTRANSFORMED temp_Vertices[] =
{
// front, clockwise triangle strip order, start at bottom left

{-1.0f,-1.0f,-1.0f, 0xffff00f0 },
{-1.0f, 1.0f,-1.0f, 0xffff0000 },
{ 1.0f,-1.0f,-1.0f, 0xffff00f0 },

{ 1.0f,-1.0f,-1.0f, 0xffff00f0 },
{-1.0f, 1.0f,-1.0f, 0xffff0000 },
{ 1.0f, 1.0f,-1.0f, 0xffff00f0 },

// right, start at bottom left

{ 1.0f,-1.0f,-1.0f, 0xff00ffff },
{ 1.0f, 1.0f,-1.0f, 0xff00ffff },
{ 1.0f,-1.0f, 1.0f, 0xff00ffff },

{ 1.0f,-1.0f, 1.0f, 0xff00ffff },
{ 1.0f, 1.0f,-1.0f, 0xff00ffff },
{ 1.0f, 1.0f, 1.0f, 0xff00ffff },

// back, start at bottom left

{ 1.0f,-1.0f, 1.0f, 0xffff00f0 },
{ 1.0f, 1.0f, 1.0f, 0xffff00f0 },
{-1.0f,-1.0f, 1.0f, 0xff000fff },

{-1.0f,-1.0f, 1.0f, 0xff000fff },
{ 1.0f, 1.0f, 1.0f, 0xffff00f0 },
{-1.0f, 1.0f, 1.0f, 0xff000fff },

// left, start at bottom left

{-1.0f,-1.0f, 1.0f, 0xf000ff00 },
{-1.0f, 1.0f, 1.0f, 0xf000ff00 },
{-1.0f,-1.0f,-1.0f, 0xf000ff00 },

{-1.0f,-1.0f,-1.0f, 0xf000ff00 },
{-1.0f, 1.0f, 1.0f, 0xf000ff00 },
{-1.0f, 1.0f,-1.0f, 0xf000ff00 },

// top, start at bottom left

{-1.0f, 1.0f,-1.0f, 0xffff00f0 },
{-1.0f, 1.0f, 1.0f, 0xffff00f0 },
{ 1.0f, 1.0f,-1.0f, 0xffff00f0 },

{ 1.0f, 1.0f,-1.0f, 0xffff00f0 },
{-1.0f, 1.0f, 1.0f, 0xffff00f0 },
{ 1.0f, 1.0f, 1.0f, 0xffff00f0 }
};

// Scale it and copy to m_sVertices...

for (int i=0; i<30; i++)
{
m_sVertices[i].x = temp_Vertices[i].x * Scale;
m_sVertices[i].y = temp_Vertices[i].y * Scale;
m_sVertices[i].z = temp_Vertices[i].z * Scale;
m_sVertices[i].color = temp_Vertices[i].color;
}
}

//---( ~CSkybox : Destructor, destroy things... )---//

CSkybox::~CSkybox()
{
// Go ahead and call Close(), it wouldn''t hurt to do this.

Close();

if( m_pVB )
m_pVB->Release();
}

//---( Create : Create the vertex buffer )---//

int CSkybox::Create( LPDIRECT3DDEVICE8 lpDevice )
{
// Create the vertex buffer. Here we are allocating enough memory

// (from the default pool) to hold all our 3 custom vertices. We also

// specify the FVF, so the vertex buffer knows what data it contains.

if( FAILED( lpDevice->CreateVertexBuffer( 3 * sizeof(CUSTOMVERTEX_UNTRANSFORMED),
0, D3DFVF_CUSTOMVERTEX_UNTRANSFORMED,
D3DPOOL_DEFAULT, &m_pVB ) ) )
{
return -1;
}

// Now we fill the vertex buffer. To do this, we need to Lock() the VB to

// gain access to the vertices. This mechanism is required because vertex

// buffers may be in device memory.

VOID* pVertices;
if( FAILED( m_pVB->Lock( 0, sizeof(m_sVertices), (BYTE**)&pVertices, 0 ) ) )
{
return -1;
}

// Copy vertices and Lock() it.

memcpy( pVertices, m_sVertices, sizeof(m_sVertices) );
m_pVB->Unlock();

// Set the Created flag to true.

m_bVBCreated = true;

return 0;
}

//---( Close: Destroy the vertex buffer )---//

void CSkybox::Close()
{
if( m_pVB )
m_pVB->Release();
}

//---( Render : Draw the sky )---//

void CSkybox::Render( LPDIRECT3DDEVICE8 lpDevice )
{
if( m_bVBCreated == false )
return;

// Now we fill the vertex buffer. To do this, we need to Lock() the VB to

// gain access to the vertices. This mechanism is required because vertex

// buffers may be in device memory.

/*VOID* pVertices;
if( FAILED( m_pVB->Lock( 0, sizeof(m_sVertices), (BYTE**)&pVertices, 0 ) ) )
{
return;
}
// Copy vertices and Lock() it.
memcpy( pVertices, m_sVertices, sizeof(m_sVertices) );
m_pVB->Unlock();*/


lpDevice->SetRenderState( D3DRS_ZENABLE, FALSE );

lpDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX_UNTRANSFORMED));// )

{
lpDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX_UNTRANSFORMED );
lpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 10 );
}

lpDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
}

// eof: CSkybox.cpp



Notice how all the filling of the VB in Render() is commented out? When its commented, some triangles are not drawn. But if i uncomment them, the cube looks the way i want it (all 10 triangles drawn).

Share this post


Link to post
Share on other sites
I have noticed DX not drawing all polygons every frame (they flicker randomly) in certain situations... but it''s very bizarre, and very rare. Witnessed on many identical P4 1.8GHz, GeForce3 Ti200, WinXP machines at work.

The same code is running each frame, but the output is occasionally missing some polys. Which polys, if any, seems to depend on the camera angle. Change the code a bit and it works fine. We''re not corrupting RAM, or using non-initialized pointers. All our buffers are of the correct size and type. Everything looks fine in code... except when a certain, rare, timing condition occurs. Since we''ve standardized machines at work (so much for broad-range testing), I can''t really say if it happens on any other configuration, whether it be a different OS, video card, or CPU.

The truly bizarre part is this. Rendering is halted when dragging a window... so just clicking and holding the title bar of a window should show the problem on occasion (the rate of flicker would suggest maybe 20% of the time), but it doesn''t. The rendering halts, but it is always perfect. This is the one part that makes me fairly certain that it''s a card/driver issue, where it presents a frame that isn''t completely drawn.

Share this post


Link to post
Share on other sites
First of all, thanks a bunch!
Second, Oh my God!

Im glad its not my code...yet Im angry (at Microsoft) for DX.
What did you do to solve your rare polygon drawing problem???

NOTE: This problem happens EVERY time for me.

BTW: Im running this on my new Gateway notebook, 2.0ghz Pentium4, ATI graphics card, 256 memory, running windows xp.

Share this post


Link to post
Share on other sites
We don''t have a fix. First though, make sure it IS the same issue. Run in windowed mode, and click the title bar as though you were going to drag the window. Is it still broken? If so, it''s not the same issue.

Share this post


Link to post
Share on other sites
I have seen this "flickering" problem as well. It was related to camera angle, distance, etc. I identified my problem as being my near clipping with a setting of 0.0. When I changed that to 0.1 things were happy again and the flickering went away.

Cheers

Share this post


Link to post
Share on other sites
The problem I was referring to didn''t look at all like the artifacts you get with bad near and far clipping planes. (though that may be the original poster''s problem...)

That type of "flickering" results from not enough depth precision based on your settings, and will change as you move the camera or character around. Clicking to drag the window won''t help this type of flicker either.

The flickering I''m referring to occurs even with a fixed camera and mesh. I think I once tracked down that it only occured with dynamic vertex buffers.

As I said, it looks fine if you halt the rendering by dragging, which indicates the drawing code is drawing everything, and it''s not a render state issue. It''s a bizarre timing issue. Our app isn''t multi-threaded, so the timing issue isn''t our problem, but likely the driver or card.

Share this post


Link to post
Share on other sites
so. the problem is the following. You have your cube( skybox ) with 36 vertices. When you create a vertex buffer, you pass the size in the first parameter. So it is the needed vertex number*vertex size.

Now, you allocated 3 vertices, so the remaining 33 copied into nothing. You''re very unfortunate you didn''t have an exception for copying into unallocated memory, because it''d help to solve the problem. You need to allocate the vertex buffer at least that size as your vertices requie. So the right code:


    
// at least

if( FAILED( lpDevice->CreateVertexBuffer( 36 * sizeof(CUSTOMVERTEX_UNTRANSFORMED),
0, D3DFVF_CUSTOMVERTEX_UNTRANSFORMED,
D3DPOOL_DEFAULT, &m_pVB ) ) )
{
return -1;
}




I hope this is the problem, and that it helped.

Share this post


Link to post
Share on other sites
ok woah. you are creating the vertex buffer to hold 3 vertices, but you copy 30 vertices into it. So change your vertex creation function, and mulitply sizeof(CUSTOMVERTEX_UNTRANSFORMED) by 30 instead of 3. Becuase you want 30 vertices correct?


indeed it is unfortunate that you didnt get access violations. It would''ve at least helped a little in finding the problem.


:::: [ Triple Buffer V2.0 ] ::::

Share this post


Link to post
Share on other sites
By golly gee wiz...you are right!

I will make that update right away....but...this brings another question...

First of all, before I read prgrmmr''s post, I ran my program without filling the VB every frame. I tried this again so that i could test if everything is drawn when i click the title bar.

Well, to my pleasant surprise and pleasant frustration, the whole box is being drawn - which is NOT what it used to do. And nothing has changed!

Now after reading prgrmmr''s post, we have godo reason to suspect that the mismatched vertex count being passed in is the problem (ill find out soon enough). But why would the copying of 30 vertices into an allocated space of 3 allow most of the box to be drawn in the first place?!

This is just weird and bad.
But then again, so is my programming i guess.

Share this post


Link to post
Share on other sites
Cheers guys,

When using DirectX for programming/rendering, I recommend using the debug dll''s, because if you have an error, or an access violation or something, it will output a message to your debug window.

Also, you should think about writing a wrapper class for the vertex buffer object and index buffer, along with anything else you can think of! This can help (read: eliminate) these kinds of errors.

You can check out most major engines, like the NeoEngine, or the OGRE engine. Or, comparitevly, you can check out my render API, at www.geocities.com/aes_cyber_god/xion_engine_v2.zip

It''s really a useful tool, and totally stops these kinds of errors before they occur. Good luck, and may the force (read: electricity) be with you

Chris Pergrossi

Share this post


Link to post
Share on other sites
quote:
But why would the copying of 30 vertices into an allocated space of 3 allow most of the box to be drawn in the first place?!


Probably becuase the next 27 spaces in memory were not being used, and were free. So they just got copied in and nothing was there to stop them. These kind of memory writes are really pains in the neck. Becuase they work sometimes and other times they dont work. So it gets really confusing. I had an array[150] that was storing stuff once, and it would work fine all the time, then it started crashing all of a sudden. Turns out all the time I was writing about 200+ objects into the array[150]. And it took me months before I noticed it


:::: [ Triple Buffer V2.0 ] ::::

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
it was more easy to blame Microsoft than to think !!

Share this post


Link to post
Share on other sites
I had once the same problem as IFooBar. It''s really a painful problem.

The reason is ( why does it work sometimes and not other times ) that you can use the unallocated places of the memory free. So if you make a random number, and do for example:

(INT*)*rand()=16;

it maybe works, if no other application uses that area of the memory. And the 16 will there until other application uses that memory block.

So for some time the
(INT*)*thesamerandomnumber()==16

but when an other applicition allocates that memory block, and may fill it with zeros.......

(INT*)*thesamerandomnumber()==0 or (INT*)*thesamerandomnumber()==random number

so, if you have some fortune, you may write values into unallocated memory, and it may works. But if you don''t allocate the block, other apps have rights to allocate it, and the values can be changed.

So if 36 vertices written into the place of three vertices, and renders correctly, you are fortunate. If the memory block after the 3 vertices is already allocated, you''ll have an exception. I some app allocate that memory after you wrote into it, the values will be lost. If no app writes to that block, so can use it.

If you allocated 36vertices*sizeof( VERTEX ) you''ll never have any problem. Because that X bytes of memory is yours, and just yours.

So the reason why the whole cube rendered is you had fortune.

Share this post


Link to post
Share on other sites
Just a general note: Whenever something runs wrong/doesn''t run, try it with the reference rasterizer. If the reference rasterizer gets it right, then it''s a driver/card issue. If it doesn''t get it right then it''s certainly your fault.

Share this post


Link to post
Share on other sites

  • Advertisement