Ok now I'm absolutely tearing my hair out. If anyone can give me even the smallest piece of advice on this I'll be forever in your debt, this bug is REALLY holding back my project :(
I've abandonned my main project for now and branched off a 'test project' for getting this thing to work.
The full load:
Shader wrapper:
#include <iostream>#include "SYM_Shader.h"using namespace std;namespace SYM{ SYM_SHADERMANAGER ShaderManager; bool SYM_SHADERMANAGER::Init() { //Create Cg context CgContext = cgCreateContext(); //Check for errors if (!CheckCgErrors()) return false; //Set deferred parameters cgSetParameterSettingMode(CgContext, CG_DEFERRED_PARAMETER_SETTING); //Set register states cgGLRegisterStates(CgContext); //Manage texture parameters cgGLSetManageTextureParameters(CgContext, CG_TRUE); return true; } void SYM_SHADERMANAGER::Shutdown() { cgDestroyContext(CgContext); } bool SYM_SHADERMANAGER::CheckCgErrors() { CGerror CgError; const char *ErrorString; ErrorString = cgGetLastErrorString(&CgError); if (CgError != CG_NO_ERROR) { if (CgError == CG_COMPILER_ERROR) { cout << ErrorString << endl; cout << cgGetLastListing(CgContext) << endl; } else cout << ErrorString << endl; return false; } return true; } CGcontext SYM_SHADERMANAGER::GetContext() { return CgContext; } bool SYM_SHADER::Load(string Filename) { //Compile Cg program from file CgEffect = cgCreateEffectFromFile(ShaderManager.GetContext(), Filename.c_str(), 0); //Check for errors if (!ShaderManager.CheckCgErrors()) return false; //Get first technique CgTechnique = cgGetFirstTechnique(CgEffect); if (!ShaderManager.CheckCgErrors()) return false; //Get matrix handles ParamWorldMatrix = cgGetEffectParameterBySemantic(CgEffect, "WORLD"); ParamWorldViewProjMatrix = cgGetEffectParameterBySemantic(CgEffect, "WORLDVIEWPROJECTION"); ParamWorldInvTransMatrix = cgGetEffectParameterBySemantic(CgEffect, "WORLDINVERSETRANSPOSE"); ParamViewMatrix = cgGetEffectParameterBySemantic(CgEffect, "VIEW"); ParamViewInverseMatrix = cgGetEffectParameterBySemantic(CgEffect, "VIEWINVERSE"); ParamWorldViewMatrix = cgGetEffectParameterBySemantic(CgEffect, "WORLDVIEW"); //Get other params ParamEyePos = cgGetEffectParameterBySemantic(CgEffect, "CAMERAPOSITION"); ParamTime = cgGetEffectParameterBySemantic(CgEffect, "Time"); return true; } CGpass SYM_SHADER::GetFirstPass() { //World if(ParamWorldMatrix != 0) cgGLSetStateMatrixParameter(ParamWorldMatrix, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY); //World view projection if(ParamWorldViewProjMatrix != 0) cgGLSetStateMatrixParameter(ParamWorldViewProjMatrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); //World inverse transpose if(ParamWorldInvTransMatrix != 0) cgGLSetStateMatrixParameter(ParamWorldInvTransMatrix, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE_TRANSPOSE); //View if(ParamViewMatrix != 0) cgGLSetStateMatrixParameter(ParamViewMatrix, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); //View inverse if(ParamViewInverseMatrix != 0) cgGLSetStateMatrixParameter(ParamViewInverseMatrix, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_INVERSE); //Worldview if(ParamWorldViewMatrix != 0) cgGLSetStateMatrixParameter(ParamWorldViewMatrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); //CamPos float EyePos[3]; EyePos[0] = 0.0f; EyePos[1] = 0.0f; EyePos[2] = -3.0f; if(ParamEyePos != 0) cgSetParameter3fv(ParamEyePos, EyePos); //Set time //const float CgTime = (float)Engine->GetElapsedTime() / 1000; //cgSetParameter1fv(ParamTime, &CgTime); //Loop through float parameters for(map<CGparameter, float> ::iterator Floats = FloatParams.begin(); Floats != FloatParams.end(); Floats++) { cgSetParameter1fv((*Floats).first, &(*Floats).second); } //Loop through float3 parameters for(map<CGparameter, float*> ::iterator Floats = Float3Params.begin(); Floats != Float3Params.end(); Floats++) { cgSetParameter3fv((*Floats).first, (*Floats).second); } //Loop through texture parameters for(map<CGparameter, SYM_TEXTURE*> ::iterator Textures = TextureParams.begin(); Textures != TextureParams.end(); Textures++) { cgGLSetTextureParameter((*Textures).first, (*Textures).second->Texture); cgSetSamplerState((*Textures).first); } return cgGetFirstPass(CgTechnique);; } CGpass SYM_SHADER::GetNextPass(CGpass CgPass) { return cgGetNextPass(CgPass); } void SYM_SHADER::SetPass(CGpass CgPass) { cgSetPassState(CgPass); } void SYM_SHADER::ResetPass(CGpass CgPass) { cgResetPassState(CgPass); } void SYM_SHADER::Destroy() { cgDestroyEffect(CgEffect); } bool SYM_SHADER::AddFloatParam(string Semantic, float Value) { //Get parameter CGparameter CgParam = cgGetNamedEffectParameter(CgEffect, Semantic.c_str()); if (CgParam == 0) return false; //Add float to map FloatParams[CgParam] = Value; } bool SYM_SHADER::AddFloat3Param(string Semantic, float F1, float F2, float F3) { //Get parameter CGparameter CgParam = cgGetNamedEffectParameter(CgEffect, Semantic.c_str()); if (CgParam == 0) return false; //Add floats to map float Floats[3]; Floats[0] = F1; Floats[1] = F2; Floats[2] = F3; Float3Params[CgParam] = Floats; } bool SYM_SHADER::AddTextureParam(string Semantic, string Filename) { //Get parameter CGparameter CgParam = cgGetNamedEffectParameter(CgEffect, Semantic.c_str()); if (CgParam == 0) { cout << "No parameter: " << Semantic << endl; return false; } //New texture SYM_TEXTURE *Texture = new SYM_TEXTURE; //Load texture if(!Texture->Load(Filename)) { cout << "Error loading texture " << Filename << endl; delete Texture; return false; } //Add parameter and texture to map TextureParams[CgParam] = Texture; return true; }} //Namespace
Init and rendering:
#include <iostream>#include <GL/gl.h>#include <GL/glu.h>#include "Qt_OpenGL.h"using namespace std;Qt_OGLScene::Qt_OGLScene (QWidget* parent) : QGraphicsScene (parent){ if(!SYM::ShaderManager.Init()) QMessageBox::warning(NULL, "Error", "Could not initialise shader manager"); Shader = new SYM::SYM_SHADER; Shader->Load("texture.cgfx"); Shader->AddTextureParam("DiffuseSampler", "rockwall.png");}Qt_OGLScene::~Qt_OGLScene (){ Shader->Destroy(); SYM::ShaderManager.Shutdown();}void Qt_OGLScene::drawForeground( QPainter* painter, const QRectF & rect ){ glEnable(GL_DEPTH_TEST); glViewport(0, 0, 800, 800); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, 800 / 800, 0.1f, 1000.0f); glMatrixMode(GL_MODELVIEW); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0, 0.2, -4.2); glRotatef(35.0f, 1, 0, 0); glRotatef(45.0f, 0, 1, 0); glEnable(GL_TEXTURE_2D); //If a shader has been bound if(Shader) { //Get the first render pass CGpass Pass = Shader->GetFirstPass(); //Loop until all passes have finished while(Pass) { //Set current pass Shader->SetPass(Pass); //Draw geometry drawCube(); //Reset current pass Shader->ResetPass(Pass); //Get the next pass Pass = Shader->GetNextPass(Pass); } } else { cout << "Error: Rendering with no shader loaded\n"; }}void Qt_OGLScene::drawCube(){ glBegin(GL_QUADS); //Front glTexCoord2f(0.0f, 0.0f); glNormal3f( 0.0f, 0.0f, -1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glNormal3f( 0.0f, 0.0f, -1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glNormal3f( 0.0f, 0.0f, -1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glNormal3f( 0.0f, 0.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); //Top glTexCoord2f(0.0f, 1.0f); glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f); //Left glTexCoord2f(0.0f, 0.0f); glNormal3f( -1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glNormal3f( -1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glNormal3f( -1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glNormal3f( -1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd();}
Anything at ALL appreciated, thanks in advance.