Sign in to follow this  

problem with vertex shader

This topic is 4388 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 D3DDevice
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER8 g_pVB = NULL; // Buffer to hold vertices
LPDIRECT3DTEXTURE8 g_pTexture = NULL; // Our texture

// A structure for our custom vertex type. We added texture coordinates
struct 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;
}


Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.0
m4x4 oPos , v0 , c0
mov oT0.xy , v2



Need oPos.xyz divided by oPos.w?

Share this post


Link to post
Share on other sites

This topic is 4388 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this