Sign in to follow this  

vertex and pixel shader question

Recommended Posts

OK so after looking at several tutorials, I have gotten my little simulation rendering with them. however the problem I am having is that not everything rendering when they are enabled the render calls buried in my class are not drawing to the screen..., would there be a reason that the SetPixelShader, and SetVertexShader would not get carried into the class when I pass it the render device?, or how would I have to pass them in and set them in the class manually?

Share this post

Link to post
Share on other sites
I don't understand your question. The current vertex shader and current pixel shader are part of the current pipeline state and they stay set on the device until you change them. It has no relevance to the structure of your code in terms of methods, subroutines, calls, etc., except in the sense that wherever your code sets the vertex shader or pixel shader, it stays set that way until some other code you've written changes that piece of state.

Share this post

Link to post
Share on other sites
ok, now i can't get anything to render, this is frustrating.


here is the rendering code from the tutorial (link)


// communicate with shaders (NEW)
D3DXMATRIXA16 matWorld, matView, matProj;
app.getDevice()->GetTransform(D3DTS_WORLD, &matWorld);
app.getDevice()->GetTransform(D3DTS_VIEW, &matView);
app.getDevice()->GetTransform(D3DTS_PROJECTION, &matProj);

D3DXMATRIXA16 matWorldViewProj = matWorld * matView * matProj;
constantTable->SetMatrix(app.getDevice(), "WorldViewProj", &matWorldViewProj);

// render scene with shaders (NEW)
app.getDevice()->SetStreamSource(0, quadVB, 0, sizeof(D3DVERTEX));
app.getDevice()->SetTexture(0, quadTexture);
app.getDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

app.getDevice()->Present(0, 0, 0, 0);

the code as written in their sample does compile and run, so I know it works.

however they never set anything to the matrices, so i think they are not doing any transforms.

I have tried to mimic this code copying my matrices in, and not calling "SetTransform" for view, projection, and world, instead copying those matrices as they would have been called without the shaders.

but all I get is a black render no matter what I do now.

ViewportInfo.Width = SCREEN_WIDTH;
ViewportInfo.Height = SCREEN_HEIGHT;
ViewportInfo.X = 0;
ViewportInfo.Y = 0;
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 212, 208, 200), 1.0f, 0);


D3DXQuaternionRotationMatrix(&matViewQuatIn,&matView); //Step 1
D3DXQuaternionRotationYawPitchRoll(&matViewQuat,CamYaw,CamPitch,CamRoll); //Step 2
D3DXQuaternionMultiply(&matViewQuatOut,&matViewQuatIn,&matViewQuat); //Step 3
D3DXQuaternionNormalize(&matViewQuatOut, &matViewQuatOut); //Step 4
D3DXMatrixRotationQuaternion(&matViewOut,&matViewQuatOut); //Step 5

D3DXMatrixTranslation(&matView, //Step 6
matView = matView * matViewOut; //Step 7
//d3ddev->SetTransform(D3DTS_VIEW, &(matView)); //Step 8
matView2 = matView;

CameraFront = D3DXVECTOR3 (0.0f,0.0f,1.0f);
CameraRight = D3DXVECTOR3 (1.0f,0.0f,0.0f);
CameraUp = D3DXVECTOR3 (0.0f,-1.0f,0.0f);
TempDeterminant = D3DXMatrixDeterminant(&matViewOut);
D3DXMatrixInverse(&TempCameraMat, &TempDeterminant, &matViewOut);
D3DXVec3Transform(&TempCameraVec, &CameraFront, &TempCameraMat);
CameraFront = D3DXVECTOR3 (TempCameraVec.x,TempCameraVec.y,TempCameraVec.z);
D3DXVec3Transform(&TempCameraVec, &CameraRight, &TempCameraMat);
CameraRight = D3DXVECTOR3 (TempCameraVec.x,TempCameraVec.y,TempCameraVec.z);
D3DXVec3Transform(&TempCameraVec, &CameraUp, &TempCameraMat);
CameraUp = D3DXVECTOR3 (TempCameraVec.x,TempCameraVec.y,TempCameraVec.z);

D3DXMATRIX matProjection; // the projection transform matrix
D3DXToRadian(CamFOV), // the horizontal field of view
(SCREEN_HEIGHT/.75)/SCREEN_HEIGHT, // the aspect ratio
0.001f, // the near view-plane
3000.0f); // the far view-plane
//d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection
matProj2 = matProjection;

D3DXMatrixScaling(&matScale, 10, 10, 10);

D3DXMatrixTranslation(&matTranslate, -CameraPosition.x, -CameraPosition.y, -CameraPosition.z);
D3DXMatrixRotationX(&matRotateX, GalaxyXAxis); // the rotation matrix
D3DXMatrixRotationY(&matRotateY, GalaxyYAxis); // the rotation matrix
D3DXMatrixRotationZ(&matRotateZ, 0); // the rotation matrix
//d3ddev->SetTransform(D3DTS_WORLD, &(matScale*matRotateX*matRotateY*matRotateZ*matTranslate)); // set the world transform;
matWorld2 = matScale*matRotateX*matRotateY*matRotateZ*matTranslate;

d3ddev->SetMaterial(&material[0]); // set the material for the subset
d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); // turn off the 3D lighting for the background

Blend = 255;
d3ddev->SetRenderState(D3DRS_BLENDFACTOR, GalaxyBlend);

ViewportInfo.Width = 1019;
ViewportInfo.Height = 768;
ViewportInfo.X = 256;
ViewportInfo.Y = 5;
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 0), 1.0f, 0);
CamFOV = 60;

d3ddev->GetTransform(D3DTS_WORLD, &matWorld2);
d3ddev->GetTransform(D3DTS_VIEW, &matView2);
d3ddev->GetTransform(D3DTS_PROJECTION, &matProj2);

D3DXMATRIXA16 matWorldViewProj = matWorld2 * matView2 * matProj2;
constantTable->SetMatrix(d3ddev, "WorldViewProj", &matWorldViewProj);
constantTable->SetFloat(d3ddev,"ColorIn1", ShaderColor.w);
constantTable->SetFloat(d3ddev,"ColorIn2", ShaderColor.x);
constantTable->SetFloat(d3ddev,"ColorIn3", ShaderColor.y);
constantTable->SetFloat(d3ddev,"AlphaIn1", ShaderColor.z);


d3ddev->SetTexture(0, texture[1]);
Galaxy->DrawSubset(0); //draw Galaxy

what it should look like without the shader modifications

I set the viewport 4 times to render the 3 sections and the background, although the last two sections are commented out in the code right now

link to the unmodified render function

anyway any help would be appreciated, I would like to get shaders working at some time :) thanks

Share this post

Link to post
Share on other sites
First, you could use the D3DXEffect interface, it's easy to use.

The difference between SetTransform and their tutorial is, that the Fixed Function Pipeline doesn't directly transform the vertices . Instead you pass the multiplied matrix

constantTable->SetMatrix(app.getDevice(), "WorldViewProj", &matWorldViewProj);

to the shader with this call. This says "Put the values of matWorldViewProj in the variable named WorldViewProj in the shader". That means that you can use this matrix in the shader to transform the vertices. And that's the reason why they didn't call SetTransform.

I'm not expert at shaders, but I doubt it will work that you mix FFP calls with shader calls. You try to pass some values to the shader, but then you set the texture for the fixed pipeline. I'm not shure if DX can differentiate and evaluate wich texture is the 1st and wich the second one. Again, using D3DXEffect is way easier.

You also might want to look into PIX, this is a great (okay, alot of people are gonna hurt me badly for saying this, but I've never experienced a crash in my life and I use it quite frequently) tool that shows you every DX call you made and also shows you what happened there.

Anway, I think you should read more about shaders and how to use them, before mixing up with the FFP

Share this post

Link to post
Share on other sites
well in looking up hoe to setup an D3DXEffect interface.

I believe i have mimicked every call from the sample code, but i still just get a black render

Here is the sample code from the tutorial

void render( void )
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0 );

D3DXMATRIX matTrans;

D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 4.0f );
D3DXMatrixRotationYawPitchRoll( &matRot,
0.0f );
g_matWorld = matRot * matTrans;
g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld );

g_pEffect->SetTechnique( "TwoPassTextureBlend" );

g_pEffect->SetTexture( "texture0", g_pTexture_0 );
g_pEffect->SetTexture( "texture1", g_pTexture_1 );

UINT uPasses;
g_pEffect->Begin( &uPasses, 0 );
g_pEffect->BeginPass( 0 );
g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

so the steps they do.

1)Call Device->Begin Scene
2)Set Matrices using Device->SetTransform
3)Set the Technique
4)Set the Textures with Effect->SetTexture
5)Call Effect->Begin
6)Call Effect->Begin Pass ('pass number')
7)Render using Device->Render code
8)Call Effect->End Pass
9)Call Effect->End
10)Call Device->EndScene
11)Call Device->Present

here is my code, all I get is a black render.

d3ddev->SetTransform(D3DTS_VIEW, &(matView));
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);
d3ddev->SetTransform(D3DTS_WORLD, &(matScale*matRotateX*matRotateY*matRotateZ*matTranslate));
g_pEffect->SetTechnique( "Sun" );
g_pEffect->SetTexture( "base_Tex", texture[16] );
UINT Passes;
g_pEffect->Begin( &Passes, 0 );
g_pEffect->BeginPass( 0 );
g_pEffect->EndPass( );
g_pEffect->End( );
d3ddev->Present(NULL, NULL, NULL, NULL);

here is my .fx file, minimal required, built with rendermonkey using their base "textured" setup and modified a tiny bit

// Textured
// Pass 0
float4x4 matViewProjection : ViewProjection;

struct VS_INPUT
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;


struct VS_OUTPUT
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;


VS_OUTPUT Textured_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )

Output.Position = mul( Input.Position, matViewProjection );
Output.Texcoord = Input.Texcoord;

return( Output );


texture base_Tex;
sampler2D baseMap = sampler_state
Texture = (base_Tex);

struct PS_INPUT
float2 Texcoord : TEXCOORD0;


float4 Textured_Pass_0_Pixel_Shader_ps_main( PS_INPUT Input ) : COLOR0
return tex2D( baseMap, Input.Texcoord );


// Technique Section for Textured
technique Sun
pass Pass_0
VertexShader = compile vs_2_0 Textured_Pass_0_Vertex_Shader_vs_main();
PixelShader = compile ps_2_0 Textured_Pass_0_Pixel_Shader_ps_main();


thanks again guys for putting up with me

Share this post

Link to post
Share on other sites
You're setting D3D's fixed pipe view and projection matrices, which are not at all related to your shader. You'll want to multiply the matrices and set the variable on your FX object.

D3DXMATRIX vp = matView * matProj;
g_pEffect->SetMatrix("matViewProjection", &vp);

Share this post

Link to post
Share on other sites
that is what the sample did, they set the view and projection with the fixed pipeline, then when they set the matrix in the .fx file they did this

float4x4 matViewProjection : ViewProjection;

they never explicitly setmatrix for it so I assume the :ViewProjection copies the value in automatically

however I have found something else peculiar.

I have another sample from code sampler, called Dx9_hlsl_fx_simple
the precompiled .exe runs fine and shows the effect..

but when I compile their code unchanged it complains that 1_x is no longer supported and to change to 2_0 or 3_0. in doing that is spits out a black render with no changes to their code other than the 1_1 compile target

here is their zipfile with the sample

Share this post

Link to post
Share on other sites
Original post by Ebola0001
they never explicitly setmatrix for it so I assume the :ViewProjection copies the value in automatically

Nope. The ViewProjection semantic is there so your app, FXComposer, RenderMonkey, etc, all know what to put in there. No fixed pipe settings are ever automatically copied over, though you may be able to set your variable to the fixed pipe state in the technique or pass block of the shader. The opposite definately works, where you can have an FX variable and set the fixed pipe matrices.

Share this post

Link to post
Share on other sites

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