Hi all,
My first CgFX application is giving me trouble. I've managed to get some very simple shaders working but am having a lot of trouble passing textures to it. I'm trying to make use of existing libs (namely NVidia's nv::Image for loading the image data from file). The shader works fine in FX Composer (2.5b).
The code is clean enough and should be logging all errors (using 'cgGetLastErrorString()' and 'glGetError()' etc). Shading appears is ok when I don't use the texture. But as soon as the texture is used, the CgFX shader compiles without warning and runs without error... but the test sphere I'm trying to draw is a black circle (which my arcball manipulator spins without any trouble).
Can anyone suggest why when I use the following code all I see is a black circle?
I've been chipping away at this for days (i hate to admit though it's becoming weeks...). can someone please put me out of my misery... even if it looks ok... any opinions/suggestions much a appreciated.
// simpleTextured.cgfx
// This is C2E1v_green from "The Cg Tutorial" (Addison-Wesley, ISBN
// 0321194969) by Randima Fernando and Mark J. Kilgard. See page 38.
float4x4 modelViewProj : WorldViewProjection < string UIWidget="None"; >;
float3 globalAmbient : Ambient = { 0.1, 0.1, 0.1 };
float3 lightColor : Specular <
string UIName = "Lamp 0";
string Object = "Pointlight0";
string UIWidget = "Color";
> = {1.0f,1.0f,1.0f};
float3 lightPosition : Position <
string Object = "PointLight0";
string UIName = "Lamp 0 Position";
string Space = "World";
> = {0.81,-3.65,5};
float3 eyePosition : Position = { 0, 0, 13 };
float3 Ke : Emissive < string UIWidget = "Color"; > = {0.0, 0.0, 0.0};
float3 Ka : Ambient = {0.0, 0.0, 0.0};
float3 Kd : Diffuse = {0.5, 0.0, 0.0};
float3 Ks < string UIWidget = "Color"; > = {0.7, 0.6, 0.6};
float shininess <
string UIWidget = "slider";
float UIMin = 0.0;
float UIMax = 100.0;
float UIStep = 1.0;
string UIName = "Specular";
> = 32.0;
//////// COLOR & TEXTURE /////////////////////
texture ColorTexture <
string ResourceName = "default_color.dds";
string UIName = "Diffuse Texture";
string ResourceType = "2D";
>;
sampler2D ColorSampler = sampler_state {
Texture = <ColorTexture>;
MinFilter = LinearMipMapLinear;
MagFilter = Linear;
WrapS = Repeat;
WrapT = Repeat;
};
// This is C5E2v_fragmentLighting from "The Cg Tutorial" (Addison-Wesley, ISBN
// 0321194969) by Randima Fernando and Mark J. Kilgard. See page 124.
void main(float4 position : POSITION,
float3 normal : NORMAL,
float2 uv : TEXCOORD0,
out float4 oPosition : POSITION,
out float2 oUV : TEXCOORD0,
out float3 objectPos : TEXCOORD1,
out float3 oNormal : TEXCOORD2)
{
oPosition = mul(modelViewProj, position);
objectPos = position.xyz;
oNormal = normal;
oUV = uv;
}
// This is C5E3f_basicLight from "The Cg Tutorial" (Addison-Wesley, ISBN
// 0321194969) by Randima Fernando and Mark J. Kilgard. See page 125.
void psLight(float4 position : TEXCOORD0,
float2 uv : TEXCOORD1,
float3 normal : TEXCOORD2,
out float4 color : COLOR)
{
float3 P = position.xyz;
float3 N = normalize(normal);
// Compute emissive term
float3 emissive = Ke;
// Compute ambient term
float3 ambient = Ka * globalAmbient;
// Compute the diffuse term
float3 L = normalize(lightPosition - P);
//float diffuseLight = max(dot(L, N), 0);
float3 diffuseLight = tex2D(ColorSampler, uv) + max(dot(L, N), 0);
float3 diffuse = Kd * lightColor * diffuseLight;
// Compute the specular term
float3 V = normalize(eyePosition - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(H, N), 0), shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = Ks * lightColor * specularLight;
color.xyz = emissive + ambient + diffuse + specular;
color.w = 1;
}
technique NewTechnique <
string Script = "Pass=p0;";
> {
pass p0 <
string Script = "Draw=geometry;";
> {
VertexProgram = compile vp40 main();
DepthTestEnable = true;
DepthMask = true;
CullFaceEnable = false;
BlendEnable = false;
DepthFunc = LEqual;
FragmentProgram = compile fp40 psLight();
}
}
// Initialize() CPP
cgContext = cgCreateContext();
LOG_CG("cgCreateContext", cgContext);
cgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
cgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(cgVertexProfile);
cgGLSetOptimalOptions(cgFragmentProfile);
LOG_CG("cgGLSetOptimalOptions", cgContext);
LOG("Cg Vertex Profile: " << cgGetProfileString(cgVertexProfile));
LOG("Cg Fragment Profile: " << cgGetProfileString(cgFragmentProfile));
PathResolver pathResolver("");
//const std::string cgFXFile = "phong.cgfx";
//const std::string cgFXFile = "green.cg";
//const std::string cgFXFile = "vertlight.cgfx";
const std::string cgFXFile = "blinn.cgfx";
std::string resolvedCgFXFile = "";
if (pathResolver.getFilePath(cgFXFile, resolvedCgFXFile))
{
cgProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, resolvedCgFXFile.c_str(), cgVertexProfile, "main", 0);
LOG_CG("cgCreateProgramFromFile(" << resolvedCgFXFile << ")", cgContext);
}
else
LOG_ERROR("File not found: " << cgFXFile);
const std::string modelFile = "cow.obj";
std::string resolvedModelFile = "";
if (pathResolver.getFilePath(modelFile, resolvedModelFile))
model = Utils::LoadModel(resolvedModelFile.c_str(), &modelBBMin, &modelBBMax);
else
LOG_ERROR("File not found: " << modelFile);
cgGLLoadProgram(cgProgram);
LOG_CG("cgGLLoadProgram", cgContext);
if(cgProgram == 0)
{
LOG_ERROR("Invalid Cg program. This program will now exit...");
exit(1);
}
cgGLRegisterStates(cgContext);
LOG_CG("cgGLRegisterStates", cgContext);
cgGLSetManageTextureParameters(cgContext, CG_TRUE);
LOG_CG("cgGLSetManageTextureParameters", cgContext);
cgEffect = cgCreateEffectFromFile(cgContext, resolvedCgFXFile.c_str(), NULL);
LOG_CG("cgCreateEffectFromFile(" << resolvedCgFXFile << ")", cgContext);
cgTechnique = cgGetFirstTechnique(cgEffect);
while (cgTechnique && cgValidateTechnique(cgTechnique) == CG_FALSE)
{
LOG_ERROR("Technique '" << cgGetTechniqueName(cgTechnique) << "' did not validate");
cgTechnique = cgGetNextTechnique(cgTechnique);
}
LOG_CG("CG Techniques initialise", cgContext);
if (cgTechnique) {
LOG("Using Cg technique '" << cgGetTechniqueName(cgTechnique) << "' from '" << cgFXFile << "'.");
} else {
LOG_ERROR("Valid Cg Technique not found");
}
// Load the texture (if needed)
CGparameter param = cgGetNamedParameter(cgProgram, "ColorSampler");
LOG_CG("cgGetNamedParameter", cgContext);
if (param != 0) {
cgGLEnableTextureParameter(param);
image = new nv::Image();
const std::string texFile = "Default_color.dds";
std::string resolvedTexFile = "";
if (!(pathResolver.getFilePath(texFile, resolvedTexFile) &&
image->loadImageFromFile(resolvedTexFile.c_str())))
LOG_ERROR("File not found: " << texFile);
LOG("Texture loaded (" << resolvedTexFile << ")");
GLuint texName;
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
glTexImage2D( GL_TEXTURE_2D, 0, image->getInternalFormat(), image->getWidth(), image->getHeight(), 0, image->getFormat(), image->getType(), image->getLevel(0));
LOG_OGL("glTexImage2D()");
cgGLSetTextureParameter(param, texName);
LOG_CG("cgGLSetTextureParameter(param, texName)", cgContext);
}
else
LOG("WARNING: No texture parameter found. Expecting 'sampler2D ColorSampler'.");
cgGLEnableProfile(cgVertexProfile);
cgGLEnableProfile(cgFragmentProfile);
// Display() in CPP
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
manipulator.applyTransform();
CGparameter param = 0;
param = cgGetEffectParameterBySemantic(cgEffect, "WorldViewProjection");
if (param != 0)
cgGLSetStateMatrixParameter(param, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY);
LOG_CG("cgGLSetStateMatrixParameter(WorldViewProjection)", cgContext);
cgGLBindProgram(cgProgram);
CGpass pass = cgGetFirstPass(cgTechnique);
while (pass) {
cgSetPassState(pass);
//DrawModel(model, modelBBMin, modelBBMax);
glutSolidSphere(0.5, 8, 8);
cgResetPassState(pass);
pass = cgGetNextPass(pass);
}
glutSwapBuffers();
[Edited by - axon on June 16, 2008 12:40:29 AM]