Sign in to follow this  
idloco

CG Shaders and DirectX 9 Vertex Declaration

Recommended Posts

i got this problem that has been drive me nuts! im trying to implement multitexture on my terrain using cg, but i can't make the cg to validate my vertex definition. here is the definition.
#define D3DFVF_CUSTOMVERTEX	( D3DFVF_XYZ | D3DFVF_NORMAL |D3DFVF_TEX1 | D3DFVF_TEX2 )
typedef struct SVertex
{
	D3DXVECTOR3 v; // Actual Vertex
	D3DXVECTOR3 n; // Normal Vector
	FLOAT	tu1, tv1; // Texture Coordinates
	FLOAT	tu2, tv2; // Texture Coordinates
} D3DVERTEX;

const D3DVERTEXELEMENT9 declaration[] = 
{
	{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
	{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL  , 0 },
	{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 0 },
	{ 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD  , 1 },
	D3DDECL_END()
};

Here is where the shaders are initialized
	TheLog.log_graphics_normal("Start Loading Terrain Shaders");

	g_CGcontext = NULL;
	// Create the context...
	g_CGcontext = cgCreateContext();

	if (!g_CGcontext)
	{
		int error = cgGetError();
		char* errorString = (char*)cgGetErrorString((CGerror)error);
		TheLog.log_graphics_critical("Error Loading CG program --------------------------------");
		TheLog.log_graphics_critical(errorString);
	}

	//
	// Since we're using Cg's expanded interface, we'll need to pass the 
	// Direct3D device to Cg.
	//

	cgD3D9SetDevice( TheGraphics.GetDevice() );

	// Determine the best vertex profile to use...
	CGprofile vertexProfile = cgD3D9GetLatestPixelProfile();

	if (vertexProfile == CG_PROFILE_UNKNOWN)
	{
		TheLog.log_graphics_critical("Error Loading CG Profile --------------------------------");
	}
	// Grab the optimal options for each profile...
	const char **vertexOptions = cgD3D9GetOptimalOptions( vertexProfile );

	//
	// Create the vertex shader...
	//

	g_CGprogram = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "Shaders/terrain_multitexture.cg",
											vertexProfile, "main",	vertexOptions );

	int error = cgGetError();
	if (error)
	{
		char* errorString = (char*)cgGetErrorString((CGerror)error);
		TheLog.log_graphics_critical("Error Loading CG program --------------------------------");
		TheLog.log_graphics_critical(errorString);
	}

	if (D3DERR_INVALIDCALL == TheGraphics.GetDevice()->CreateVertexDeclaration( declaration, &g_pVertexDeclaration ))
	{
		TheLog.log_graphics_critical("Error...D3D Invalid Vertex Declarations");
	}

//-----------------------------------------------------------------------------
// This line give's me error
//-----------------------------------------------------------------------------
	if (cgD3D9ValidateVertexDeclaration( g_CGprogram, declaration ) == CG_FALSE)
	{
		TheLog.log_graphics_critical("Error... CG Invalid Vertex Declarations");
	}


	
	//
	// Load the program using Cg's expanded interface...
	//
	// When the second parameter is set to TRUE, shadowing is enabled. This
	// will allow parameters like our g_CGparam_constColor to be set once and
	// reused with out constantly setting it over and over again.
	//

	cgD3D9LoadProgram( g_CGprogram, TRUE, 0 );

	//
	// Bind some parameters by name so we can set them later...
	//

	g_CGparam_texture0    = cgGetNamedParameter( g_CGprogram, "texture0" );
	g_CGparam_texture1	  = cgGetNamedParameter( g_CGprogram, "texture1" );
	g_CGparam_texture2    = cgGetNamedParameter( g_CGprogram, "texture2" );
	g_CGparam_blendMap    = cgGetNamedParameter( g_CGprogram, "blendMap" );

	//
	// Set uniform parameters that don't change. They only have to be set
	// once when parameter shadowing is enabled during the call to 
	// cgD3D9LoadProgram.
	//

	int iError = 0;


	iError = cgD3D9SetUniform( g_CGparam_texture0, terrainTexture[0]->GetTextureHandle() );
	if (iError ) 
	{
		assert("Bad input");
	}
	cgD3D9SetUniform( g_CGparam_texture0, terrainTexture[1]->GetTextureHandle() );
	cgD3D9SetUniform( g_CGparam_texture0, terrainTexture[2]->GetTextureHandle() );
	cgD3D9SetUniform( g_CGparam_texture0, terrainTexture[3]->GetTextureHandle() );


	TheLog.log_graphics_normal("Finished Loading Terrain Shaders");
	return S_OK;

And here is the shader
struct InputVS
{
	float3 position		: POSITION;
	float3 normal		: COLOR;
	float2 texcoord0	: TEXCOORD0;
	float2 texcoord1	: TEXCOORD1;
};
struct OutputPS
{
	float4	position	:POSITION;
	float	color		: COLOR;
};
//-----------------------------------------------------------------------------
// Terrain Texture Blending Shader
//-----------------------------------------------------------------------------
void main(
		InputVS input,
		out float4 color : COLOR,
		uniform sampler2D texture0,
		uniform sampler2D texture1,
		uniform sampler2D texture2,
		uniform sampler2D blendMap)
{

	// Layer maps are tiled
    float4 c0 = tex2D(texture0, input.texcoord0);
    float4 c1 = tex2D(texture1, input.texcoord0);
    float4 c2 = tex2D(texture2, input.texcoord0);
    
    // Blendmap is not tiled.
    float4 B = tex2D(blendMap, input.texcoord1);

	// Find the inverse of all the blend weights so that we can
	// scale the total color to the range [0, 1].
    float totalInverse = 1.0f / (B.r + B.g + B.b);
    
    c0 *= B.r * totalInverse;
    c1 *= B.g * totalInverse;
    c2 *= B.b * totalInverse;
    
    color = (c0 + c1 + c2) * 1.0;

}

Sorry for the high amount of code.

Share this post


Link to post
Share on other sites
actually the base of the code is based on codesampler.com samples.
but when i change the things to work on my engine, all the things fail.

Share this post


Link to post
Share on other sites
Hi Idloco,
How are you doing?

[What could be wrong?]
I can't see anything really wrong with your VertexDeclaration,
What you might want to try if you haven't already is a small loaded mesh and a simple diffuse shader.
Then add a vertex declaration.
Normally with a vertex declaration, you load a mesh and if the mesh doesn't have the normals, you add it to the vertex declaration and clone the mesh with that vertex decl.

[Conclusion]
I do tend to do this with most problems I encounter. See if your validate vertex declaration works with something simple like a sphere mesh.. etc..

I hope this helps a bit.
Take care.

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