Sign in to follow this  
sirlemonhead

D3D9 Transparency using diffuse - fixed function

Recommended Posts

Hey, I'm trying to find the root of an issue i'm having rendering some transparent untextured quads for GUI/HUD stuff and screen fade ins. Everything is perfectly fine on my machine when running with the dx release runtime, but if I switch to the debug runtime, all untextured polygons i'm drawing where I use diffuse alpha for transparency appear white/grey coloured. This means my nice fade from black screen sized quad appears as fading in from white. I'm setting these as my texture stages, and not changing them at all during runtime
	d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP,	D3DTOP_MODULATE);
	d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1,	D3DTA_TEXTURE);
	d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2,	D3DTA_DIFFUSE);

	d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,	D3DTOP_MODULATE);
	d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,	D3DTA_TEXTURE);
	d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,	D3DTA_DIFFUSE);

	d3d.lpD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP,	D3DTOP_DISABLE);
	d3d.lpD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP,	D3DTOP_DISABLE);

        d3d.lpD3DDevice->SetRenderState(D3DRS_CULLMODE,	D3DCULL_NONE);
	d3d.lpD3DDevice->SetRenderState(D3DRS_CLIPPING, FALSE);
	d3d.lpD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
	d3d.lpD3DDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
	d3d.lpD3DDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);


This works fine on my pc with the release runtimes, but i'm hearing from other users that they're seeing this white/grey. Perhaps they're running with the debug runtime on but I'd like to sort it out regardless.. Vertex format is:
typedef struct _D3DTLVERTEX {
    union {
        float sx;
        float dvSX;
    };
    union {
        float sy;
        float dvSY;
    };
    union {
        float sz;
        float dvSZ;
    };
    union {
        float rhw;
        float dvRHW;
    };
    union {
        D3DCOLOR color;
        D3DCOLOR dcColor;
    };
    union {
        D3DCOLOR specular;
        D3DCOLOR dcSpecular;
    };
    union {
        float tu;
        float dvTU;
    };
    union {
        float tv;
        float dvTV;
    };
#if (defined __cplusplus) && (defined D3D_OVERLOADS)
    _D3DTLVERTEX() { }
    _D3DTLVERTEX(const D3DVECTOR& v,float w,D3DCOLOR col,D3DCOLOR spec, float _tu, float _tv)
        { sx = v.x; sy = v.y; sz = v.z; rhw=w;
          color = col; specular = spec;
          tu = _tu; tv = _tv;
    }
#endif
} D3DTLVERTEX, *LPD3DTLVERTEX;

#define D3DFVF_TLVERTEX	(D3DFVF_XYZRHW|/*D3DFVF_RESERVED0|*/D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX1)


In a single frame, I change render states a few times. I render my opaques first, then transparents. eg I'd only use D3DRS_ALPHABLENDENABLE, D3DRS_SRCBLEND and D3DRS_DESTBLEND. I also have bilinear No errors from the dx debug output. The irritating thing about this issue is that If I try debug using PIX, everything looks fine regardless of what runtime I use! here's an example of a function which draws a rectangular untextured quad on screen. I don't notice this issue occuring on transparent textured quads. If I debug using PIX, everything of course looks fine, but I can see that i'm definitly setting a null texture and
void D3D_Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a) 
{
#if 1

	D3DCOLOR colour = D3DCOLOR_ARGB(a,r,g,b);

	CheckVertexBuffer(4, -1, TRANSLUCENCY_GLOWING); /* we want to add 4 verts to vertex buffer, use -1 to specify no texture, and enable transparency using 	d3d.lpD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
d3d.lpD3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
d3d.lpD3DDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
*/
	// top left - 0
	mainVertex[vb].sx = x0;
	mainVertex[vb].sy = y0;
	mainVertex[vb].sz = 0.0f;
	mainVertex[vb].rhw = 1.0f;
	mainVertex[vb].color = colour;

	vb++;

	// top right - 1
	mainVertex[vb].sx = x1 - 1;
	mainVertex[vb].sy = y0;
	mainVertex[vb].sz = 0.0f;
	mainVertex[vb].rhw = 1.0f;
	mainVertex[vb].color = colour;

	vb++;

	// bottom right - 2
	mainVertex[vb].sx = x1 - 1;
	mainVertex[vb].sy = y1 - 1;
	mainVertex[vb].sz = 0.0f;
	mainVertex[vb].rhw = 1.0f;
	mainVertex[vb].color = colour;

	vb++;

	// bottom left - 3
	mainVertex[vb].sx = x0;
	mainVertex[vb].sy = y1 - 1;
	mainVertex[vb].sz = 0.0f;
	mainVertex[vb].rhw = 1.0f;
	mainVertex[vb].color = colour;

	vb++;

	OUTPUT_TRIANGLE(0,1,2, 4);
	OUTPUT_TRIANGLE(0,3,2, 4);
#endif
}


the colour values i'm passing are fine. It's a weird one as it does look fine using the release dx runtimes.. Anyone got an ideas? Should I be changing texture state settings when I set a NULL texture? I've tried this but it didnt make a difference..perhaps I did it wrong? Any help appreciated

Share this post


Link to post
Share on other sites
Maybe I'm missing something here...but why are you using a texture as an argument in your colorop and alphaop when you're not texturing the quads? I would think you want to use D3DTOP_SELECTARG2 as your colorop and alphaop. (I never used fixed-function stuff though, so I could be wrong on that)

Share this post


Link to post
Share on other sites
Just a quick glance (I'm not a texture stage expert by any means) - maybe you intend it but shouldn't:

d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

be:

d3d.lpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);

?

Share this post


Link to post
Share on other sites
No matter what I do with the render states, it either disables textures or makes everything white :
Some screenshots. Obviously, not my game, i'm just working with the source code for it (don't want to take any credit where it's not due)

Here's how the console should look - green and yellow
working console

Here's how it looks using the debug runtime
white console

Here's the predators thermal vision showing a marine's thermal image
working thermal

and here it is, all white
white thermal

That's with alpha blending off, texture disabled (according to pix, where it looks fine)

The original pre dx8 code for this game specified this render state:

STATE_DATA(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, ExecBufInstPtr);

which according to information I can find from the linux Wine project, which "emulates" this mode using these settings

SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

I've tried that, same deal.

Share this post


Link to post
Share on other sites
Sorry for the bump, but just wanted to reply here in case anyone ever stumbles across this thread in the future..

my problem was that I wasn't filling in all my vertex information. Ie if I was drawing an untextured quad, I was just doing this:

mainVertex[vb].sx = x0;
mainVertex[vb].sy = y1 - 1;
mainVertex[vb].sz = 0.0f;
mainVertex[vb].rhw = 1.0f;
mainVertex[vb].color = RGBALIGHT_MAKE(r,g,b,a);//colour;

I may have been actually leaving out the rhw value too.

I went back to my problematic functions and added the full fields:

mainVertex[vb].sx = x0;
mainVertex[vb].sy = y1 - 1;
mainVertex[vb].sz = 0.0f;
mainVertex[vb].rhw = 1.0f;
mainVertex[vb].color = RGBALIGHT_MAKE(r,g,b,a);//colour;
mainVertex[vb].specular = 1.0f;
mainVertex[vb].tu = 0.0f;
mainVertex[vb].tv = 0.0f;

(is 1.0f a good default value for specular?)

and everything looks fine now. No more white rendered quads. colours showing as normal :)

Also, filling out the array in the order the values are specified in the vertex format too.

It seems painfully obvious to me now. I guess direct3d was reading junk from those unset values? Either way, I know for the future :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this