Problems with Cg and libgfx matrices

Started by
-1 comments, last by Starfox 15 years, 9 months ago
I'm trying to use libgfx to generate the projection/modelview matrices for my Cg application, but it seems to be introducing a 90-degree rotation about the X axis that I can't understand. There also seems to be a need to swap two elements of the projection matrix generated before passing it to Cg. I verify the value by using glGetDoublev with modelview or projection matrices and then comparing that to the matrix libgfx created. In the source below (complete app), pressing space will switch between fixed function VP and shaders, and the update_matrices function reads the GL values. Any idea why this is happening? To build, you may need libgfx_d.lib, which I uploaded here: http://www.mganin.com/libgfx_d.lib

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <cassert>

#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/wglew.h>
#include <GL/glut.h>
#include <gl/GLU.h>

#include <Cg/cg.h>
#include <Cg/cgGL.h>

#include <gfx/mat4.h>

#pragma comment(lib, "glew32s.lib")
#pragma comment(lib, "cg.lib")
#pragma comment(lib, "cggl.lib")

#ifdef _DEBUG
#pragma comment(lib, "libgfx_d")
#else
#pragma comment(lib, "libgfx")
#endif

using namespace std;
using namespace gfx;

void check_cg_error(CGcontext TargetContext, const char* const Situation = "Unknown situation")
{
	CGerror Error;
	const char* const ErrorString = cgGetLastErrorString(&Error);

	if (Error != CG_NO_ERROR)
	{
		cerr << Situation << " : " << ErrorString << " ." << endl;
		if (Error == CG_COMPILER_ERROR)
		{
			cerr << "\t" << cgGetLastListing(TargetContext) << endl;
		}
		exit(1);
	}
}

CGcontext CgContext;
CGprofile CgVertexProfile;
CGprofile CgFragmentProfile;
CGprogram CgVertexProgram;
CGprogram CgFragmentProgram;

Mat4 ProjectionMatrix;
Mat4 ViewMatrix;
Mat4 WorldMatrix;
Mat4 WorldViewMatrix;
Mat4 WorldViewProjectionMatrix;

const char* const VertexShaderCode =
"float4 main(float4 Position : POSITION,\n"
"\t\t\tuniform float4x4 WorldViewProjectionMatrix) : HPOS\n"
"{\n"
"\treturn mul(WorldViewProjectionMatrix, Position);\n"
"}";

const char* const FragmentShaderCode =
"float4 main() : COLOR\n"
"{\n"
"\treturn float4(0, 0, 1, 1);\n"
"}";

const int ScreenWidth = 1280;
const int ScreenHeight = 720;

void update_matrices();

void initialize_cg()
{
	CgContext = cgCreateContext();
	check_cg_error(CgContext, "Creating context");
	cgGLSetDebugMode( CG_FALSE );
	cgGLSetManageTextureParameters(CgContext, true);
	cgSetParameterSettingMode(CgContext, CG_DEFERRED_PARAMETER_SETTING);
	CgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
	cgGLSetOptimalOptions(CgVertexProfile);
	check_cg_error(CgContext, "Selecting vertex profile");
	CgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
	cgGLSetOptimalOptions(CgFragmentProfile);
	check_cg_error(CgContext, "Selecting fragment profile");
	cgGLEnableProfile(CgVertexProfile);
	check_cg_error(CgContext, "Enabling vertex profile");
	cgGLEnableProfile(CgFragmentProfile);
	check_cg_error(CgContext, "Enabling fragment profile");
	//
	CgVertexProgram = cgCreateProgram(CgContext, CG_SOURCE, VertexShaderCode, CgVertexProfile, "main", NULL);
	check_cg_error(CgContext, "Creating vertex program");
	cgGLLoadProgram(CgVertexProgram);
	check_cg_error(CgContext, "Loading vertex program");
	CgFragmentProgram = cgCreateProgram(CgContext, CG_SOURCE, FragmentShaderCode, CgFragmentProfile, "main", NULL);
	check_cg_error(CgContext, "Creating fragment program");
	cgGLLoadProgram(CgFragmentProgram);
	check_cg_error(CgContext, "Loading fragment program");
	//
	ProjectionMatrix = perspective_matrix(90.0, 1280.0/720.0, 1.0, 1000.0);
	double* PD = ProjectionMatrix;
	swap(PD[11], PD[14]);
	double M[16];
	glGetDoublev(GL_PROJECTION_MATRIX, M);
	ViewMatrix = Mat4::I();
	WorldMatrix = Mat4::I();
	update_matrices();
	//
}

void initialize_gl()
{
	glewInit();
	//Disable VSync (Allowing frame rate to exceed monitor refresh rate.
	wglSwapIntervalEXT(0);
	glClearColor(0, 1, 0, 1);
	glMatrixMode(GL_PROJECTION);
	gluPerspective(90.0, 1280.0/720.0, 1.0, 1000.0);
	glMatrixMode(GL_MODELVIEW);
	//
}

void update_matrices()
{
	WorldViewMatrix = ViewMatrix * WorldMatrix;
	WorldViewMatrix = WorldMatrix;
	WorldViewProjectionMatrix = ProjectionMatrix * WorldViewMatrix;
	//
	double* PD = ProjectionMatrix;
	//swap(PD[11], PD[14]);
	double P[16];
	glGetDoublev(GL_PROJECTION_MATRIX, P);
	double M[16];
	glGetDoublev(GL_MODELVIEW_MATRIX, M);
	//
	CGparameter WorldViewProjectionMatrixParameter = cgGetNamedParameter(CgVertexProgram, "WorldViewProjectionMatrix");
	check_cg_error(CgContext, "Getting WorldViewProjectionMatrix parameter");
	cgSetMatrixParameterdr(WorldViewProjectionMatrixParameter, WorldViewProjectionMatrix);
	check_cg_error(CgContext, "Setting WorldViewProjectionMatrixparameter value");
}

bool X = true;

void render_scene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	WorldMatrix = Mat4::I(); glLoadIdentity();
	WorldMatrix = WorldMatrix * translation_matrix(Vec3(0, 0, -15)); glTranslatef(0, 0, -15);
	update_matrices();
	glColor3f(1, 0, 0);
	cgGLBindProgram(CgVertexProgram);
	cgGLBindProgram(CgFragmentProgram);
	if(X)
	{
		cgGLEnableProfile(CgVertexProfile);
	}
	else
	{
		cgGLDisableProfile(CgVertexProfile);
	}
	glutWireTeapot(1.0);
	glutSwapBuffers();
}

void idle()
{
	glutPostRedisplay();
}

void key(unsigned char k, int, int)
{
	if(k == ' ') X = !X;
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(1280,720);
	glutCreateWindow("GPGPU Program #1");
	//
	initialize_gl();
	initialize_cg();
	////////////////

	glutDisplayFunc(render_scene);
	glutKeyboardFunc(key);
	glutIdleFunc(idle);
	cout << "Vertex shader listing:\n\n";
	cout << VertexShaderCode;
	cout << "\n\n";
	cout << "Fragment shader listing:\n\n";
	cout << FragmentShaderCode;
	cout << "\n\n";
	glutMainLoop();
}



UPDATE: Binary available at http://www.mganin.com/cg_libgfx.exe
Holy crap I started a blog - http://unobvious.typepad.com/

This topic is closed to new replies.

Advertisement