# 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.

## Recommended Posts

##### Share on other sites
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.

Cheers,
Jason

##### 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.

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 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 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 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.hstruct 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 on other sites
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 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 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 on other sites
Quote:
 Original post by synth_catI 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 on other sites
Quote:
 Original post by synth_catThe 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 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 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 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 structurestruct 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 structurestruct 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?