vertex and pixel shader question

Started by
6 comments, last by Namethatnobodyelsetook 15 years, 8 months ago
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?
Quando Omni Flunkus MoritatiWhen All Else Fails, Play Dead!
Advertisement
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.

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

ok, now i can't get anything to render, this is frustrating.


ANYWAY.

here is the rendering code from the tutorial (link)
            app.getDevice()->BeginScene();            // 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()->SetVertexDeclaration(vertexDecl);            app.getDevice()->SetVertexShader(vertexShader);            app.getDevice()->SetPixelShader(pixelShader);            app.getDevice()->SetStreamSource(0, quadVB, 0, sizeof(D3DVERTEX));            app.getDevice()->SetTexture(0, quadTexture);            app.getDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);            app.getDevice()->EndScene();			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->SetViewport(&ViewportInfo);     d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 212, 208, 200), 1.0f, 0);     d3ddev->BeginScene();    D3DXQuaternionRotationMatrix(&matViewQuatIn,&matView);                          //Step 1    D3DXQuaternionRotationYawPitchRoll(&matViewQuat,CamYaw,CamPitch,CamRoll);       //Step 2    D3DXMatrixRotationQuaternion(&matViewChange,&matViewQuat);    D3DXQuaternionMultiply(&matViewQuatOut,&matViewQuatIn,&matViewQuat);            //Step 3    D3DXQuaternionNormalize(&matViewQuatOut, &matViewQuatOut);                      //Step 4    D3DXMatrixRotationQuaternion(&matViewOut,&matViewQuatOut);                      //Step 5    	D3DXMatrixTranslation(&matView,                                                 //Step 6                          CameraPosition.x,                          CameraPosition.y,                          CameraPosition.z);    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    D3DXMatrixPerspectiveFovLH(&matProjection,                               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;	GalaxyBlend=D3DCOLOR_ARGB(Blend,Blend,Blend,Blend);    d3ddev->SetRenderState(D3DRS_BLENDFACTOR, GalaxyBlend);	d3ddev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_BLENDFACTOR);    d3ddev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVBLENDFACTOR);        ViewportInfo.Width = 1019;	ViewportInfo.Height = 768;	ViewportInfo.X = 256;	ViewportInfo.Y = 5;    d3ddev->SetViewport(&ViewportInfo);    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->SetVertexDeclaration(vertexDecl);    d3ddev->SetVertexShader(vertexShader);    d3ddev->SetPixelShader(pixelShader);    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
Quando Omni Flunkus MoritatiWhen All Else Fails, Play Dead!
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
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 );	g_pd3dDevice->BeginScene();	D3DXMATRIX matTrans;	D3DXMATRIX matRot;    	D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 4.0f );	D3DXMatrixRotationYawPitchRoll( &matRot, 		                            D3DXToRadian(g_fSpinX), 		                            D3DXToRadian(g_fSpinY), 		                            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_pEffect->EndPass(); 	g_pEffect->End();	g_pd3dDevice->EndScene();    	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->BeginScene();		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 );			   Galaxy->DrawSubset(0);			g_pEffect->EndPass( );		g_pEffect->End( );	d3ddev->EndScene();    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 ){   VS_OUTPUT Output;   Output.Position = mul( Input.Position, matViewProjection );   Output.Texcoord = Input.Texcoord;   return( Output );   }texture base_Tex;sampler2D baseMap = sampler_state{   Texture = (base_Tex);   ADDRESSU = WRAP;   ADDRESSV = WRAP;   MINFILTER = LINEAR;   MAGFILTER = LINEAR;};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
Quando Omni Flunkus MoritatiWhen All Else Fails, Play Dead!
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);
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
http://www.woodrell.com/joe/dx9_hlsl_fx_simple.zip
Quando Omni Flunkus MoritatiWhen All Else Fails, Play Dead!
Quote: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.

This topic is closed to new replies.

Advertisement