Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 1 (5 posts)

Problem getting a simple vertex shader to run

Last post 11/11/2009 1:29 PM by adamroper. 4 replies.
  • 8/7/2009 9:49 AM

    Problem getting a simple vertex shader to run

    Hi,

    I was trying to set up a simple vertex shader and get in running on two triangles but for some reason it doesn't seem to be applied to the vertices. As you'll be able to see if the shader was successfully run all the vertices would be white but unfortunately for me they are not.

    I have the D3D_DEBUG_INFO preprocessor flag set for Direct3D. I get no warnings from Direct3D except if I run in software processing mode where it outputs saying there was a first chance exception. I have an NVidia Quadro FX 3700 graphics card that supports vertex shader 3.0. When I try to debug the vertex shaders using pix it says "An error occurred while attempting to debug shader". If I look at the mesh tab in PIX it says vertes shading disabled. All the Direct3D calls return D3D_OK.

    If anyone would like to run the program for me and see if they get the same results, I've added all the includes and libraries by pragma calls so literally all you have to do is create a blank Win32 project and paste the code into your main file and put the SimpleHLSL.fx file in a subfolder called shaders.

    I'm really at a loose end on this one, any help would be appreciated.

    Thanks =)

    SimpleHLSL.fx

     
     
    //--------------------------------------------------------------------------------------  
    // Global variables  
    //--------------------------------------------------------------------------------------  
     
    float4x4    gr4x4WorldViewProjection;  
     
    struct cOutputVS  
    {  
        float4  mPositionOut    : POSITION;  
        float4  mColourOut      : COLOR0;  
    };  
     
    cOutputVS MyVertexShaderVS(   
            float4  lPositionIn     : POSITION,  
            float4  lColourIn       : COLOR0 )  
    {  
        cOutputVS lOutputVS;  
          
        lOutputVS.mPositionOut = mul( lPositionIn, gr4x4WorldViewProjection );  
     
        lOutputVS.mColourOut = float4( 1.0f, 1.0f, 1.0f, 1.0f); //lColourIn;  
          
        return lOutputVS;  
    }  
     
    technique EntryPoint  
    {  
        pass P0  
        {  
            VertexShader = compile vs_3_0 MyVertexShaderVS();  
        }  
    }  
     

    main.cpp
    #include "stdafx.h"  
     
    #include <stdio.h>
    #define VC_EXTRALEAN  
    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>  
     
    #include <d3d9.h>
    #include <d3dx9Effect.h>  
    #pragma comment ( lib, "d3d9.lib" )
    #pragma comment ( lib, "d3dx9.lib" )  
    #pragma comment ( lib, "d3dcompiler.lib" )  
     
    typedef unsigned int U32;
    #include <d3d9.h>  
    #pragma warning( disable : 4996 ) // disable deprecated warning   
    #include <strsafe.h>
    #pragma warning( default : 4996 )  
     
    //-----------------------------------------------------------------------------  
    // Global variables  
    //-----------------------------------------------------------------------------  
    IDirect3D9*         gpD3d = NULL; // Used to create the D3DDevice  
    IDirect3DDevice9*   gpD3dDevice = NULL; // Our rendering device  
     
    class cVertex  
    {  
    public:  
        float   mrX;  
        float   mrY;  
        float   mrZ;  
        float   mrRHW;  
        U32     muColour;  
    };  
     
    cVertex gaVertices[ 4 ] =   
    {  
        { 0.0f, 0.0f, 0.0f, 1.0f, 0xffff0000 },  
        { 100.0f, 0.0f, 0.0f, 1.0f, 0xff0000ff },  
        { 0.0f, 100.0f, 0.0f, 1.0f, 0xff00ff00 },  
        { 100.0f, 100.0f, 0.0f, 1.0f, 0xffffffff }  
    };  
     
    IDirect3DVertexBuffer9* gpVertexBuffer = NULL;  
     
    U32 guVertexFormat = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;  
     
    U32 guVertexSoftwareOrHardwareProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;  
    //U32 guVertexSoftwareOrHardwareProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  
     
    ID3DXEffect*    gpEffect = NULL;  
     
     
    //-----------------------------------------------------------------------------  
    // Name: InitD3D()  
    // Desc: Initializes Direct3D  
    //-----------------------------------------------------------------------------  
    HRESULT InitD3D( HWND hWnd )  
    {  
        // Create the D3D object, which is needed to create the D3DDevice.  
        if( NULL == ( gpD3d = Direct3DCreate9( D3D_SDK_VERSION ) ) )  
            return E_FAIL;  
     
        // Set up the structure used to create the D3DDevice. Most parameters are  
        // zeroed out. We set Windowed to TRUE, since we want to do D3D in a  
        // window, and then set the SwapEffect to "discard", which is the most  
        // efficient method of presenting the back buffer to the display.  And   
        // we request a back buffer format that matches the current desktop display   
        // format.  
        D3DPRESENT_PARAMETERS d3dpp;  
        ZeroMemory( &d3dpp, sizeof( d3dpp ) );  
        d3dpp.Windowed = TRUE;  
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;  
        d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;  
     
        // Create the Direct3D device. Here we are using the default adapter (most  
        // systems only have one, unless they have multiple graphics hardware cards  
        // installed) and requesting the HAL (which is saying we want the hardware  
        // device rather than a software one). Software vertex processing is   
        // specified since we know it will work on all cards. On cards that support   
        // hardware vertex processing, though, we would see a big performance gain   
        // by specifying hardware vertex processing.  
        if( FAILED( gpD3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,  
                                          guVertexSoftwareOrHardwareProcessing,  
                                          &d3dpp, &gpD3dDevice ) ) )  
        {  
            return E_FAIL;  
        }  
     
        // Check device capabilities  
     
        // Device state would normally be set here  
     
        gpD3dDevice->SetFVF( guVertexFormat );   
        gpD3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );  
     
        // Set up vertex buffer  
     
        gpD3dDevice->CreateVertexBuffer(   
            sizeof( gaVertices ),  
            guVertexSoftwareOrHardwareProcessing,  
            guVertexFormat,  
            D3DPOOL_DEFAULT,   
            &gpVertexBuffer,  
            NULL );  
     
        void* lpVertexBufferData;  
     
        gpVertexBuffer->Lock( 0, sizeof( gaVertices ), &lpVertexBufferData, 0 );  
     
        memcpy( lpVertexBufferData, gaVertices, sizeof( gaVertices ) );  
     
        gpVertexBuffer->Unlock();  
     
        // Vertex Shader Effect  
        ID3DXBuffer*    lpCompilationErrorsBuffer;  
     
        HRESULT lResult = D3DXCreateEffectFromFileA(  
            gpD3dDevice,  
            "Shaders/SimpleHLSL.fx",  
            NULL,  
            NULL,
    #ifndef _DEBUG  
            D3DXSHADER_OPTIMIZATION_LEVEL3,
    #else  
            D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION,
    #endif  
            NULL,  
            &gpEffect,  
            &lpCompilationErrorsBuffer );  
     
        if ( lResult != S_OK )  
        {  
            printf( "%s", lpCompilationErrorsBuffer->GetBufferPointer() );  
            return E_FAIL;  
        }  
     
        D3DXMATRIX lWorld;  
        D3DXMATRIX lView;  
        D3DXMATRIX lProjection;  
        D3DXMATRIX lWorldViewProjection;  
              
        gpD3dDevice->GetTransform( D3DTS_WORLD, &lWorld );  
        gpD3dDevice->GetTransform( D3DTS_VIEW, &lView );  
        gpD3dDevice->GetTransform( D3DTS_PROJECTION, &lProjection );  
     
        D3DXMatrixMultiply( &lWorldViewProjection, &lWorld, &lView );  
        D3DXMatrixMultiply( &lWorldViewProjection, &lWorldViewProjection, &lProjection );  
     
        lResult = gpEffect->SetMatrix( "gr4x4WorldViewProjection", &lWorldViewProjection );  
     
        lResult = gpEffect->SetTechnique( "EntryPoint" );  
     
        return S_OK;  
    }  
     
     
     
     
    //-----------------------------------------------------------------------------  
    // Name: Cleanup()  
    // Desc: Releases all previously initialized objects  
    //-----------------------------------------------------------------------------  
    VOID Cleanup()  
    {  
        if ( gpEffect != NULL )  
        {  
            gpEffect->Release();  
        }  
     
        if ( gpVertexBuffer != NULL )  
        {  
            gpVertexBuffer->Release();  
        }  
     
        if( gpD3dDevice != NULL )  
            gpD3dDevice->Release();  
     
        if( gpD3d != NULL )  
            gpD3d->Release();  
    }  
     
     
     
     
    //-----------------------------------------------------------------------------  
    // Name: Render()  
    // Desc: Draws the scene  
    //-----------------------------------------------------------------------------  
    VOID Render()  
    {  
        HRESULT lResult;  
     
        if( NULL == gpD3dDevice )  
            return;  
     
        // Clear the backbuffer to a blue color  
        gpD3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );  
     
        // Begin the scene  
        if( SUCCEEDED( gpD3dDevice->BeginScene() ) )  
        {  
            U32 luNumPasses;  
     
            lResult = gpEffect->Begin( &luNumPasses, 0 );  
     
            for( U32 luPass = 0; luPass < luNumPasses; luPass++ )  
            {  
                lResult = gpEffect->BeginPass( luPass );  
     
                // The effect interface queues up the changes and performs them   
                // with the CommitChanges call. You do not need to call CommitChanges if   
                // you are not setting any parameters between the BeginPass and EndPass.  
                // V( g_pEffect->CommitChanges() );  
     
                // Render the mesh with the applied technique  
     
                gpD3dDevice->SetStreamSource( 0, gpVertexBuffer, 0, sizeof( cVertex ) );   
                gpD3dDevice->DrawPrimitive(   
                    D3DPT_TRIANGLESTRIP, // D3DPRIMITIVETYPE PrimitiveType,  
                    0, // UINT StartVertex,  
                    2 ); // UINT PrimitiveCount  
     
                lResult = gpEffect->EndPass();  
            }  
     
            gpEffect->End();  
     
            // End the scene  
            gpD3dDevice->EndScene();  
        }  
     
        // Present the backbuffer contents to the display  
        gpD3dDevice->Present( NULL, NULL, NULL, NULL );  
    }  
     
     
     
     
    //-----------------------------------------------------------------------------  
    // Name: MsgProc()  
    // Desc: The window's message handler  
    //-----------------------------------------------------------------------------  
    LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )  
    {  
        switch( msg )  
        {  
            case WM_DESTROY:  
                Cleanup();  
                PostQuitMessage( 0 );  
                return 0;  
     
            case WM_PAINT:  
                Render();  
                ValidateRect( hWnd, NULL );  
                return 0;  
        }  
     
        return DefWindowProc( hWnd, msg, wParam, lParam );  
    }  
     
     
     
     
    //-----------------------------------------------------------------------------  
    // Name: wWinMain()  
    // Desc: The application's entry point  
    //-----------------------------------------------------------------------------  
    INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )  
    {  
        // Register the window class  
        WNDCLASSEX wc =  
        {  
            sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,  
            GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,  
            L"D3D Vertex Shader Test", NULL  
        };  
        RegisterClassEx( &wc );  
     
        // Create the application's window  
        HWND hWnd = CreateWindow( L"D3D Vertex Shader Test", L"D3D Vertex Shader Test",  
                                  WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,  
                                  NULL, NULL, wc.hInstance, NULL );  
     
        // Initialize Direct3D  
        if( SUCCEEDED( InitD3D( hWnd ) ) )  
        {  
            // Show the window  
            ShowWindow( hWnd, SW_SHOWDEFAULT );  
            UpdateWindow( hWnd );  
     
            // Enter the message loop  
            MSG msg;  
            while( GetMessage( &msg, NULL, 0, 0 ) )  
            {  
                TranslateMessage( &msg );  
                DispatchMessage( &msg );  
            }  
        }  
     
        UnregisterClass( L"D3D Vertex Shader Test", wc.hInstance );  
        return 0;  
    }  
     
  • 8/7/2009 7:51 PM In reply to

    Re: Problem getting a simple vertex shader to run

    2 things:
    1)turn on the D3D9 debug runtime via the control panel
    2)dont use xyzrhw, thats pre-transformed vertices and of course wont be affected by the vertex pipeline.
  • 8/10/2009 10:15 AM In reply to

    Re: Problem getting a simple vertex shader to run

    Hi Phil, thanks for the reply!

    PhilTaylor:
    2 things:
    1)turn on the D3D9 debug runtime via the control panel.


    Yep when I mentioned getting no warnings from D3D I meant with the debug runtime enabled.

    PhilTaylor:
    2)dont use xyzrhw, thats pre-transformed vertices and of course wont be affected by the vertex pipeline


    Thanks for this, I wasn't aware that RHW signified pre-transformed vertices and skipped the vertex shader. I really probably should have read up more. Thanks again!!
  • 8/10/2009 3:49 PM In reply to

    Re: Problem getting a simple vertex shader to run

    The other thing you might want to start getting familiar with are vertex declarations instead of FVF. These are a bit more flexible to work with and makes it easier to switch to an all shader oriented API like DX10. Where you will have to define the shader inputs in a similiar fashion.
  • 11/11/2009 1:29 PM In reply to

    Re: Problem getting a simple vertex shader to run

    Have you called {myDevice}->SetVertexDeclaration() anywhere?  If not then the vertex shader won't be able to pick up the format of your textures.
Page 1 of 1 (5 posts) Previous Discussion Next Discussion