Archived

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

Cuculain

Strangely missing 3D

Recommended Posts

I have a strange problem when executing my DX9 app on another computer. The 2D interface appears as normal and the logs indicate that everything has loaded just fine. But strangely no 3D meshes are rendered (or at least visible) on the screen of the other computers - it''s just black - altough it is still possible to pick the meshes with the mouse. I use a computer with GeForce 4 TI 4600 128 MB and the computers I''ve tried on also had DX9 and G4 TI 4200 64 MB and G2 Ultra 64 MB. Thankful for any ideas...

Share this post


Link to post
Share on other sites
1. Set your clear colour to something other than black to check whether the meshes are''nt appearing at all or whether they''re just appearing in black.

2. If the meshes are appearing, but they appear in black, check your lighting setup, and check any pixel pipeline states (SetTextureStageState() etc). Doing something that isn''t supported in the hardware/driver you''re running on is a common cause for black meshes.

3. NEVER rely on the default values for render states etc - set them explicitly so you KNOW what they''re all set to, and that there isn''t anything unexpected like user clip planes being enabled.

--
Simon O''Connor
ex -Creative Asylum
Programmer &
Microsoft MVP

Share this post


Link to post
Share on other sites
I agree with Simon, check your lighting.



____________________________________________________________
Try RealityRift at www.planetrift.com
Feel free to comment, object, laugh at or agree to this. I won''t engage in flaming because of what I have said.
I could be wrong or right but the ideas are mine.

Share this post


Link to post
Share on other sites
Thanks for your replies. I removed the terrain from rendering and changed the clear color to white. The other objects then appeared as black in contrast. I guess there is something wrong with the lighting then, which is a bit disturbing because it works fine on my dev computer.

And I do init my light (directional) and turn it on.

Share this post


Link to post
Share on other sites
OK, now I have identified the root of this problem. Thanks to Simon for that

It seems that when using SetTextureStageState with index 2 (or higher probably) the results became strange. When using only stage 0 + 1 it works fine on the other machines, but I really need more than two stages.

The troublesome machine is using GeForce 4 440 GO if that has any impact.


m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

m_pDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_ADD);
m_pDevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

m_pDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

Share this post


Link to post
Share on other sites
You need to check the caps for the number of texture stages available. Based on that you may have to do multipass rendering. That''s where the D3DX Effects framework comes in real handy.

I like pie.

Share this post


Link to post
Share on other sites
Yep.

The caps of most interest are: MaxTextureBlendStages and MaxSimultaneousTextures.

MaxSimultaneousTextures is the maximum number of *DIFFERENT* textures you can use in all stages for a single pass. You can often use the same texture multiple times (more than the cap says) though.

MaxTextureBlendStages is pretty obvious really.


Unfortunately though, these caps don''t tell you enough - a card that reports say 5 for MaxTextureBlendStages can''t necessarily do ALL of the possible operations it supports in each of those stages.

There usually ARE restrictions, and it''s also horribly combinatoric - enabling a certain, seemingly unrelated other pixel blending renderstate, and even things like texture format might lose you the ability to use a specific texture stage state or even whole stage.

On GeForce 2 (and other older GeForces and those newer ones that are really disguised GF2s) chips for example, you MaxSimultaneousTextures is only 2 !! and MaxTextureBlendStages is 8.

However MaxTextureBlendStages in this case is misleading:

GF2 can do:

1x 8 stage setup - and not a normal one either, it''s really the nVidia way to get at the TNT style register combiners directly.

1x 4 stage setup

~4x 3 stage setups

any 2 stage setup

any 1 stage setup

no 5,6 or 7 stage setups


By "setup" I mean all of the states in all of the stages, i.e. the 3 and 4 stage setups are VERY specific, designed to allow very specific things to be done (usually after developers have asked if a certain operation is possible).


Because of the combinatoric nature of the TSS setup, D3D has the ValidateDevice() call, this checks the WHOLE pixel pipeline (texture formats, texture stage states, render states etc) to see if what you''re asking for is compatibile with the hardware. i.e. it asks the driver "are all these states going to work on your hardware ?". ValidateDevice() is the only reliable way to check the combinatorical things.

The usual way to use ValidateDevice is when your program first starts up in roughly the following way:


for (each effect/rendering style)
{
for (each technique for achieving that style)
{
Check caps, skip to next technique if caps show this one not possible

SetTextureStageState()s for style
SetRenderState()s for style
etc
if (SUCCEEDED( ValidateDevice() ))
{
technique_to_use_for_this_effect = current_technique;
break;
}

++current_technique;
}
}


The D3DX Effects framework mentioned by RenderTarget does the above for you. Its definately worth a look.


If you need to support ancient graphics hardware like the older 3Dfx Voodoos, then beware that older drivers do occasionally tell lies when you call ValidateDevice() - so I''d provide a hidden "advanced user" setting in your app to ignore the result from VD(). If someone reports a problem to you with that particular driver, you could tell them how to enable your "ignore VD()" setting.
Alternatively you could use Tom Forsyth''s .tom file idea - when you discover a driver where VD() or the caps give dodgy results, you find the device and driver identifier and add it to a file that keeps details of those dodgy devices. Your program then reads the file at startup and alters its settings/behaviour if it detects a chip/driver in the "blacklist".

--
Simon O''Connor
ex -Creative Asylum
Programmer &
Microsoft MVP

Share this post


Link to post
Share on other sites