Para comenzar creamos un widget que contenga opengl.
El header es:
#ifndef QGLWIDGET_H_INCLUDED
#define QGLWIDGET_H_INCLUDED
#include <QtOpenGL/QGLWidget>
#include <Cg/cg.h>
#include <Cg/cgGL.h>
class Glwidget : public QGLWidget //hereda de QGLwidget
{
public:
Glwidget(QWidget *parent=0);
~Glwidget();
protected:
//funciones a sobrescribir de opengl
void initializeGL();
void paintGL();
void resizeGL(int,int);
private:
//Miembros de CG
CGcontext contexto;
CGprofile perfil; //para crear el perfil dependiendo de la api y la gpu
CGparameter modelViewMatrix; //parámetro para ingresar
CGprogram programa;
};
Ahora el archivo cpp. qglwidget.cpp es:
#include <QtGui>
#include "qglwidget.h"
#include <iostream>
//Estos includes siguientes son necesarios para utilizar code-completion de codeblocks sin problemas
#include <GL/gl.h>
#include <GL/glu.h>
//función para el manejador de errores
void MyErrorHandler(CGcontext contexto, CGerror error, void *data) {
CGcontext alf=cgCreateContext();
if(contexto!=NULL){//para arreglar un problema de salida del programa
alf=contexto;}
const char *lastListing = cgGetLastListing(alf);
qDebug() << (lastListing == 0 ? "No error." : lastListing);
}
Glwidget::Glwidget(QWidget *parent){};
Glwidget::~Glwidget(){
cgDestroyProgram(programa);
cgDestroyContext(contexto);
cgDestroyParameter(modelViewMatrix);
}
void Glwidget::initializeGL(){
contexto=cgCreateContext();
//Creamos un manejador de errores con la función MyErrorHandler es muy útil utilizarlo para
// encontrar los errores facilmente en el archivo CG.
cgSetErrorHandler(MyErrorHandler,NULL);
//Se crea el perfil a partir de la ultima versión soportada por nuestra GPU.
//Este es simplemente un Vertex shader, para hacer shaders mas realistas es necesario
//utilizar también pixel shaders y para eso poner CG_GL_FRAGMENT
perfil= cgGLGetLatestProfile(CG_GL_VERTEX);
cgGLSetOptimalOptions(perfil);
//mi archivo cg se llama simplemente red.cg únicamente cambia el color del polígono.
//mainv es la función principal en nuestro programa.
programa = cgCreateProgramFromFile(contexto,CG_SOURCE,"red.cg",perfil,"mainv",NULL);
cgGLLoadProgram(programa);
//Relacionamos nuestro parámetro a la variable literalmente de nuestro programa en cg
modelViewMatrix = cgGetNamedParameter(programa, "ModelViewProj");
glShadeModel(GL_SMOOTH);
glClearColor(0.0,0.0,0.0,0.0);
glClearDepth(1.0f); // Depth buffer setup
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // R
}
void Glwidget::resizeGL(int width,int height){
if (height == 0)
height = 1;
glViewport(0, 0, width, height); // Reset current viewport
glMatrixMode(GL_PROJECTION); // Select projection matrix
glLoadIdentity(); // Reset projection matrix
gluPerspective (45.0f, (GLfloat)(width)/(GLfloat)(height),0.1f, 100.0f); // Calculate The Aspect Ratio
glMatrixMode(GL_MODELVIEW); // Select modelview matrix
}
void Glwidget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//las transformaciones siempre antes de aplicar el shader
glTranslatef(0.0f, 0.0f, -5.0f);
//ingresar nuestra matriz de proyección.
cgGLSetStateMatrixParameter(modelViewMatrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
//activamos el perfil y el programa.
cgGLEnableProfile(perfil);
cgGLBindProgram(programa);
//Hacemos un sencillo cuadrado
glBegin(GL_QUADS);
glVertex2f(0.7f, 0.7f);
glVertex2f(0.7f, -0.7f);
glVertex2f(-0.7f, -0.7f);
glVertex2f(-0.7f, 0.7f);
glEnd();
cgGLDisableProfile(perfil);
glFlush ();
}
creamos una archivo main.cpp con el siguiente código:
#include <iostream>
#include "qglwidget.h" //el widget creado
#include <QApplication>
using namespace std;
int main(int argc,char *argv[])
{
QApplication app2(argc,argv);
Glwidget wid;
wid.show();
return app2.exec();
}
De esta manera podemos utilizar nuestro shader creado con CG.