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.