Sign in to follow this  
Xrystal

[MDX Solved] Problem Using Shaders

Recommended Posts

edit: Just realised the title may have been misleading. Using the various books I have around and the internet I thought I had the basic shader written. All it did was set the world position of a single triangle at first but no luck. I then thought maybe I needed to set the color or texture so added a color out value. My DXPrimitive Class handles all primitive drawing so I added the effect file access coding to that class. Class Member Variables
String* m_effectFile;
D3D::Effect* m_effect;
D3D::EffectHandle* m_effectHandle;
D3D::VertexDeclaration* m_verDec;
D3D::VertexElement m_elements[];
This is the DXPrimitive Constructor Code
	UsingBuffers = false;
	m_device = device;
	m_vertexCount = vertexCount;
	m_indexCount = indexCount;
	Console::WriteLine(String::Format("Vertex Format = {1} - Index Count = {0}",__box(m_indexCount),__box(vf)));
	m_vformat = vf;
	if (indexCount > 0) m_indices = new Int32[indexCount];
	if (vertexCount > 0)
	{
		switch (vf)
		{
			case CustomVertex::PositionOnly::Format:
			{
				m_poverts = new CustomVertex::PositionOnly[m_vertexCount];
				m_elements = new D3D::VertexElement[2];
				m_elements[0] = D3D::VertexElement(0,00,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Position, 0);
				m_elements[1] = VertexElement::VertexDeclarationEnd;
				break;
			}
			case CustomVertex::PositionNormalColored::Format:
			{
				m_pncverts = new CustomVertex::PositionNormalColored[m_vertexCount];
				m_elements = new D3D::VertexElement[4];
				m_elements[0] = D3D::VertexElement(0,00,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Position, 0);
				m_elements[1] = D3D::VertexElement(0,12,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Normal, 0);
				m_elements[2] = D3D::VertexElement(0,24,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Color, 0);
				m_elements[3] = VertexElement::VertexDeclarationEnd;
				break;
			}
			case CustomVertex::PositionNormalTextured::Format:
			{
				m_pntverts = new CustomVertex::PositionNormalTextured[m_vertexCount];
				m_elements = new D3D::VertexElement[4];
				m_elements[0] = D3D::VertexElement(0,00,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Position, 0);
				m_elements[1] = D3D::VertexElement(0,12,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Normal, 0);
				m_elements[2] = D3D::VertexElement(0,24,	DeclarationType::Float3, DeclarationMethod::Default, DeclarationUsage::Color, 0);
				m_elements[3] = VertexElement::VertexDeclarationEnd;
			break;
			}
		};
		m_verDec = new D3D::VertexDeclaration(m_device, m_elements);

	}

	// Set World Object Information
	m_device = device;
	m_WorldPosition = Vector3();
	m_WorldSpace = new DXWorld(device);



This is the initial Draw Routine for the Primitive Based object
bool DXPrimitive::Draw(PrimitiveType primitiveType)
{
	if (!m_device) 
	{
		Console::WriteLine("No Device to use");
		return false;
	}

	bool DrawPass = false;

	if (m_effectFile != "")
	{
		m_effect = Effect::FromFile(m_device,m_effectFile,NULL,ShaderFlags::None,NULL);
		m_effectHandle = EffectHandle::FromString("TShader");
		m_effect->Technique = m_effectHandle;
		int passes = m_effect->Begin(FX::None);
		for (int i = 0; i < passes; i++)
		{
			// Set a shader constant
			m_effectHandle = EffectHandle::FromString("matWorldViewProj");

			// Set state for the current effect pass.
			m_effect->SetValue(m_effectHandle, m_WorldSpace->Transform());
			m_effect->BeginPass(i);
	      
			// Render some primitives.
			//m_dxBase->Device->SetTexture(0,m_dxTexture->Texture);
			//UpdateWorld();
			DrawPass = Draw(primitiveType,0,m_vertexCount);
			// End the effect pass
			m_effect->EndPass();
			if (!DrawPass) break;
		}
		m_effect->End();
	}
	else
	{
		DrawPass = Draw(primitiveType,0,m_vertexCount);
	}
    return DrawPass;
}



The Second Stage Draw routine handles the actual call to which DrawPrimitive function to use but before it does anything it does this piece of code:
	if (m_effectFile == "") 
	{
		m_device->VertexFormat = m_vformat;
	}
	else
	{
		m_device->VertexDeclaration = m_verDec;
	}



At Object Creation I do this:
	m_Player = new DXPrimitive(m_dxBase->Device,3,3,CustomVertex::PositionOnly::Format);
	m_Player->SetTriangle(0,10.0f);
	m_Player->CreateVertexBuffer();
	m_Player->CreateIndexBuffer();
	m_Player->WorldCoords = Vector3(0.0f,0.0f,0.0f);
	m_Player->EffectFile = "Ambient.fx";



If I set EffectFile to "" it draws fine as expected and in front of the camera which is 50 pixels behind the player object. The SetTriangle routine simple sets up the vertices, colors etc as required. In this example only the postion is set up as per the example in Tom Millers book in the chapter on Shaders. This is the effects file I am using. I altered the initial coding to match what Tom Miller was using in his book.
// -------------------------------------------------------------
// Ambient Lighting
// 
// Copyright (c) 2003 - 2004 Wolfgang F. Engel (wolf@direct3d.net)
// All rights reserved.
// -------------------------------------------------------------

// -------------------------------------------------------------
// variables that are provided by the application
// -------------------------------------------------------------
float4x4 matWorldViewProj : WORLDVIEWPROJECTION;	


// -------------------------------------------------------------
// vertex shader output channels
// -------------------------------------------------------------
struct VS_OUTPUT
{
   float4 Pos: POSITION;
   float4 Diffuse: COLOR;
};

struct VS_INPUT
{
   float4 Pos: POSITION;
};

// -------------------------------------------------------------
// vertex shader function (input channels)
// -------------------------------------------------------------

VS_OUTPUT VS( VS_INPUT In)
{
   VS_OUTPUT Out = (VS_OUTPUT) 0; 
   Out.Pos = mul(In.Pos, matWorldViewProj); // transform Position
   Out.Diffuse.ra = 1.0f;
   Out.Diffuse.gb = 0.0f; 
   return Out;
}

// -------------------------------------------------------------
// Pixel Shader (input channels):output channel
// -------------------------------------------------------------
//float4 PS() : COLOR
//{
//  float Aintensity = 0.8f;
//  float4 Acolor =  float4(1.0f, 0.075f, 0.075f, 1.0f);
//  return Aintensity * Acolor;
//}

// -------------------------------------------------------------
// Name technique | pass | how to compile 
// -------------------------------------------------------------
technique TShader
{
    pass P0
    {
        // compiler directives
        VertexShader = compile vs_1_1 VS();
        PixelShader  = NULL;
    }
}



Can someone see anything wrong with these additions? It's clearly not positioning properly even though it is being set to the value that is usually used when Updating the World position in the program. Thanks in advance. [Edited by - Xrystal on October 11, 2006 2:15:04 AM]

Share this post


Link to post
Share on other sites
Okay managed to get the coloring part working right :D

But for some reason I cannot get the vertexshader to reposition the object in the same way the main program does. Unless there is something else I have to do to get it to return the value back.

This is the effect file taken from chapter 4 of Engels book. All I have changed is the // in the VertexShader line as that doesn't work for some reason with my code:


// -------------------------------------------------------------
// Ambient Lighting
//
// Copyright (c) 2003 - 2004 Wolfgang F. Engel (wolf@direct3d.net)
// All rights reserved.
// -------------------------------------------------------------

// -------------------------------------------------------------
// variables that are provided by the application
// -------------------------------------------------------------
float4x4 matWorldViewProj;


// -------------------------------------------------------------
// vertex shader output channels
// -------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos: POSITION;
};

// -------------------------------------------------------------
// vertex shader function (input channels)
// -------------------------------------------------------------

VS_OUTPUT VS( float4 Pos: POSITION )
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
Out.Pos = mul(Pos, matWorldViewProj); // transform Position
return Out;
}

// -------------------------------------------------------------
// Pixel Shader (input channels):output channel
// -------------------------------------------------------------
float4 PS() : COLOR
{
float Aintensity = 0.8f;
float4 Acolor = float4(1.0f, 0.075f, 0.075f, 1.0f);
return Aintensity * Acolor;
}

// -------------------------------------------------------------
// Name technique | pass | how to compile
// -------------------------------------------------------------
technique TShader
{
pass P0
{
// compiler directives
VertexShader = NULL;//compile vs_1_1 VS();
PixelShader = compile ps_1_1 PS();
}
}




I would have thought just commenting out this line:

m_Player->UpdateWorld();


which contains this code:

if (!m_WorldSpace->Static) m_device->Transform->World = m_WorldSpace->Transform();


And replacing it with the updateworld code effect file would be enough.

And of course because it isn't positioning properly you cannot see if its working. Fortunately a little tweak and if I set up a colorchange only file that runs just the pixel shader it works fine :D

Can anyone think of anything that might cause this kinda of problem? Any assistance appreciated.

Share this post


Link to post
Share on other sites
I take it no-one has come across this problem at all ? It's pretty much got me stymied on moving some of my code to shader while its in its early stages. Well here's hoping I manage to get it working this weekend or someone reads and recognises the problem I'm getting.

Share this post


Link to post
Share on other sites
Finally got a reply at the microsoft forums on this and helped me locate the cause. I was only passing the object being drawns world position and not the view or projection matrices. Once I combined all three and passed the new value it all worked fine.

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