PDA

View Full Version : OBJ Loader for OpenGL ES 1.5



pericus
10-26-2010, 11:13 AM
Hello

I am writing an OBJ loader for OpenGL ES. What am I doing worng? loadModel is called once, while drawModel is called 25 times per second.

bool SFModel::loadModel()
{

...
parsing obj data
...

// Load textures
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
texture = (GLuint*)malloc(sizeof(GLuint)*materials.count());
glGenTextures(materials.count(), texture);

for (int i=0; i<materials.count(); i++)
{
QString materialFile = "data/" + materials[i].remove(0,1);
QImage image;
if (image.load(materialFile, "PNG"))
{
QImage matImage = QGLWidget::convertToGLFormat( image );
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexImage2D( GL_TEXTURE_2D, 0, 3,
matImage.width(), matImage.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, matImage.bits() );
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else {
qDebug("Cannot load image from file %s", materialFile.toAscii().data());
}
}
// Define vertices, normals and textcoords

glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, textureVertices);

return true;
}

void SFModel::drawModel()
{
glPushMatrix();
glLoadIdentity();

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// Draw faces
for (uint i = 0; i < numFaces; i++)
{
glBindTexture( GL_TEXTURE_2D, texture[faces[i].material] );
glNormal3f( normals[faces[i].nindices[0]-1].x(),
normals[faces[i].nindices[0]-1].y(),
normals[faces[i].nindices[0]-1].z() );
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT,
faces[i].vindices);
}

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

glPopMatrix();
}

Thank you very much

carsten neumann
10-26-2010, 01:47 PM
I am writing an OBJ loader for OpenGL ES. What am I doing worng?


I don't know what might be wrong, because you don't say what the problem is ;)

PS: please use
around source code snippets.

pericus
10-27-2010, 04:51 AM
The problem is that the first image aparently shows correctly, but the "world" doesn't move. This code is for a car simulator, we are moving the camera with gluLookAt and gluPerspective. The part of the code with gluLookAt and gluPerspective works perfectly with GLM, which is a library for loading OBJs, but GLM doesn't compile on OpenGLES. That's why we are developing this OBJ loader.

carsten neumann
10-27-2010, 07:05 AM
void SFModel::drawModel()
{
glPushMatrix();
glLoadIdentity();


If the modelview matrix is active here you set it to identity for drawing the object, any camera setup from gluLookAt is undone.

I'd be surprised if the problem is in the model loading code, that should not have an effect on camera movement.

pericus
10-28-2010, 12:41 AM
It shows nothing (only a completely blue window):



bool SFModel::loadModel()
{
...
parsing obj data
...
// Load textures
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
texture = (GLuint*) malloc(sizeof(GLuint) * materials.count());
glGenTextures(materials.count(), texture);

for (int i=0; i<materials.count(); i++)
{
QString materialFile = "data/" + materials[i].remove(0,1);
qDebug("Loading material file: %s", materialFile.toAscii().data());
QImage image;
if (image.load(materialFile, "PNG"))
{
QImage matImage = QGLWidget::convertToGLFormat( image );
qDebug("Width: %d, Height: %d", matImage.width(), matImage.height());
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexImage2D( GL_TEXTURE_2D, 0, 3, matImage.width(), matImage.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, matImage.bits() );
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else {
qDebug("Cannot load image from file %s", materialFile.toAscii().data());
}
}
// Define vertices, normals and textcoords

glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, textureVertices);

return true;
}

void SFModel::drawModel()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// Draw faces
for (uint i = 0; i < numFaces; i++)
{
glBindTexture( GL_TEXTURE_2D, texture[faces[i].material] );
glNormal3f( normals[faces[i].nindices[0]].x(), normals[faces[i].nindices[0]].y(), normals[faces[i].nindices[0]].z() );
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, faces[i].vindices);
}

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}


This code is called from:



void Graphics::paintGL()
{
glPushMatrix();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(fovy, aspect, zNear, zFar);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

...

gluLookAt( x, height + newheight, z,
x + 10 + 1 * sin(angle), newheight + height, z + 10 + 1 * cos(angle),
track->getNormal(x, z).x(), 100.0 * track->getNormal(x, z).y(), track->getNormal(x, z).z());

model->drawModel();

glDisable(GL_LIGHTING);

glPopMatrix();

swapBuffers();
glEnable(GL_LIGHTING);
}


Thank you very much for your help and time.

carsten neumann
10-28-2010, 07:58 AM
hm, are you perhaps looking in the wrong direction? It looks a bit as if you are looking down the positive z axis and if z > 0 and the model is in the origin you are not going to see it.

Basically your gluLookAt call boils down to:



gluLookAt(x, y, z,
x + 10, y, z + 10,
upx, upy, upz);


The sin/cos should not matter much, as that simply adds a value in [-1, 1].

Try placing your camera at say (0, 0, 100) looking at (0, 0, 0):



gluLookAt(0, 0, 100,
0, 0, 0,
0, 1, 0 )


Depending on the size of your model you may need to make the 100 larger or smaller to see it well.

pericus
10-28-2010, 09:23 AM
Thanks, you are right. I can see the model. Now I am fighting against gluLookAt in order to look from and to the correct point. Again, thank you very much!