Archived

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

jack_1313

Vertex Buffer... 2D terrain?

Recommended Posts

Hi. My game uses D3D 8.1 and is 2D-side-view (800x600x16), where I render the ground as a bunch of triangles, in a way similar to that seen in such games as Soldat and Elasto-mania. Now, each triangle is stored as a linked-list consists of three vertecies (obviously), and can have one of four textures. Previously, I have been going through the linked-list every frame, using DrawPrimativeUP to render the ground. I am also rendering 2 tiled-backdrops using DrawPrimativeUP, one a cloud-texture, the other a 94% transparent texture with a few drops of rain on it. I also draw the game objects, which are rarely bigger that 32x32. This is s l o w. When I render the terrain, objects and one backdrop, I get acceptable framerates. But as soon as I go for the second backdrop, I get about 18 fps. This sucks. I figure this is because I am using DrawPrimativeUP instead of creating vertex buffers and using DrawPrimative. Vertex buffers for each backdrop should be easy enough. My questions concern the rendering of the terrain. So far, I render my triangles at their co-ordiantes, - viewx,viewy: variables describing the current view of the game word. 1) Would I need a vertex buffer of triangles for each of the four textures ie triangles of texture a go into vb a etc? 2) Do I need to clear my vertex buffer (for the triangles) every frame, and then go through my linked list and copy the vertex co-ordiantes - viewx/viewy, or is there some way I can create a static vertex buffer, then use matricies (I dont know what they are) or something to alter the view of the game world (this would be better because I wouldnt have to reload the vb every frame)?. Note that the terrain never changes, other than to reflect the current viewx/viewy position. 3) If I do clear vb, reload the triangles based on view co-ordinates etc then how would I do this? Ie, how would I use memcpy to go through a linked list, adding in more data to the vb as I go? 4) Am I right that it is DrawPrimativeUP that is killing my framerate? Thanks in advance to anyone that can help.

Share this post


Link to post
Share on other sites
I''m new to DirectX (and 3d programming in general) myself but I think I can help you out.

You can use a single static vertex buffer to store your terrain. Use triangle strip(s) if you aren''t already.

I''m not sure exactly how much of speed-up this will give you. What are your system specs?

Share this post


Link to post
Share on other sites
Hi. You don''t want to know my system specs... but I''ll post them anyhow:
540 mhz processor.
64 mb of ram (which is really only 56 mb when you subtract the vidieo ram)
8 mb shared vidieo ram (intregated vidieo)
Anyhow, this may be crap compared to todays P4 2.5s and 128 mb graphics, but it sould easily be enough for this type of thing, should it not? I remeber using DirectDraw... never had to wory about anything like this.
Anyhow, you siad a static vertex buffer. How would I then change the in-game view co-ordinates to show different parts of the level? Will this mess with other parts of my code?
The other thing was, the terrain is shaded different colors, and so is the main backdrop with the clouds - could this be a performance hit?
As for triangle stips... could I use a triangle-list. That would be much easier for me. Currently I have been using triangle-fans to render the terrain, but it should not matter because I am rendering one triangle at a time.

Share this post


Link to post
Share on other sites
I hope I can give you a few helpful suggestions.

You will want to use vertex buffers to speed up the process here in my opinion. Create a "Terrain" vertex buffer. Then every frame:

1. determine which parts of the terrain are currently on the screen.
2. Lock the terrain vertex buffer
3. copy the vertex information of the currently on-screen vertices to terrain vertex buffer.
4. Unlock the terrain vertex buffer
5. Call DrawPrimitive for that vertex buffer.

I would also suggest doing something similar for all common objects. For example: Have a vertex buffer for all enemies and players.

I''m not sure if you already do what i''m about to talk about next but i''ll put it here just in case: Group as many pictures as you can into one texture. Then use the texture coordinates to retrieve that picture out of the texture. This way you limit the amount of times you call SetTexture (very expensive) to a minimum.

Share this post


Link to post
Share on other sites
Your view point determines what is visible and what is not (using a Camera class, for example). You can do some culling to not draw the invisible vertices (and therefore, use a dynamic VB).

Share this post


Link to post
Share on other sites
Ok, you''ve lost me a bit here. Vertex buffers are always of a fixed size, right? How could I determine what polygons are on screen then put them into the VB,when the VB has a defined size?
What is culling?
What memory function (ie memcpy) would I use to add data onto data that is already in the vertex buffer? I would use memset to clear the vertex buffer?
Would it not be better to create a static vertex buffer, and then do something with views? What is the view class, and how does it work? Most Willuseing this view thing effect my drawprimativeUPs?
And finally, how much speed advantage am I going to get? Will I do all this, then mind that my framerate is still at 20fps? Is DrawPrimativeUP really causing the hit to my framerate, or could it be something else, like clipping or something?

Share this post


Link to post
Share on other sites
Yeah vertex buffers are static sizes, i''m pretty sure......anyways just make one pretty big. When you make a call to DrawPrimitive one of the parameters is how many primatives you want to draw. This way you can, each frame, lock your vertex buffer. Fill it up with the current polygons that are visible, make sure you don''t go out of bounds and when your done just call drawprimitive.

Should work

Share this post


Link to post
Share on other sites
how do you mean ''out of bounds''? You mean trying to overfill the vertex buffer?
And will I be needing a seperate vertex buffer for each texture?
How do I use memcpy to add data onto data that is alread in the VB?

Share this post


Link to post
Share on other sites
Hmmm... things can get real difficult if you''re not familiar
with background knowledge like cullin'', VB sizes, index buffer
and stuff like that. But there has to be a start.

So OK, "culling" means "removing". Some triangles are back-
facin'' the user and you don''t want to waste processin'' power on
them and eventually not seein'' them on screen. So your 3D
hardware/software will do some calculations (normals and stuff)
and remove those invisible triangles.

The VB can be of fixed size, unless you create dynamic VBs.
There''s a flag to specify and I can''t remember what was it, try
checkin'' out the SDK. You write into the VB by lockin'' it, and
write your triangle data into it, then unlock it, and draw.
However, this can sometimes have serious impact on your frame
rate when done so frequently (every frame).

Why? One, because when you lock the VB, it''s likely that the
video card don''t get to access the VB and draw it on screen,
resultin'' in a stall. (Though it''s possible to let CPU/GPU both
workin'' at the same time, but that''s different story for a
different day.) Two, lock/fill data/unlock process are done in
system memory, which has to be sent over to video memory for
renderin'' (uhm for your case it''s the same memory, but...). So
that means there''s data across the system bus each frame,
doesn''t sound too good eh? Yeah.

Oh shit, my company bus is almost here, gotta go, tell you more
later! (I''ll be goin'' to Perth 10th November, explain to you if
I get to see you there ) See ya!!





Share this post


Link to post
Share on other sites