• Advertisement
Sign in to follow this  

Q's about my game engine structure

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

I am currently working on my game project in DirectX9 with VC++2005 EE, and I want to pose a few questions about my design, more specifically about the way I handle static geometry. My engine handles static environment geometry fairly simply; before the loop begins my program loads a series of unindexed tris from a file, and then all these tris are drawn in one call every step. The world geometry is currently just XYZ and UV data. I use a single texture, which is a tilesheet, to draw all of my world. All "tilesheet" means is that each world triangle's UV coords are restricted to a certain 32X32 portion of the texture. Using a tilesheet-style texture allows me to use one texture for an unlimited number of environments. There is just one catch: Because my current engine has no lighting whatsoever, my tilesheet has to include several versions of each tile for different lighting orientations (such as having a light, a dark, and a very dark tile, etc.) This forces me to use a 512X512 texture, when I could have gone with a much smaller one otherwise. It also makes designing my worlds very tedious and slow (I use a tool I've written because my 3d modeller does not support tilesheet-style texturing.) Then I got the idea of adding an int color value to my world vertex FVF and doing a blend. This would be exactly like Direct3d "vertex lighting" except that it would not be dynamic - all the color values would be loaded from my world file. I could add the color values manually in my world editor. Thus, if a triangle had color values of 0xffffffff for all of its vertices, it would be drawn as if there were no color value,, but if one of its vertices' color value was changed to 0xff000000, then the triangle would be shaded from that vertex. This method would be great: I could use a 128X128 texture, I could greatly reduce world-design time, and I would have an extremely enhanced ability to realistically light my worlds, because I would be able to control not only light-to-dark, but color-shading as well. My questions: Firstly: Is this idea of "pre-calculated vertex lighting" feasible for use on my world geometry? Would it generate strange problems or be extremely slow on my users' computers? As I may have mentioned earlier, I draw _all_ my world geometry in a single call, with no frustrum culling or special tricks (this was always meant to be a simple engine, after all.) My worlds aren't exactly huge; I am trying to ensure that one world never has more than 6000 polys. So should I go ahead with this new plan? Secondly: Is it such a bad problem that I use unindexed geometry? You will appreciate that this is necessary because of the way my triangles are textured (tilesheet-styled.) I'm not concerned with the minor loss of performance which I know is inevitable; I just want to know if drawing unindexed geometry is liable to cause serious slowdowns or problems on the average user's system. Thanks very much for your help! -synth_cat

Share this post


Link to post
Share on other sites
Advertisement
Unless you're targeting really (and I mean really) old hardware, adding a color field per vertex and blending with it shouldn't present any speed issues.

For reference, I was using that method of pre-lighting on a 3Dfx Voodoo 3 back in the day for the arcade racing game Arctic Thunder, at least for the track. If memory serves (it's been awhile), we were probably submitting between 2000-5000 track tris per frame.

More modern GPUs should be able to eat the triangle load you're talking about without blinking.

Cheers,
Jason

Share this post


Link to post
Share on other sites
Thanks for the reply! That is very good news - I guess this means I don't need to be so uptight about restricting the size of my worlds. Now I'll be able to do all kinds of cool things like tint entire worlds a certain color and stuff like that.

But I'm still anxious about the unindexed-geometry thing. Do I really need to worry about this?

I'm also wondering: If I were to have a triangle where all the verts had a color value of 0xffffffff, would that triangle be optimized at all by DirectX (in other words, would this tri be excluded from color-blending?) I just want to know in case I could get a small performance boost by only shading necessary triangles. Otherwise I can just go crazy and shade everything to my heart's content.

Share this post


Link to post
Share on other sites
Unless you've got vast swaths of un-tinted triangles, and only a few tinted, I wouldn't really recommend switching vertex formats to avoid white vertexes. Honestly, you might end up with slightly faster rendering because you'll end up with better texture fetch coherency because you're not baking the lighting into the texture. In any event, adding the vertex color adds some memory bandwidth consumption (but not much if you're just using a DWORD for it), and one multiply to the pipeline - for reference, some games currently in development have pixel shaders that are hundreds of instructions long.

I'm honestly not sure about the exact ramifications of the un-indexed verts. If I had to guess, though, I would expect that it'd just be an issue of how many verts needed storage and processing - you're at 3 verts per triangle, versus, say 1.6 new verts per triangle using a sort of average triangle strip (or nearer to something like 1.2 in a closer to optimal strip). But, if your verts wouldn't be identical anyways, because of your texture mapping, I have a hard time seeing how indexing could be a win.

In any event, you're still talking about less than 20k verts, so unless you're seeing issues on the hardware you're targeting, I wouldn't lose sleep...

Cheers,
Jason

Share this post


Link to post
Share on other sites

Well, it seems as if this pre-calculated per-vertex lighting thing will work. However, what is the "correct" way to do this? I guess I can break this down into a few questions:

Should the color value for each vertex be an int or a DWORD? (I don't really see how it could be a DWORD, but you mentioned that in the last post.)

What are the renderstates I would set? Off the top of my head I'm guessing that I would set COLORARG2 and COLOROP to render the blended tris. Am I right? If so, which COLOROP should I use (my first guess would be MULTIPLY, but I'm really not sure.) I want it to work out so that a black color value will completely darken a vertex and a white color value will not shade the vertex at all.

PS.
Quote:

Unless you've got vast swaths of un-tinted triangles, and only a few tinted, I wouldn't really recommend switching vertex formats to avoid white vertexes.

(I wasn't talking about actually switching vertex formats. The tris would still all be rendered at once. I was just wondering if Direct3d would perform some sort of internal optimization on untinted triangles with "nuetral" color values, like all white.)

Share this post


Link to post
Share on other sites
Can someone help me out? I've tested the method and it doesn't exactly work.
Here is the code I have written:



//within structs.h
struct VERTEXWORLD
{
D3DXVECTOR3 pos;
D3DXVECTOR2 uv;
int color;
};

//within vertex_fvfs.h...
#define VERTEX_WORLD (D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE)

//within drawing function
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

d3ddev->SetTexture(0, t_tile);
d3ddev->SetStreamSource(0, vb_world, 0, sizeof(VERTEXWORLD));
d3ddev->SetFVF(VERTEX_WORLD);
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, num_world_tris);

d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);





When I create the vertex buffer, I set all the color values to a test value. However, no matter what I set it to, all I get is a dull red tint or complete blackness on my tris. Does anyone know what I'm doing wrong?

Share this post


Link to post
Share on other sites
On your initial post.
Why aren't you using real lights? Doing all those work arounds is a waste of time and efort.
Secondly, I'd use meshes for world geometry. It'll simplify things a bit.

Using vertex indexing will get you a performance gain if you deal with big numbers of polys.

Share this post


Link to post
Share on other sites
Quote:

Why aren't you using real lights? Doing all those work arounds is a waste of time and efort.
Secondly, I'd use meshes for world geometry. It'll simplify things a bit.

I can easily explain why I want to render my world this way. For one thing, I want my engine to be as simple as possible. Thus, I steer away from using meshes (which are more or less a way of using more than one FVF for one object, which, as far as I'm concerned, is pointless in this context.)

The reason I don't use "real lights" is similar. They add complexity, for one thing. Since Direct3d only offers support for something like two lights at a time, I would have to write my own vertex shader. Besides which, it would require an immense amount of effort to set up a realtime lighting system (either fixed-function pipeline or vertex shader) which could create the kind of lighting that I could do "by hand". Also, if I were to do dynamic lighting, I would have to change my world vertex buffer from static to dynamic, which could be a big performance loss on larger levels.

Back on topic -

I still can't get this color-blending to work. For some reason, I can't find a documented example of this technique anywhere.

Do I have to do multi-stage rendering for this to work? I really hope not, and I don't see why I should have to, seeing as all I'm using for COLOROP is the texture color and the diffuse color.

Share this post


Link to post
Share on other sites
I've noticed another problem. When I add a color value to my VERTEXWORLD structure and adda D3DFVF_DIFFUSE flag to my FVF definition, all my texture coords get messed up! Basically, all the v coords are zeroed. This happens even when I do normal drawing (COLOROP = SELECTARG1) without color blending, and it is unaffected by what I actually set the color values of the vertices to.

This is really weirding me out! Does anyone know how I am going wrong?

Share this post


Link to post
Share on other sites
Quote:
Original post by synth_cat
I can easily explain why I want to render my world this way. For one thing, I want my engine to be as simple as possible. Thus, I steer away from using meshes (which are more or less a way of using more than one FVF for one object, which, as far as I'm concerned, is pointless in this context.)


Usually you want to easily modify or add new geometry to your world. Using meshes is the way to go, unless you have your own geometry editor that helps you arrange triangles in realistic shapes. Why do you care how many FVF per object are being used?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by synth_cat
The reason I don't use "real lights" is similar. They add complexity, for one thing. Since Direct3d only offers support for something like two lights at a time, I would have to write my own vertex shader. Besides which, it would require an immense amount of effort to set up a realtime lighting system (either fixed-function pipeline or vertex shader) which could create the kind of lighting that I could do "by hand". Also, if I were to do dynamic lighting, I would have to change my world vertex buffer from static to dynamic, which could be a big performance loss on larger levels.


I think you've got it backwards...

Using dynamic CPU calculated lighting woud require a dynamic vertex buffer.

Using dymanic "real lights" (GPU calculated) allows you to use a static buffer.

Also, the max lights at once is a lot more than 2. Even old hardware can do 8 lights at once...

No need for vertex shaders here philip.

Share this post


Link to post
Share on other sites
I think I'd better restate my question:
I have a vertex buffer that contains my world geometry. It currently uses only a texture for color, but I want to be able to add a color value to the vertex structure so that I can shade vertices (sort of like pre-calculated per-vertex lighting.) Has anyone ever done this? (My unsuccessful attempts are described in the previous posts.)


Quote:

I think you've got it backwards...
Using dynamic CPU calculated lighting woud require a dynamic vertex buffer.
Using dymanic "real lights" (GPU calculated) allows you to use a static buffer.

You're right (my mistake). However, it is besides the point. I definitely do not want to use any dynamic lighting - it would be so unnecessary if I could just get this blending thing to work.

Quote:

Using meshes is the way to go, unless you have your own geometry editor that helps you arrange triangles in realistic shapes.

I do have my own modeling tools, so I can just stick with a simple vertex buffer. Remember that I want to keep all my world tris in a single drawing call (not a problem since my worlds will be low-poly.)

Share this post


Link to post
Share on other sites
I was just researching this problem when I came across something called D3DLVERTEX. Is this what I have to use to get my rendering method to work?

Thanks!

Share this post


Link to post
Share on other sites
Yes! I finally got it to work!

It turns out that there was nothing wrong with the render states at all - the problem actually resided in my vertex structure and definition!

Here is the old way that did not work:

//here is the FVF define
#define VERTEX_WORLD (D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE )

//here is the vertex structure
struct VERTEXWORLD
{
D3DXVECTOR3 pos;
D3DXVECTOR2 uv;
DWORD color;
};



When I used this method, the vertices would be irregularly tinted and my uv coords would be all messed up. However, the method worked perfectly when I switched to this:

//here is the FVF define
#define VERTEX_WORLD (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)

//here is the vertex structure
struct VERTEXWORLD
{
D3DXVECTOR3 pos;
DWORD color;
D3DXVECTOR2 uv;
};



Even though the blending now works fine, I feel somewhat disturbed by the solution. What if some of my other FVFs generate problematic results like this on my users' machines?

Share this post


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

  • Advertisement