PDA

View Full Version : How to sue glMapBuffers/glUnmapBuffer with QGLWidget?



jshafferman
24th October 2013, 22:12
I am trying to follow the OpenGL Superbible (4th Edition) example (ThunderbirdGL) and they have a function glMapBuffers() in a VBOMesh.cpp file and I can't get that function to be recognized by any header that is included with GL. Am I missing something simple?



///////////////////////////////////////////////////////////////////////////

// Scale of the vertices. The only way to do this is to map the VBO back

// into client memory, then back again

void CVBOMesh::Scale(GLfloat fScaleValue)

{

glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]);

M3DVector3f *pVertexData = (M3DVector3f *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);



if(pVertexData != NULL)

{

for(unsigned int i = 0; i < nNumVerts; i++)

m3dScaleVector3(pVertexData[i], fScaleValue);



glUnmapBuffer(GL_ARRAY_BUFFER);

}

}


The error I see from the compiler is:
../shared/VBOMesh.cpp:204: error: 'glMapBuffer' was not declared in this scope
../shared/VBOMesh.cpp:211: error: 'glUnmapBuffer' was not declared in this scope

where shared is the folder that VBOMesh is in.

http://www.opengl.org/sdk/docs/man/xhtml/glMapBuffer.xml reference for glMapBuffer
http://www.opengl.org/sdk/docs/man4/xhtml/glMapBuffer.xml reference for glUnmapBuffer

Any help would be awesome! Thanks

wysota
24th October 2013, 22:48
Did you include GL.h?

jshafferman
25th October 2013, 13:05
Yup I still get the same error after I use this include
#include <GL/gl.h>

VBOMesh.h has #include <QtOpenGL> passed into it from a different header in case your curious.

Just an FYI, I am trying to use mostly Qt related stuff because I am doing all my opengl stuff in QGLWidget. Also I am using Qt 4.8.4 because that is the same version we use at my office and eventually we will be doing Opengl stuff in our widget. Finally the reason I am using Opengl Superbible 4th edition is because that is the superbible edition that matches our products opengl capability set (2.0, 2.1, and ES 2.0)

wysota
25th October 2013, 14:23
I never used glMapBuffer so I might be wrong but don't you have to query for this function using dlsym/getprocaddress first?

stampede
25th October 2013, 14:55
Yes, this function needs to be loaded. I have always used GLEW (The OpenGL Extension Wrangler Library) to load additional functions, simply include glew before gl.h:


#include <GL/glew.h>
#include <GL/gl.h>
...

and link with -lGLEW.
More info here : GLEW (http://glew.sourceforge.net/)

jshafferman
25th October 2013, 15:51
Ok, so I haven't used glew before but if I am guessing I can't use QGLFunctions anymore... Is there a way around that? I will show the whole class just so you can see how I am using QGLFunctions and the current problem is the final function in this .cpp



#include "VBOMesh.h" (in VBOMesh.h I have #inlcude <GL/glew.h>)

#include <QGLFunctions>

QGLFunctions glFuncs(QGLContext::currentContext());

///////////////////////////////////////////////////////////
// Constructor, does what constructors do... set everything to zero or NULL
CVBOMesh::CVBOMesh(void)
{
pIndexes = NULL;
pVerts = NULL;
pNorms = NULL;
pTexCoords = NULL;

nMaxIndexes = 0;
nNumIndexes = 0;
nNumVerts = 0;
}

////////////////////////////////////////////////////////////
// Free any dynamically allocated memory. For those C programmers
// coming to C++, it is perfectly valid to delete a NULL pointer.
CVBOMesh::~CVBOMesh(void)
{
// Just in case these still are allocated when the object is destroyed
delete [] pIndexes;
delete [] pVerts;
delete [] pNorms;
delete [] pTexCoords;

// Delete buffer objects
glFuncs.glDeleteBuffers(4, bufferObjects);
}

////////////////////////////////////////////////////////////
// Start assembling a mesh. You need to specify a maximum amount
// of indexes that you expect. The EndMesh will clean up any uneeded
// memory. This is far better than shreading your heap with STL containers...
// At least that's my humble opinion.
void CVBOMesh::BeginMesh(GLuint nMaxVerts)
{
// Just in case this gets called more than once...
delete [] pIndexes;
delete [] pVerts;
delete [] pNorms;
delete [] pTexCoords;

nMaxIndexes = nMaxVerts;
nNumIndexes = 0;
nNumVerts = 0;

// Allocate new blocks
pIndexes = new GLushort[nMaxIndexes];
pVerts = new M3DVector3f[nMaxIndexes];
pNorms = new M3DVector3f[nMaxIndexes];
pTexCoords = new M3DVector2f[nMaxIndexes];
}

/////////////////////////////////////////////////////////////////
// Add a triangle to the mesh. This searches the current list for identical
// (well, almost identical - these are floats you know...) verts. If one is found, it
// is added to the index array. If not, it is added to both the index array and the vertex
// array grows by one as well.
void CVBOMesh::AddTriangle(M3DVector3f verts[3], M3DVector3f vNorms[3], M3DVector2f vTexCoords[3])
{
const float e = 0.000001; // How small a difference to equate

// First thing we do is make sure the normals are unit length!
// It's almost always a good idea to work with pre-normalized normals
m3dNormalizeVector(vNorms[0]);
m3dNormalizeVector(vNorms[1]);
m3dNormalizeVector(vNorms[2]);


// Search for match - triangle consists of three verts
for(GLuint iVertex = 0; iVertex < 3; iVertex++)
{
GLuint iMatch = 0;
for(iMatch = 0; iMatch < nNumVerts; iMatch++)
{
// If the vertex positions are the same
if(m3dCloseEnough(pVerts[iMatch][0], verts[iVertex][0], e) &&
m3dCloseEnough(pVerts[iMatch][1], verts[iVertex][1], e) &&
m3dCloseEnough(pVerts[iMatch][2], verts[iVertex][2], e) &&

// AND the Normal is the same...
m3dCloseEnough(pNorms[iMatch][0], vNorms[iVertex][0], e) &&
m3dCloseEnough(pNorms[iMatch][1], vNorms[iVertex][1], e) &&
m3dCloseEnough(pNorms[iMatch][2], vNorms[iVertex][2], e) &&

// And Texture is the same...
m3dCloseEnough(pTexCoords[iMatch][0], vTexCoords[iVertex][0], e) &&
m3dCloseEnough(pTexCoords[iMatch][1], vTexCoords[iVertex][1], e))
{
// Then add the index only
pIndexes[nNumIndexes] = iMatch;
nNumIndexes++;
break;
}
}

// No match for this vertex, add to end of list
if(iMatch == nNumVerts)
{
memcpy(pVerts[nNumVerts], verts[iVertex], sizeof(M3DVector3f));
memcpy(pNorms[nNumVerts], vNorms[iVertex], sizeof(M3DVector3f));
memcpy(pTexCoords[nNumVerts], &vTexCoords[iVertex], sizeof(M3DVector2f));
pIndexes[nNumIndexes] = nNumVerts;
nNumIndexes++;
nNumVerts++;
}
}
}

//////////////////////////////////////////////////////////////////
// Compact the data. This is a nice utility, but you should really
// save the results of the indexing for future use if the model data
// is static (doesn't change).
void CVBOMesh::EndMesh(void)
{
// Create the buffer objects
glFuncs.glGenBuffers(4, bufferObjects);

// Copy data to video memory
// Vertex data
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]);
glFuncs.glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pVerts, GL_STATIC_DRAW);

// Normal data
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA]);
glFuncs.glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pNorms, GL_STATIC_DRAW);

// Texture coordinates
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[TEXTURE_DATA]);
glFuncs.glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*2, pTexCoords, GL_STATIC_DRAW);

// Indexes
glFuncs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]);
glFuncs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*nNumIndexes, pIndexes, GL_STATIC_DRAW);

// Free older, larger arrays
delete [] pIndexes;
delete [] pVerts;
delete [] pNorms;
delete [] pTexCoords;

// Reasign pointers so they are marked as unused
pIndexes = NULL;
pVerts = NULL;
pNorms = NULL;
pTexCoords = NULL;
}

//////////////////////////////////////////////////////////////////////////
// Draw - make sure you call glEnableClientState for these arrays
void CVBOMesh::Draw(void)
{
// Here's where the data is now
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]);
glVertexPointer(3, GL_FLOAT,0, 0);

// Normal data
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA]);
glNormalPointer(GL_FLOAT, 0, 0);

// Texture coordinates
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[TEXTURE_DATA]);
glTexCoordPointer(2, GL_FLOAT, 0, 0);

// Indexes
glFuncs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]);
glDrawElements(GL_TRIANGLES, nNumIndexes, GL_UNSIGNED_SHORT, 0);
}


///////////////////////////////////////////////////////////////////////////
// Scale of the vertices. The only way to do this is to map the VBO back
// into client memory, then back again
void CVBOMesh::Scale(GLfloat fScaleValue)
{
glFuncs.glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]);
M3DVector3f *pVertexData = (M3DVector3f *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);

if(pVertexData != NULL)
{
for(unsigned int i = 0; i < nNumVerts; i++)
m3dScaleVector3(pVertexData[i], fScaleValue);

glUnmapBuffer(GL_ARRAY_BUFFER);
}
}


If I add #include <GL/glew.h> before VBOMesh/QGLFunctions I get the following errors

Compile Errors:
/opt/Qt/include/QtOpenGL/qglfunctions.h:24:2: warning: #warning qglfunctions.h is not compatible with GLEW, GLEW defines will be undefined
/opt/Qt/include/QtOpenGL/qglfunctions.h:25:2: warning: #warning To use GLEW with Qt, do not include <QtOpenGL> or <QGLFunctions> after glew.h
....

Edit:
This disappears when I include the lib -lGLEW

/home/jshafferman/OpenGL/build-ThunderbirdGL-Desktop-Debug/../shared/VBOMesh.cpp:204: undefined reference to `__glewMapBuffer'
/home/jshafferman/OpenGL/build-ThunderbirdGL-Desktop-Debug/../shared/VBOMesh.cpp:211: undefined reference to `__glewUnmapBuffer'

So by that compiler error I am not allowed to use QGLFunctions so all the places where glFuncs."" are used won't work anymore but does glew have that functionality built into it?

Thanks for all your help! You are all rockstars ;)

Added after 6 minutes:

I build 'green' however I still have the above warnings and when I try to run the program I get this error/crash response:

ASSERT: "context" in file qglfunctions.cpp, line 143
The program has unexpectedly finished.

Any ideas?

stampede
25th October 2013, 16:00
I never used QGLFunctions, but I think you shouldn't mix it with GLEW. I'd just stick to plain OpenGL calls and remove all occurences of QGLFunctions from the project. GLEW should have all functions you need.

jshafferman
25th October 2013, 16:39
Thank you very much for your comments! Yeah it was the QGLFunctions not working properly or not having the set of functions I wanted. The glew library worked perfectly for me so once I removed the QGLFunction the glew library allowed me to handle all the functions that I wanted it to. Thanks stampede and wysota!

jshafferman
25th October 2013, 20:41
Boo! So I am now running into an issue that is related to using glew (or so I think). I compile green inside of Qt Creator no problem but when I run my executable I get this output:

texobj = 2
level = 0
The program has unexpectedly finished.
I will put the .cpp file in the next thread...

Where thunderBirdBody/Glass are the VBOMesh previously discussed.

Added after 5 minutes:

Part 1:



#include "glwidget.h"

#include "../shared/gltools.h"

#include <math.h>
#include <QKeyEvent>

// Thunderbird body
extern short face_indicies[3704][9];
extern GLfloat vertices [1898][3];
extern GLfloat normals [2716][3];
extern GLfloat textures [2925][2];

// Glass cock-pit
extern short face_indiciesGlass[352][9];
extern GLfloat verticesGlass[197][3];
extern GLfloat normalsGlass [227][3];
extern GLfloat texturesGlass [227][2];

namespace
{
// Storeage for two texture objects
GLuint textureObjects[3];
#define CUBE_MAP 0
#define BODY_TEXTURE 1
#define GLASS_TEXTURE 2

// Six sides of a cube map
const char *szCubeFaces[6] = { "../Vbo/pos_x.tga", "../Vbo/neg_x.tga", "../Vbo/pos_y.tga", "../Vbo/neg_y.tga",
"../Vbo/pos_z.tga", "../Vbo/neg_z.tga" };

GLenum cube[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
}

GLWidget::GLWidget(QWidget *parent) :
QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::SampleBuffers), parent)
{
animationTimer.setSingleShot(false);
connect(&animationTimer, SIGNAL(timeout()), this, SLOT(TimerFunction()));
animationTimer.start(0);
}

GLWidget::~GLWidget()
{
glDeleteTextures(2, textureObjects);
}

void GLWidget::initializeGL()
{

GLfloat fScale = 0.01f;
GLbyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
int i;

// Cull backs of polygons
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);

glGenTextures(2, textureObjects);

// Set up texture maps
// Cube Map
glBindTexture(GL_TEXTURE_CUBE_MAP, textureObjects[CUBE_MAP]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

// Load Cube Map images
for(i = 0; i < 6; i++)
{
// Load this texture map
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
pBytes = gltLoadTGA(szCubeFaces[i], &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(cube[i], 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
}


// Load the body texture
glBindTexture(GL_TEXTURE_2D, textureObjects[BODY_TEXTURE]);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
pBytes = gltLoadTGA("../Vbo/body.tga", &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, (void *)pBytes);
free(pBytes);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

GLfloat fLargest;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);


glBindTexture(GL_TEXTURE_2D, textureObjects[GLASS_TEXTURE]);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

pBytes = gltLoadTGA("../Vbo/glass.tga", &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, (void *)pBytes);
free(pBytes);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


/////////////////////////////////////////////////////////////////////
// Set up the texture units

// First texture unit contains the color map
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Decal tarnish

// Second texture unit contains the cube map
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureObjects[CUBE_MAP]);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glEnable(GL_TEXTURE_CUBE_MAP);

// Multiply this texture by the one underneath
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

// Load Thunderbird body and canopy
// Temporary workspace
M3DVector3f vVerts[3];
M3DVector3f vNorms[3];
M3DVector2f vTex[3];

// Start assembling the body mesh, set maximum size
thunderBirdBody.BeginMesh(3704*3);

// Loop through all the faces
for(int iFace = 0; iFace < 3704; iFace++)
{
// Assemble the triangle
for(int iPoint = 0; iPoint < 3; iPoint++)
{
memcpy(&vVerts[iPoint][0], &vertices[face_indicies[iFace][iPoint]][0], sizeof(M3DVector3f));
memcpy(&vNorms[iPoint][0], &normals[face_indicies[iFace][iPoint+3]][0], sizeof(M3DVector3f));
memcpy(&vTex[iPoint][0], &textures[face_indicies[iFace][iPoint+6]][0], sizeof(M3DVector2f));
}

thunderBirdBody.AddTriangle(vVerts, vNorms, vTex);
}

// Close the mesh and scale it (it's a little BIG in it's original format)
thunderBirdBody.EndMesh();
thunderBirdBody.Scale(fScale);

// Now do the same for the canopy
thunderBirdGlass.BeginMesh(352*3);

for(int iFace = 0; iFace < 352; iFace++)
{
// Assemble the triangle
for(int iPoint = 0; iPoint < 3; iPoint++)
{
memcpy(&vVerts[iPoint][0], &verticesGlass[face_indiciesGlass[iFace][iPoint]][0], sizeof(M3DVector3f));
memcpy(&vNorms[iPoint][0], &normalsGlass[face_indiciesGlass[iFace][iPoint+3]][0], sizeof(M3DVector3f));
memcpy(&vTex[iPoint][0], &texturesGlass[face_indiciesGlass[iFace][iPoint+6]][0], sizeof(M3DVector2f));
}

thunderBirdGlass.AddTriangle(vVerts, vNorms, vTex);
}

thunderBirdGlass.EndMesh();
thunderBirdGlass.Scale(fScale);

GLfloat fAmbLight[] = { 0.075f, 0.075f, 0.075f, 0.0f };
GLfloat fDiffLight[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat fSpecLight[] = { 0.25f, 0.25f, 0.25f, 0.0f };
GLfloat lightPos[] = { -50.0f, 100.0f, 100.0f, 1.0f };

// Set up lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, fDiffLight);
glMateriali(GL_FRONT, GL_SHININESS, 128);

glLightfv(GL_LIGHT0, GL_AMBIENT, fAmbLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, fDiffLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, fSpecLight);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fAmbLight);
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);

// Light never changes, put it here
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

frameCamera.MoveUp(20.0f);
}


Part 2



void GLWidget::DrawSkyBox()
{
GLfloat fExtent = 50.0f;

glBegin(GL_QUADS);
//////////////////////////////////////////////
// Negative X
// Note, we must now use the multi-texture version of glTexCoord
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, 1.0f);
glVertex3f(-fExtent, -fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, -1.0f);
glVertex3f(-fExtent, -fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, -1.0f);
glVertex3f(-fExtent, fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, 1.0f);
glVertex3f(-fExtent, fExtent, fExtent);


///////////////////////////////////////////////
// Postive X
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, -1.0f);
glVertex3f(fExtent, -fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, 1.0f);
glVertex3f(fExtent, -fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, 1.0f);
glVertex3f(fExtent, fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, -1.0f);
glVertex3f(fExtent, fExtent, -fExtent);


////////////////////////////////////////////////
// Negative Z
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, -1.0f);
glVertex3f(-fExtent, -fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, -1.0f);
glVertex3f(fExtent, -fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, -1.0f);
glVertex3f(fExtent, fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, -1.0f);
glVertex3f(-fExtent, fExtent, -fExtent);


////////////////////////////////////////////////
// Positive Z
glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, 1.0f);
glVertex3f(fExtent, -fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, 1.0f);
glVertex3f(-fExtent, -fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, 1.0f);
glVertex3f(-fExtent, fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, 1.0f);
glVertex3f(fExtent, fExtent, fExtent);


//////////////////////////////////////////////////
// Positive Y
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, 1.0f);
glVertex3f(-fExtent, fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, 1.0f, -1.0f);
glVertex3f(-fExtent, fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, -1.0f);
glVertex3f(fExtent, fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, 1.0f, 1.0f);
glVertex3f(fExtent, fExtent, fExtent);


///////////////////////////////////////////////////
// Negative Y
glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, -1.0f);
glVertex3f(-fExtent, -fExtent, -fExtent);

glMultiTexCoord3f(GL_TEXTURE1, -1.0f, -1.0f, 1.0f);
glVertex3f(-fExtent, -fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, 1.0f);
glVertex3f(fExtent, -fExtent, fExtent);

glMultiTexCoord3f(GL_TEXTURE1, 1.0f, -1.0f, -1.0f);
glVertex3f(fExtent, -fExtent, -fExtent);
glEnd();
}

void GLWidget::DrawThunderBird()
{

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_CUBE_MAP);
glActiveTexture(GL_TEXTURE0);

glPushMatrix();
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, textureObjects[BODY_TEXTURE]);
thunderBirdBody.Draw();
glPopMatrix();

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_CUBE_MAP);
glActiveTexture(GL_TEXTURE0);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
glBindTexture(GL_TEXTURE_2D, textureObjects[GLASS_TEXTURE]);

glTranslatef(0.0f, 0.132f, 0.555f);

glFrontFace(GL_CW);
thunderBirdGlass.Draw();
glFrontFace(GL_CCW);
thunderBirdGlass.Draw();
glDisable(GL_BLEND);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}


// Called to draw scene
void GLWidget::paintGL()
{
// Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
frameCamera.ApplyCameraTransform(); // Move the camera about

// Sky Box is manually textured
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);

glEnable(GL_TEXTURE_CUBE_MAP);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
DrawSkyBox();

// Use texgen to apply cube map
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_CUBE_MAP);

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);


glActiveTexture(GL_TEXTURE1);
glMatrixMode(GL_TEXTURE);
glPushMatrix();

// Invert camera matrix (rotation only) and apply to
// texture coordinates
M3DMatrix44f m, invert;
frameCamera.GetCameraOrientation(m);
m3dInvertMatrix44(invert, m);
glMultMatrixf(invert);
glActiveTexture(GL_TEXTURE0);
glMatrixMode(GL_MODELVIEW);

// This displays a rotating ThunderBird Model
static GLfloat yRot = 0.0f;
yRot += 1.1f;
glTranslatef(0.0f, 19.6f, -3.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
DrawThunderBird();

// This shows four ThunderBirds flying in formation
// Coment out the above section, and uncomment
// the following section to see the four ThunderBirds
// in formation.
/*
glPushMatrix();
glTranslatef(0.0f, 21.5f, -7.0f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glRotatef(-10.0f, 1.0f, 0.0f, 0.0f);
DrawThunderBird();
glPopMatrix();

glPushMatrix();
glTranslatef(0.85f, 20.75f, -6.5f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glRotatef(-10.0f, 1.0f, 0.0f, 0.0f);
DrawThunderBird();
glPopMatrix();

glPushMatrix();
glTranslatef(-1.0f, 19.75f, -7.0f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glRotatef(-10.0f, 1.0f, 0.0f, 0.0f);
DrawThunderBird();
glPopMatrix();

glPushMatrix();
glTranslatef(-0.15f, 19.0f, -6.5f);
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glRotatef(-10.0f, 1.0f, 0.0f, 0.0f);
DrawThunderBird();
glPopMatrix();
*/

glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE1);
glPopMatrix();
glActiveTexture(GL_TEXTURE0);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

// Do the buffer Swap
swapBuffers();
}

void GLWidget::keyPressEvent(QKeyEvent *event)
{

if(event->key() == Qt::Key_Up)
frameCamera.MoveForward(0.1f);

if(event->key() == Qt::Key_Down)
frameCamera.MoveForward(-0.1f);

if(event->key() == Qt::Key_Left)
frameCamera.RotateLocalY(0.1);

if(event->key() == Qt::Key_Right)
frameCamera.RotateLocalY(-0.1);

if(event->key() == Qt::Key_PageUp)
frameCamera.RotateLocalX(0.1);

if(event->key() == Qt::Key_PageDown)
frameCamera.RotateLocalX(-0.1);

// Refresh the Window
update();
}

void GLWidget::TimerFunction()
{
update();
}

void GLWidget::resizeGL(int width, int height)
{
GLfloat fAspect;

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(height == 0)
height = 1;

glViewport(0, 0, width, height);

fAspect = (GLfloat)width / (GLfloat)height;

// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the clipping volume
gluPerspective(35.0f, fAspect, 1.0f, 1000.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

stampede
26th October 2013, 08:12
1. Did you call glewInit() ?
2. Did you try to debug the app ?
btw. read here (http://www.opengl.org/wiki/OpenGL_Loading_Library) the part about GLEW

saman_artorious
26th October 2013, 11:40
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glext.h>

void GlWidget::exec()
{
initializeGLFunctions();

GLuint vboId = ppi->getVBOID();

glBindBuffer(GL_ARRAY_BUFFER, vboId);

//glBufferData( GL_ARRAY_BUFFER, (ANGLE_COUNT/24 * RANGE_COUNT * 6 * sizeof(float)), buffer0, GL_DYNAMIC_DRAW );

if(segmentCount % 2 == 0)
glBufferSubData(GL_ARRAY_BUFFER, segmentIndex * RANGE_COUNT * 6 * sizeof(float), 5 * RANGE_COUNT * 6 * sizeof(float), &buffer0[0]);
else
glBufferSubData(GL_ARRAY_BUFFER, segmentIndex * RANGE_COUNT * 6 * sizeof(float), 5 * RANGE_COUNT * 6 * sizeof(float), &buffer1[0]);

glBindBuffer(GL_ARRAY_BUFFER, 0);
}

jshafferman
29th October 2013, 13:21
Thanks to both comments! I was able to figure out that I hadn't initialized glew with the glewInit() function. I haven't used glew so I didn't realize you had to initialize it similair to glut. I put the glewInit() funciton as the first line in the the GLWidget::initializeGL() and everything is working as it should. I will most likely have more questions in the future but thanks for everyone and there help!