problem with vertex shader

Started by
6 comments, last by 6666662000 18 years, 4 months ago
Hi,all! I was trying to write a simple vs just simulate fixed pipeline render. But the result is uncorrect!!! the main source is below: 1.vsh

; input	:   v0   = pos
;           v1   = diffuse, not used
;           v2   = texture coord
;           c0-3 = WorldViewProjection 

vs.1.0                             ; shader version 1.0
m4x4    oPos , v0   , c0           
mov	oT0.xy	, v2



the cpp code is modied from the D3D8SDK's sample:Texture vertex shader creation code:

	DWORD dwDecl[] =
	{
		D3DVSD_STREAM(0),
			D3DVSD_REG( 0,  D3DVSDT_FLOAT3 ),
			D3DVSD_REG( 1,    D3DVSDT_D3DCOLOR ),
			D3DVSD_REG( 2, D3DVSDT_FLOAT2 ),
			D3DVSD_END()
	};

	if( FAILED( g_pd3dDevice->CreateVertexShader( dwDecl, (DWORD*)buffer->GetBufferPointer(), &m_dwShader, 0 ) ) )
		return E_FAIL;



render code:

	D3DXMATRIX matWorld, matView, matProj, matWVP;
	g_pd3dDevice->GetTransform( D3DTS_WORLD, &matWorld );
	g_pd3dDevice->GetTransform( D3DTS_VIEW, &matView );
	g_pd3dDevice->GetTransform( D3DTS_PROJECTION, &matProj );

	matWVP =( matWorld * matView) * matProj;

	g_pd3dDevice->SetVertexShaderConstant( 0, &matWVP, 4 );



Where is wrong?Please help me!Thanks!
Advertisement
Two things. First, the "GetTransform" functions won't work if you're using a pure device. Second, vertex shaders and the fixed function transformation pipeline are mutually exclusive. So that means that you cannot use both "SetTransform" types of calls along with "SetVertexShader". Whichever one you set last before you render is the one that will be applied.

So what you need to do is have your keep track of the matrices used instead of relying on the "GetTransform" functions. Even if you're using a non-pure device, those functions will likely return garbage when used with shaders.

neneboricua
after your show, still wrong!
the whole code is below:
#include <d3dx8.h>#include <mmsystem.h>//-----------------------------------------------------------------------------// Global variables//-----------------------------------------------------------------------------LPDIRECT3D8             g_pD3D       = NULL; // Used to create the D3DDeviceLPDIRECT3DDEVICE8       g_pd3dDevice = NULL; // Our rendering deviceLPDIRECT3DVERTEXBUFFER8 g_pVB        = NULL; // Buffer to hold verticesLPDIRECT3DTEXTURE8      g_pTexture   = NULL; // Our texture// A structure for our custom vertex type. We added texture coordinatesstruct CUSTOMVERTEX{    D3DXVECTOR3 position; // The position    D3DCOLOR    color;    // The color    FLOAT       tu, tv;   // The texture coordinates};// Our custom FVF, which describes our custom vertex structure#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)//-----------------------------------------------------------------------------// Name: InitD3D()// Desc: Initializes Direct3D//-----------------------------------------------------------------------------HRESULT InitD3D( HWND hWnd ){    // Create the D3D object.    if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )        return E_FAIL;    // Get the current desktop display mode, so we can set up a back    // buffer of the same format    D3DDISPLAYMODE d3ddm;    if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )        return E_FAIL;    // Set up the structure used to create the D3DDevice. Since we are now    // using more complex geometry, we will create a device with a zbuffer.    D3DPRESENT_PARAMETERS d3dpp;    ZeroMemory( &d3dpp, sizeof(d3dpp) );    d3dpp.Windowed = TRUE;    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    d3dpp.BackBufferFormat = d3ddm.Format;    d3dpp.EnableAutoDepthStencil = TRUE;    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;    // Create the D3DDevice    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,                                      D3DCREATE_HARDWARE_VERTEXPROCESSING,                                      &d3dpp, &g_pd3dDevice ) ) )    {        return E_FAIL;    }    // Turn off culling    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );    // Turn off D3D lighting    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );    // Turn on the zbuffer    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );    return S_OK;}DWORD m_dwShader;//-----------------------------------------------------------------------------// Name: InitGeometry()// Desc: Create the textures and vertex buffers//-----------------------------------------------------------------------------HRESULT InitGeometry(){    // Use D3DX to create a texture from a file based image    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp",                                           &g_pTexture ) ) )        return E_FAIL;    // Create the vertex buffer.    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),                                                  0, D3DFVF_CUSTOMVERTEX,                                                  D3DPOOL_DEFAULT, &g_pVB ) ) )    {        return E_FAIL;    }    // Fill the vertex buffer. We are setting the tu and tv texture    // coordinates, which range from 0.0 to 1.0    CUSTOMVERTEX* pVertices;    if( FAILED( g_pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 ) ) )        return E_FAIL;    for( DWORD i=0; i<50; i++ )    {        FLOAT theta = (2*D3DX_PI*i)/(50-1);        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta) * 3.0f,-3.0f, cosf(theta) * 3.0f );        pVertices[2*i+0].color    = 0xffffffff;        pVertices[2*i+0].tu       = ((FLOAT)i)/(50-1);        pVertices[2*i+0].tv       = 1.0f;        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta) * 3.0f, 3.0f, cosf(theta) * 3.0f );        pVertices[2*i+1].color    = 0xff808080;        pVertices[2*i+1].tu       = ((FLOAT)i)/(50-1);        pVertices[2*i+1].tv       = 0.0f;    }    g_pVB->Unlock();	LPD3DXBUFFER	buffer;	LPD3DXBUFFER	errmsg;	if( FAILED( D3DXAssembleShaderFromFile( "1.vsh", 0, NULL, &buffer, &errmsg ) ) )		return E_FAIL;	DWORD dwDecl[] =	{		D3DVSD_STREAM(0),			D3DVSD_REG( 0,  D3DVSDT_FLOAT3 ),			D3DVSD_REG( 1,    D3DVSDT_D3DCOLOR ),			D3DVSD_REG( 2, D3DVSDT_FLOAT2 ),			D3DVSD_END()	};	if( FAILED( g_pd3dDevice->CreateVertexShader( dwDecl, (DWORD*)buffer->GetBufferPointer(), &m_dwShader, 0 ) ) )		return E_FAIL;    return S_OK;}//-----------------------------------------------------------------------------// Name: Cleanup()// Desc: Releases all previously initialized objects//-----------------------------------------------------------------------------VOID Cleanup(){    if( g_pTexture != NULL )        g_pTexture->Release();    if( g_pVB != NULL )        g_pVB->Release();    if( g_pd3dDevice != NULL )        g_pd3dDevice->Release();    if( g_pD3D != NULL )        g_pD3D->Release();}//-----------------------------------------------------------------------------// Name: Render()// Desc: Draws the scene//-----------------------------------------------------------------------------VOID Render(){    // Clear the backbuffer and the zbuffer    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,                         D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );    // Begin the scene    g_pd3dDevice->BeginScene();    g_pd3dDevice->SetTexture( 0, g_pTexture );    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );	// Apply vertex shader	g_pd3dDevice->SetVertexShader( m_dwShader );	D3DXMATRIX matWorld, matView, matProj, matWVP;	D3DXMatrixIdentity( &matWorld );	D3DXMatrixRotationX( &matWorld, timeGetTime()/1000.0f );	D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-15.0f ),		&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),		&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );	D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );	matWVP =( matWorld * matView) * matProj;	g_pd3dDevice->SetVertexShaderConstant( 0, &matWVP, 4 );    // Render the vertex buffer contents    g_pd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );    g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );    // End the scene    g_pd3dDevice->EndScene();    // Present the backbuffer contents to the display    g_pd3dDevice->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:            PostQuitMessage( 0 );            return 0;    }    return DefWindowProc( hWnd, msg, wParam, lParam );}//-----------------------------------------------------------------------------// Name: WinMain()// Desc: The application's entry point//-----------------------------------------------------------------------------INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ){    // Register the window class    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,                      "D3D Tutorial", NULL };    RegisterClassEx( &wc );    // Create the application's window    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 05: Textures",                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,                              GetDesktopWindow(), NULL, wc.hInstance, NULL );    // Initialize Direct3D    if( SUCCEEDED( InitD3D( hWnd ) ) )    {        // Create the scene geometry        if( SUCCEEDED( InitGeometry() ) )        {            // Show the window            ShowWindow( hWnd, SW_SHOWDEFAULT );            UpdateWindow( hWnd );            // Enter the message loop            MSG msg;            ZeroMemory( &msg, sizeof(msg) );            while( msg.message!=WM_QUIT )            {                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )                {                    TranslateMessage( &msg );                    DispatchMessage( &msg );                }                else                    Render();            }        }    }    // Clean up everything and exit the app    Cleanup();    UnregisterClass( "D3D Tutorial", wc.hInstance );    return 0;}
You're never calling SetVertexDeclaration or SetFVF. You need to call one (and only one) of these to tell D3D what type of vertices to expect. This is the case regardless of whether you're using shaders or the fixed function pipeline and is covered in the tutorials included with the SDK.

neneboricua
Hey, I think there's something different between DX8 and DX9.
In DX8 there is no SetFVF and SetVertexDeclaration function. DX8 use SetVertexShader instead of SetFVF. If you use shader, you just send a DWORD which get from the 3rd parameter of CreateVertexShader.Otherwise if you want to use fixed function pipeline, you send D3DFVF_XYZ... to the SetVertexShader()
you can see the code in my main topic.
Quote:I was trying to write a simple vs just simulate fixed pipeline render. But the result is uncorrect!!!

Could you elaborate on what was incorrect about it?

Was the visual output incorrect? colours/textures wrong? was the geometry in the wrong place? did the geometry not move as you expect it to?

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

It's hard to describe!It just like you was In the bucket.Not Outside the bucket.I think I've passed in the correct matrix: matWorld * matView * matProj
The texture seems right.
You can copy the source code and build a project to see the scene yourself.
Did this right:
; input	:   v0   = pos;           v1   = diffuse, not used;           v2   = texture coord;           c0-3 = WorldViewProjection vs.1.0                             ; shader version 1.0m4x4    oPos , v0   , c0           mov	oT0.xy	, v2

Need oPos.xyz divided by oPos.w?
eeeeee..., for there days, I found where is the problem. The matrix dat must be transposed before passing into the shader.The matrix in the shader is row basis!!!
Hope this some helpful to the people with the same puzzle.

This topic is closed to new replies.

Advertisement