0

I'm writing an application which renders graphics on the screen. The application can switch between Direct3D9 and Direct3D10 graphics modules (I wrote DLLs that wrap both D3D9 and D3D10). When trying to render a test mesh (a torus which comes as a stock mesh in D3DX9 and in DXUT library you can find in DirectX10 samples), Direct3D10 module behaves rather weird. Here's what I get.

D3D9: Torus rendered by D3D9 module.

D3D10: Torus rendered by D3D10 module

The view, projection and world matrices are the same for both cases. The only thing that differs is the device initialization code, and the HLSL effect files (for simplicity I only apply ambient colors and don't use advanced lighting, texturing etc). Can this be because of wrong device initialization or because of bad shaders? I would appreciate any hint. I can post any code piece by request.

A guy on Game Dev StackExchange suggested that it is probably because of transposed Projection matrix. I've tried replacing the order the matrices are multiplied in shader file, I've tried almost every permutation I could get, but no right output on the screen.

Thanks in advance. EDIT: Here's the .fx file. You can ignore PS, there's nothing interesting happening in there.

//Basic ambient light shader with no textures
matrix World;
matrix View;
matrix Projection;
float4 AmbientColor : AMBIENT = float4(1.0, 1.0, 1.0, 1.0);
float AmbientIntensity = 1.0;

struct VS_OUTPUT
{
    float4 Position   : SV_POSITION; // vertex position 
    float4 Color    : COLOR0;    // vertex color    
};

RasterizerState rsWireframe { FillMode = WireFrame; };

VS_OUTPUT RenderSceneVS( float4 vPos : POSITION)
{
    VS_OUTPUT output;
    matrix WorldProjView = mul(World, mul(View, Projection));   
    vPos = mul(vPos, WorldProjView);        
    output.Position = vPos;
    output.Color.rgb = AmbientColor * AmbientIntensity;
    output.Color.a = AmbientColor.a;

    return output;
}

struct PS_OUTPUT
{
    float4 RGBColor : SV_Target;  // Pixel color
};

PS_OUTPUT RenderScenePS( VS_OUTPUT In ) 
{
    PS_OUTPUT output;
    output.RGBColor = In.Color;
    return output;
}

technique10 Ambient
{
    pass P0
    {
        SetRasterizerState( rsWireframe );  
        SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( ) ) );
            SetGeometryShader( NULL );
            SetPixelShader( CompileShader( ps_4_0, RenderScenePS( ) ) );            
    }
}
george.zakaryan
  • 960
  • 1
  • 6
  • 18
  • Could you post the shader code? This would greatly help. Also, "Transposed" does not mean the order of multiplication. It means the way the Matrix is formed: http://en.wikipedia.org/wiki/Row-major_order – Stardidi Feb 27 '13 at 15:47
  • I tried using the shader flag parameter to change the matrix order from column major to row major, that didn't help either. – george.zakaryan Feb 27 '13 at 15:50
  • These Matrix issues are such a pain to deal with, try setting your World and View matrix to Identity. If that doesn't fix it, there clearly is a problem in the way you create your Projection matrix. (Maybe post that line of code) – Stardidi Feb 27 '13 at 15:54
  • My Projection matrix is generated by D3DXMatrixPerspectiveFovLH, I pass 640/480 as aspect ratio, PI/4 as field of view, 1.0f and 1000.0f as near and far ranges. – george.zakaryan Feb 27 '13 at 16:06
  • Make sure vPos.w = 1.0f and maybe try transpose(WorldProjView); before you multiply your position with it. Also, Direct3D10 expects World * View * Proj, but your variable name indicates World * Proj * View – Stardidi Feb 27 '13 at 16:15
  • @Stardidi, the reason was vPos.w wasn't 1.0f. After assigning 1.0f to it, the vertex shader worked like a charm. Please post this comment as an answer, I want to accept it. – george.zakaryan Feb 28 '13 at 07:42

3 Answers3

2

Make sure that your vPos.w = 1.0f. If this is not the case, matrix multiplication will go wild and create strange results.

Stardidi
  • 308
  • 2
  • 10
1

Not sure what causes the problem but you can check the following:

  • make sure constant buffers with tranformation matrices are "initialized with something", not some garbage data
  • if you use normal/tangent in your vertex buffer also make sure you don't put some garbage data in there (per vertex) but it would rather cause problem with texturing
  • make sure your vertex layout description matches the input in vertexshader (.hlsl), sometimes even if it doesn't match it will just compile and run but showing some unexpected mesh.
  • I have no idea how is it in DX9 but maybe there is also something with coordinates, multiplying z in vertex buffer on in some transformation matrix by -1 might help

Edit: It might be also good idea to just put some simple mesh into the buffer, cube for example (a triangle even) and check if it's drawning properly.

Lufi
  • 161
  • 1
  • 1
  • 3
  • The mesh is generated by DXUT sample which comes with DirectX SDK. So I don't have much control over it. – george.zakaryan Feb 27 '13 at 16:01
  • You should make sure however that your mesh doesn't contain more information than just POSITION. Actually scratch that, that would just create a really weird mesh. – Stardidi Feb 27 '13 at 16:11
0

You need to transpose your matrices before setting them as shader constants. If you are using xnamath use the XMMatrixTranspose() function on each of the world, view and projection matrices before setting them into your constant buffer.

alanw
  • 645
  • 6
  • 10