Sign in to follow this  
idloco

CG Shaders and DirectX 9 Vertex Declaration

Recommended Posts

idloco    156
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
idloco    156
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
Armadon    1091
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