PDA

View Full Version : Need help texturing/materials with display lists



Gauge
03-11-2009, 11:21 AM
First let me say I've tried figuring this out on my own, reading a ton of stuff googling forever. I just can't seem to solve my problem. When I render a single textured object my code works. When I add a textured object to the object vector seen in my code, it crashes. I know my object class is intact and working correctly, I've reconstructed my object files from the loaded objects. So I know data is being stored correctly. On top of that for some reason it always misses parts of my non textured objects.

What I'm trying to do here is create segmented objects with each segment being in a display list. Each segment also can have multiple textures/materials.

Please please please have a look at my code and just brush over it. It's been 4 days since I made any progress at all on it.

Here is my rendering code



#include "render.h"

render::render()
{
theta = 47;
}

render::~render()
{
tFactory.DeleteAll();
}

void render::LoadObject(vector<BaseObject>::iterator&amp; tempObject)
{ofstream outfile;
outfile.open("blah.out");
vector<point>::iterator v = tempObject->GetVBegin();
vector<point>::iterator vn = tempObject->GetVnBegin();
vector<uvPoint>::iterator vt = tempObject->GetVtBegin();

int y = 0;

tFactory.LoadTextures(tempObject->GetMaterialLoc());

for(vector<group>::iterator x = tempObject->GetGroupsBegin(); x != tempObject->GetGroupsEnd() ; x++)
{
x->groupCompileIndex = glGenLists(1);
glNewList(x->groupCompileIndex, GL_COMPILE_AND_EXECUTE);
glPushMatrix();
glBegin(GL_TRIANGLES);

for(int i = 0 ; i < x->faces.size() ; i++)
{
if(i == 0)
{
tFactory.SetUpTexture(x->materials[y].materialName, outfile);
}
else if(i == x->materials[y].polyIndex)
{
y++;
tFactory.SetUpTexture(x->materials[y].materialName, outfile);
}

if(x->faces[i].vtIndex != NULL)
{
glTexCoord2f(vt[x->faces[i].vtIndex[0]-1].x, vt[x->faces[i].vtIndex[0]-1].y);
}
glNormal3f(vn[x->faces[i].vnIndex[0]-1].x, vn[x->faces[i].vnIndex[0]-1].y, vn[x->faces[i].vnIndex[0]-1].z);
glVertex3f(v[x->faces[i].vIndex[0]-1].x, v[x->faces[i].vIndex[0]-1].y, v[x->faces[i].vIndex[0]-1].z);

if(x->faces[i].vtIndex != NULL)
{
glTexCoord2f(vt[x->faces[i].vtIndex[1]-1].x, vt[x->faces[i].vtIndex[1]-1].y);
}
glNormal3f(vn[x->faces[i].vnIndex[1]-1].x, vn[x->faces[i].vnIndex[1]-1].y, vn[x->faces[i].vnIndex[1]-1].z);
glVertex3f(v[x->faces[i].vIndex[1]-1].x, v[x->faces[i].vIndex[1]-1].y, v[x->faces[i].vIndex[1]-1].z);

if(x->faces[i].vtIndex != NULL)
{
glTexCoord2f(vt[x->faces[i].vtIndex[2]-1].x, vt[x->faces[i].vtIndex[2]-1].y);
}
glNormal3f(vn[x->faces[i].vnIndex[2]-1].x, vn[x->faces[i].vnIndex[2]-1].y, vn[x->faces[i].vnIndex[2]-1].z);
glVertex3f(v[x->faces[i].vIndex[2]-1].x, v[x->faces[i].vIndex[2]-1].y, v[x->faces[i].vIndex[2]-1].z);
}
glEnd();
glEndList();
y = 0;
}
outfile.close();
}

void render::LoadTextures(string fileName)
{
tFactory.LoadTextures(fileName);
}

void render::LightSetup()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
}

void render::SetupBlending(int&amp; bType) const //antialiasing
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

switch(bType)
{
case GG_AA_X2:
{
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
}
case GG_AA_X4:
{
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
}
case GG_MS:
{
glEnable(GL_MULTISAMPLE);
}
}
}

void render::Init(int bType)
{
glEnable(GL_TEXTURE_2D);

SetupBlending(bType);

glMatrixMode(GL_PROJECTION);
gluPerspective(theta, 1, .9, 500);
glMatrixMode(GL_TEXTURE);
glRotatef(180.0, 1.0, 0.0, 0.0); //Flips textures due to how SDL loads them.
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0, 0.0, 0.0);
glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
LightSetup();
}

void render::Display(vector<BaseObject>&amp; objects)
{
for(vector<BaseObject>::iterator i = objects.begin() ; i != objects.end() ; i++)
{glTranslatef(4.0, 0, 0);
if(!i->Loaded())
{
LoadObject(i);
i->ChangeLoadState(true);
}
else
{
for(vector<group>::iterator x = i->GetGroupsBegin() ; x != i->GetGroupsEnd() ; x++)
{
glCallList(x->groupCompileIndex);
}
}
}
}

void render::FreeLists(vector<BaseObject>&amp; objects)
{
for(vector<BaseObject>::iterator i = objects.begin() ; i != objects.end() ; i++)
{
for(vector<group>::iterator x = i->GetGroupsBegin() ; x != i->GetGroupsEnd() ; x++)
{
glDeleteLists(x->groupCompileIndex, 1);
}
}
tFactory.DeleteAll();
}


and here is my texture factory



#include "textureFactory.h"

textureFactory::textureFactory()
{
}

textureFactory::~textureFactory()
{
textureList.clear();
}

bool textureFactory::TextureLoaded(string textureName) const
{
if(textureList.empty())
{
return false;
}
else if(textureList.find(textureName) != textureList.end())
{
return true;
}
else
{
return false;
}
}

void textureFactory::TextureFormat(GLenum&amp; textureFormat, int&amp; numOfColors, SDL_Surface*&amp; picture)
{
numOfColors = picture->format->BytesPerPixel;

if (numOfColors == 4)
{
if (picture->format->Rmask == 0x000000ff)
{
textureFormat = GL_RGBA;
}
else
{
textureFormat = GL_BGRA;
}
}
else if (numOfColors == 3)
{
if (picture->format->Rmask == 0x000000ff)
{
textureFormat = GL_RGB;
}
else
{
textureFormat = GL_BGR;
}
}
}

void textureFactory::LoadTextures(string fileName)
{
string garbage, tempMaterial, map;
int numOfColors;
GLenum textureFormat = GL_RGB;
SDL_Surface* picture = NULL;
textureNode tempTexture;
tempTexture.isUvMap = false;
ifstream infile;
infile.open(fileName.c_str());
//ofstream outfile;
//outfile.open("blah.out");
infile >> garbage;
while(infile)
{
if(garbage == "newmtl")
{
infile >> tempMaterial;
//outfile << tempMaterial << endl;
textureList.insert(make_pair(tempMaterial, tempTexture));
infile >> garbage >> textureList[tempMaterial].ns >> garbage;
infile >> textureList[tempMaterial].ka.x >> textureList[tempMaterial].ka.y >> textureList[tempMaterial].ka.z;
infile >> garbage >> textureList[tempMaterial].kd.x >> textureList[tempMaterial].kd.y >> textureList[tempMaterial].kd.z;
infile >> garbage >> textureList[tempMaterial].ks.x >> textureList[tempMaterial].ks.y >> textureList[tempMaterial].ks.z >> garbage;

if(garbage == "map_Kd")
{
textureList[tempMaterial].isUvMap = true;

infile >> map >> garbage;
picture = SDL_LoadBMP(map.c_str());
TextureFormat(textureFormat, numOfColors, picture);

glGenTextures(1, &amp;textureList[tempMaterial].textureIndex);
glBindTexture(GL_TEXTURE_2D, textureList[tempMaterial].textureIndex);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, numOfColors, picture->w, picture->h, 0, textureFormat, GL_UNSIGNED_BYTE, picture->pixels);
//gluBuild2DMipmaps(GL_TEXTURE_2D, numOfColors, picture->w, picture->h, textureFormat, GL_UNSIGNED_BYTE, picture->pixels);

if(picture)
{
SDL_FreeSurface(picture);
picture = NULL;
}
}
infile >> textureList[tempMaterial].d;
}
infile >> garbage;
}
infile.close();
//outfile.close();
}

void textureFactory::DeleteTexture(string textureName)
{
if(textureList.find(textureName) != textureList.end() &amp;&amp; !textureList.empty())
{
glDeleteTextures(1, &amp;textureList.find(textureName)->second.textureIndex);
textureList.erase(textureList.find(textureName));
}
}

void textureFactory::DeleteAll()
{
for(map<string, textureNode>::iterator i = textureList.begin() ; i != textureList.end() ; i++)
{
glDeleteTextures(1, &amp;i->second.textureIndex);
}
textureList.clear();
}

void textureFactory::SetUpTexture(string textureName, ofstream&amp; outfile)
{
if(textureList.find(textureName) != textureList.end() &amp;&amp; !textureList.empty())
{
float temp[4];

glMaterialf(GL_FRONT, GL_SHININESS, textureList[textureName].ns);
temp[0] = textureList[textureName].ka.x;
temp[1] = textureList[textureName].ka.y;
temp[2] = textureList[textureName].ka.z;
temp[3] = textureList[textureName].d;
glMaterialfv(GL_FRONT, GL_AMBIENT, temp);
temp[0] = textureList[textureName].kd.x;
temp[1] = textureList[textureName].kd.y;
temp[2] = textureList[textureName].kd.z;
temp[3] = textureList[textureName].d;
glMaterialfv(GL_FRONT, GL_DIFFUSE, temp);
temp[0] = textureList[textureName].ks.x;
temp[1] = textureList[textureName].ks.y;
temp[2] = textureList[textureName].ks.z;
temp[3] = textureList[textureName].d;
glMaterialfv(GL_FRONT, GL_SPECULAR, temp);

if(textureList[textureName].isUvMap)
{
glBindTexture(GL_TEXTURE_2D, textureList[textureName].textureIndex);
}
}
}


I just can't seem to trace my problem. I know it's a texturing/materials problem. Also, if I use GL_COMPILE on the non textured object, it will draw the missing material but mess up somewhere else. I'm just at such a loss of what to do or how to debug this problem. I'm new to openGL I'm a littl eout of my league. Also I don't have much time t debug since I'm in iraq. Please please please help :'(

Gauge

Gauge
03-12-2009, 01:50 AM
I fixed my non textured object problem by moving my glBegin and glEnd state calls in my load object funtion. It was dumb of me to put them where they are in the code above.

However, it still crashes when I draw more than one textured object at a time, even if the object only has a single texture. It will draw one textured object, but not two, not even two of the same object with the same texture.

ZbuffeR
03-12-2009, 04:23 AM
You should use a debugger, to pinpoint the exact place of the crash.

Gauge
03-12-2009, 06:54 AM
for the life of me I can't figure out how to use the dev c++ debugger. I've tried several times.

I did manually load 2 textures and loaded a single object and it worked. So I know it's not how I'm loading textures because I could freely load either of them.

It crashes on glTexCoord, when I remove those it works when I don't it doesn't ( with 2 objects that is ). right before glEnd();
I posted this on gamedev also and got nothing from there either. It is an enigma to me really. I know it's something I'm doing in openGL though. It has to be something with using texcoord in a single pass or something....I have no idea.

ZbuffeR
03-12-2009, 07:00 AM
devc++ : click the "debug" tab at the bottom, then the "debug" button. Then when you app crashes, it should point you to the line where it happened. The backtrace is usefull too.
You can also double click before a code line, to insert a breakpoint, next debug session will allow you to step fromt here, watch variable values, send gdb commands, ...

It can not crash in glTexCoord2f, but right before, when you send your array value.
Try first assigning it to a temp value, and do that for each temp step, so that you can easily step trough this and watch your mistake. Probably and array out of bounds or something like that.

Gauge
03-12-2009, 07:52 AM
When I try to debug it says an access violation(seg fault) raised in your program. It doesn't show me the line it happens at. For the most part I find debuggers worthless. So it's a seg fault, now I just have to find where.

I've outputted my objects tons of times and there is no problem with loading the texcoords in them....

Gauge
03-12-2009, 08:24 AM
Well when you're right, you're right. For some reason when I load more than one object my texcoords inside the object are getting all jacked up. So a seg fault it is. Thank you much kind sir. Must look at my c++ code. It's good to know that it wasn't my openGL code messin this stuff up lmao. After seeing tutorial after tutorial of people doing what I'm doing the exact same way I was getting frustrated and feeling rather stupid. I can deal with a seg fault though, happens to the best of us and are often very hard to track down.

Peace.