Archived

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

Nypyren

Help! D3DTA_DIFFUSE died!

Recommended Posts

I''m trying to color-modulate a greyscale texture to a certain color by modulating TEXTURE with DIFFUSE: device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); // texture device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); But the result is all black, even though my vertex diffuse are all 0xFFFFFFFF. I try SELECTARG2 to get only the diffuse, and it''s pitch black again. I use SELECTARG1 to get only the texture, and it displays the texture fine (but obviously not modulated) I''m using a directional light, FVF is diffuse, xyz, normal, tex1 My memcpy works... Vertexbuffer works (otherwise how would the texture coords be correct?) alphablend is enabled... the transparent places are correct... This is seriously aggrivating.

Share this post


Link to post
Share on other sites
Remember that if you enable lighting, Direct3D don't use diffuse color in your VERTEX structure any more, but the material properties. So to tell D3D that he must use diffuse value of your vertex structure, try this:

device->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );

(although I'm not sure it will work)

[edited by - HiddenInBSP on September 1, 2002 6:12:53 AM]

Share this post


Link to post
Share on other sites
I tried your code... everything behaves the same (DIFFUSE pretends to be black)

I TOTALLY disabled lighting... normals, lights, vertex format...

texturing still works, diffuse does not.


The strange part is that when I have lighting enabled, and I spin the light''s direction around, the texture stays the same brightness...

Share this post


Link to post
Share on other sites
If this helps any:

vertex format flags:

#define FVF_CUSTOMVERTEX (D3DFVF_DIFFUSE | D3DFVF_NORMAL | D3DFVF_XYZ | D3DFVF_TEX1)


vertex buffer is using the following:
CUSTOMVERTEX cv[4] = { {-0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 0xFFFFFF00, 0.0, 0.0},
{ 0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 0xFFFF00FF, 1.0, 0.0},
{-0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 0xFF00FFFF, 0.0, 1.0},
{ 0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 0xFFFFFFFF, 1.0, 1.0} };

// It''s a square with a texture in it.

this is my "SetRenderStates()" function:

{
device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); // texture
device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

device->SetRenderState(D3DRS_ZENABLE, true);
device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
}

This is my render primitive function:
{
device->SetIndices(iBuffer, 0);
device->SetTexture(0, texture);
device->SetVertexShader(FVF_CUSTOMVERTEX);
device->SetStreamSource(0, vBuffer, sizeof(CUSTOMVERTEX));

if (D3D_OK != device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, numVerts, 0, numTris))
throw "BUNK";
}


I checked the vertex buffer by locking, dumping to memory and printing to file, unlocking... the data is perfect.

I''ve done this before in DirectX 8.0, worked great, but now I''m using 8.1, and I suspect that I''m forgetting something like a RenderState or some feces.

Share this post


Link to post
Share on other sites
I think you will have to define material properties, or if you want you can put:
device->SetRenderState( D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1 );
If it don''t work, I think your data are corrupts...

Share this post


Link to post
Share on other sites
typedef struct
{
float x, y, z;
float nx, ny, nz;
DWORD color;
float u, v; // texture coords
} CUSTOMVERTEX;


Here''s my plan... I''m going to start a new project from scratch and try to get the Tutorial with the spinning triangle working again...

Hopefully that will help me figure it out

Share this post


Link to post
Share on other sites
You''re my official hero!

device->SetRenderState( D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1 );

It fixed my problems!


I guess the issue was that with 8.0 I didn''t need to mess with materials, and 8.1 I have to.

Share this post


Link to post
Share on other sites
Ok, it seems good, but the solution that I've given you is not really a "good" solution (although it works), cause if your vertices emit color, they can't be correctly affected by other lights (So if you want to add other light effects, in the future, maybe it will suck)...
I think there is a problem with your light...
And to light correctly your vertices, you can try this:

//The ambient reflection is defined by Diffuse member of VERTEX
//structure
Device->SetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1 );

//Put a white and bright ambient light
Device->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB( 255, 255, 255 ) );

If it works (I'm not sure), so use this instead of using emissive material...

[edited by - HiddenInBSP on September 2, 2002 6:37:28 AM]

Share this post


Link to post
Share on other sites
After I messed around a bit more, I changed EMISSIVE back to DIFFUSEMATERIALSOURCE, and actually created a pure-white material like the MSDN tutorial for lighting shows... and everything works great.

I hate it when they don't have a "things you need to do in 8.1 that you didn't need in 8.0" section in there...


So anyway, everything seems to be working great.. lighting and all.

This is what I'm using *finally*


D3DLIGHT8 light;
ZeroMemory( &light, sizeof(D3DLIGHT8) );
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse = color;
light.Range = 1000.0f;
light.Direction = dir;
light.Attenuation0 = 1.0f;

device->SetLight(l, &light);
device->LightEnable(l, TRUE);
device->SetRenderState(D3DRS_LIGHTING, TRUE);
device->SetRenderState(D3DRS_AMBIENT, 0x00000000);


D3DMATERIAL8 mtrl;
ZeroMemory( &mtrl, sizeof(D3DMATERIAL8) );
mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
mtrl.Diffuse.b = mtrl.Ambient.b = 1.0f;
mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
device->SetMaterial( &mtrl );


device->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );

device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

device->SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF); // or whatever color to modulate the entire texture with

device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR);

device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
device->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
device->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);


device->SetRenderState(D3DRS_ZENABLE, true);
device->SetRenderState(D3DRS_NORMALIZENORMALS, true);


[edited by - Nypyren on September 3, 2002 2:27:37 PM]

Share this post


Link to post
Share on other sites