Hi guys,
I have a project I’m working where I need to paint a sprite and I can’t seem to get it to paint textures. I have don’e extensive error checking through my texture loading routine and nothing turns up. I’m at a loss. The code compiles fine and runs and it even paints the gl display list. It just won’t paint the texture. I have never had this problem but I am new to display lists and was wondering if that might be causing some of the issue. Here is the code that is giving me trouble:
#include "Sprite.h"
namespace NEngine
{
namespace NGFX
{
void CheckGLError();
CSprite::CSprite()
{
mpPng = new NFormats::CPng();
mpFile = new NFile::CFileSystem();
/**
* We need to load all the sprites in the "Data/Gfx/Sprites" folder
*/
std::vector<std::string> vec_folders = mpFile->GetFolders("Data/Gfx/Sprites");
std::vector<std::string> vec_files;
for(int i = 0; i < vec_folders.size(); ++i)
{
vec_files = mpFile->GetFilesInFolder(vec_folders.at(i), "*.sprite");
for(int j = 0; j < vec_files.size(); ++j)
{
LoadSprite(vec_files.at(j));
}
}
}
CSprite::~CSprite()
{
delete mpPng;
}
void CSprite::LoadSprite(std::string astrPath)
{
FILE *pF = fopen(astrPath.data(), "rb");
if(!pF)
{
REPORT("{GFX}["<< TIME<<"]Error:"<< astrPath<< " is an invalid file! <CStd File I/O>
");
return;
}
fseek(pF, 0, SEEK_END);
int length = ftell(pF);
fseek(pF, 0, SEEK_SET);
if(length <= 0)
{
REPORT("{GFX}["<< TIME<<"]Error: "<< astrPath<< " is an empty file! <CStd File I/O>
");
return;
}
char *vData = new char[length];
fread(vData, 1, length, pF);
ParseSpriteFile(vData);
fclose(pF);
}
void CSprite::GenerateGLDisplayList(SGfxSprite *aSprite, int aNumFrames)
{
assert(aSprite != NULL);
int iGlError = glGetError();
if(iGlError != GL_NO_ERROR)
{
REPORT("{Gfx}["<< TIME<< "]Error: "<< gluErrorString(iGlError)<< " <OpenGL>
");
}
aSprite->iFrames = new uint[aNumFrames];
uint displayList = glGenLists(aNumFrames);
if(displayList <= 0)
{
REPORT("{Gfx}["<< TIME<< "]Error: Couldn't create OpenGL display lists! <OpenGL>
");
return;
}
aSprite->iFrames[0] = displayList;
aSprite->iFrames[1] = displayList+1;
aSprite->iFrames[2] = displayList+2;
aSprite->iFrames[3] = displayList+3;
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: List "<< aSprite->iFrames[0]<< " created! <Sprite System>
");
REPORT("{Gfx}["<< TIME<< "]DEBUG: List "<< aSprite->iFrames[1]<< " created! <Sprite System>
");
REPORT("{Gfx}["<< TIME<< "]DEBUG: List "<< aSprite->iFrames[2]<< " created! <Sprite System>
");
REPORT("{Gfx}["<< TIME<< "]DEBUG: List "<< aSprite->iFrames[3]<< " created! <Sprite System>
");
#endif
for(int i = 0; i < aNumFrames; ++i)
{
glNewList(aSprite->iFrames[i], GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, aSprite->iGLTextures[i]);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2f(aSprite->gfxObject->sPoly->sPosition->nX, aSprite->gfxObject->sPoly->sPosition->nY);
glTexCoord2i(1, 0);
glVertex2f(aSprite->gfxObject->sPoly->sDimensions->nX, aSprite->gfxObject->sPoly->sPosition->nY);
glTexCoord2i(1, 1);
glVertex2f(aSprite->gfxObject->sPoly->sDimensions->nX, aSprite->gfxObject->sPoly->sDimensions->nY);
glTexCoord2i(0, 1);
glVertex2f(aSprite->gfxObject->sPoly->sPosition->nX, aSprite->gfxObject->sPoly->sDimensions->nY);
glEnd();
glEndList();
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Display list "<< aSprite->iFrames[i]<< " compiled! <OpenGL>
");
#endif
iGlError = glGetError();
if(iGlError != GL_NO_ERROR)
{
REPORT("{Gfx}["<< TIME<< "]Error: "<< gluErrorString(iGlError)<< " <OpenGL>
");
}
if(!aSprite->iFrames[i])
{
REPORT("{Gfx}["<< TIME<< "]Error: Display list reference is not a list! <OpenGL>
");
}
}
aSprite->currentFrame = 0;
REPORT("{Gfx}["<< TIME<< "]Information: OpenGL Display lists for "<< aSprite->str_Name<< " was successfully created! <Sprite System>
");
}
void CSprite::PaintSpriteByName(std::string aStrName)
{
int iGlError = glGetError();
if(iGlError != GL_NO_ERROR)
{
REPORT("{Gfx}["<< TIME<< "]Error: "<< gluErrorString(iGlError)<< " <OpenGL>
");
}
for(int i = 0; i < vec_Sprites.size(); ++i)
{
SGfxSprite *sCurrSprite = &vec_Sprites.at(i);
if(!strcmp(sCurrSprite->str_Name.data(), aStrName.data()))
{
if(sCurrSprite->currentFrame >= DIM(sCurrSprite->iGLTextures))
{
sCurrSprite->currentFrame = 0;
}
else
{
++sCurrSprite->currentFrame;
}
glBindTexture(GL_TEXTURE_2D, sCurrSprite->iGLTextures[0]);
glCallList(sCurrSprite->iFrames[0]);
}
}
iGlError = glGetError();
if(iGlError != GL_NO_ERROR)
{
REPORT("{Gfx}["<< TIME<< "]Error: "<< gluErrorString(iGlError)<< " <OpenGL>
");
}
}
void CSprite::ParseSpriteFile(char aData[])
{
CheckGLError();
/**
* The scripts are setup like so:
***********************************************
* Pngs:
* 4; // This is the number of frames.
* <pngname>_001.png;
* <pngname>_002.png;
* <pngname>_003.png;
* <pngname>_004.png;
*
* Properties:
* name=<obj name>;
* width=###;
* height=###;
************************************************
*/
vec_Sprites.push_back(SGfxSprite("",
new SGraphicsObject(EPhysicsObjectShape_Quad,
new SPoly(new SVec2D(0, 0), new SVec2D(0, 0)))));
char *pPngStr = new char[4096];
pPngStr = strtok(aData, "
");
pPngStr = strtok(NULL, "
");
int iNumFrames = atoi(pPngStr);
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Number of frames: "<< iNumFrames<< " <Sprite System>
");
#endif
vec_Sprites.at(vec_Sprites.size()-1).iGLTextures = new uint[iNumFrames];
glGenTextures(iNumFrames, vec_Sprites.at(vec_Sprites.size()-1).iGLTextures);
int i = 0; // used for loop only!
while(pPngStr != NULL)
{
pPngStr = strtok(NULL, "
");
if(!strcmp(pPngStr, "Properties:") || i >= iNumFrames)
{
break;
}
if(mpPng->LoadPng(pPngStr))
{
CheckGLError();
glBindTexture(GL_TEXTURE_2D, vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[i]);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
CheckGLError();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mpPng->miWidth, mpPng->miHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mpPng->mpData);
CheckGLError();
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Created texture for "<< pPngStr<< " at "<< vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[i]<<"! <OpenGL>
");
#endif
CheckGLError();
}
if(!glIsTexture(vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[i]))
{
REPORT("{Gfx}["<< TIME<< "]Error: Texture reference is not a texture! <OpenGL>
");
}
++i;
}
pPngStr = strtok(NULL, "=
");
pPngStr = strtok(NULL, "
");
std::string str_name = pPngStr;
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Sprite name: "<< str_name<< " <Sprite System>
");
#endif
pPngStr = strtok(NULL, "=
");
pPngStr = strtok(NULL, "
");
int iWidth = atoi(pPngStr);
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Sprite width(pixels): "<< iWidth<< " <Sprite System>
");
#endif
pPngStr = strtok(NULL, "=
");
pPngStr = strtok(NULL, "
");
int iHeight = atoi(pPngStr);
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Sprite height(pixels): "<< iHeight<< " <Sprite System>
");
#endif
vec_Sprites.at(vec_Sprites.size()-1).str_Name = str_name;
vec_Sprites.at(vec_Sprites.size()-1).gfxObject->sPoly->sDimensions->nX = iWidth;
vec_Sprites.at(vec_Sprites.size()-1).gfxObject->sPoly->sDimensions->nY = iHeight;
GenerateGLDisplayList(&vec_Sprites.at(vec_Sprites.size()-1), iNumFrames);
#ifdef DEBUG
REPORT("{Gfx}["<< TIME<< "]DEBUG: Sprite("<< str_name<<") OpenGL textures:
"<<
vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[0]<<
"
"<< vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[1]<<
"
"<< vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[2]<<
"
"<< vec_Sprites.at(vec_Sprites.size()-1).iGLTextures[3]<< " <Sprite System>
");
#endif
CheckGLError();
}
void CheckGLError()
{
int iGlError = glGetError();
if(iGlError != GL_NO_ERROR)
{
REPORT("{Gfx}["<< TIME<< "]Error: "<< gluErrorString(iGlError)<< " <OpenGL>
");
}
}
}
}
Like I said, the code compiles fine and it runs. The REPORT macro I have here even reports a green light the whole time. So, my question is: Is there something in this code that I am doing wrong that would prevent OpenGL from either generating or painting a texture?
NOTE: I am coding with Qt on Linux (Xubuntu 12.04 LTS) (Qt 4.8.1)
My OpenGL context is actually a Qt Widget called QGLWidget. Here is the code for that class:
class CGLWidget : public QGLWidget
{
public:
CGLWidget(CEngine *aEngine, int aPID, char *paArgs[], SIDLookup *aLookup) :
mEngine(aEngine), miPID(aPID), mpArgs(paArgs), mpLookup(aLookup)
{
mpCom = new SCom(0, 0, "QtGL", EMessageType_None, NULL);
initializeGL();
}
~CGLWidget() {}
void paintGL()
{
if(!bInitialized)
{
return;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
mpCom->Data = NULL;
mpCom->eMsgType = EMessageType_Update;
mpCom->iRecieverID = mpLookup->iGraphicsID;
mEngine->SendMsg(mpCom, mpLookup);
}
void initializeGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void resizeGL(int w, int h)
{
if(!bInitialized)
{
return;
}
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
REPORT("{GFX}["<< TIME<< "]Information: Resizing to ("<< w<< ", "<< h<< ") <OpenGL>
");
}
void InitEngine()
{
if(!bInitialized)
{
mEngine = new CEngine(miPID, mpArgs, mpLookup);
bInitialized = true;
}
}
Any help is greatly appreciated!!!