Jump to content
  • Advertisement
Sign in to follow this  
cpatuzzo

OpenGL glm - displaying vertices, but no textures

This topic is 2883 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey there,

I can successfully load objects into OpenGL using this code:

//Loading the model
GLMModel* model;
model=glmReadOBJ("glm-data/f-16.obj");
glmVertexNormals(model,180.0,false);//Optional-recalculates and smooths the normals

//Drawing the model
glPushMatrix();
//transformations here...
glmDraw(model,GLM_SMOOTH|GLM_TEXTURE|GLM_MATERIAL);
glPopMatrix();



However, textures are not loading - all objects are shaded white. The object I am trying to load contains a line for material loading and that is in the same folder.

I am using glm and the object & texture data from here.

Am I missing something like glEnable(GL_TEXTURES), or along those lines? I can provide the source for my initialisation function if needed. I'd rather not have to write my own texture loader.

I am using OpenGL 2.0 and SDL 1.2 running on Ubuntu 10.10 x86 (32-bit).

Many thanks,
Chris Patuzzo

Share this post


Link to post
Share on other sites
Advertisement

/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file.
* Returns a pointer to the created object which should be free'd with
* glmDelete().
*
* filename - name of the file containing the Wavefront .OBJ format data.
*/

GLMmodel*
glmReadOBJ(const char* filename)
{
GLMmodel* model;
FILE* file;
int i, j;

/* open the file */
file = fopen(filename, "r");
if (!file) {
__glmFatalError( "glmReadOBJ() failed: can't open data file \"%s\".",
filename);
}

/* allocate a new model */
model = (GLMmodel*)malloc(sizeof(GLMmodel));
model->pathname = __glmStrdup(filename);
model->mtllibname = NULL;
model->numvertices = 0;
model->vertices = NULL;
model->numnormals = 0;
model->normals = NULL;
model->numtexcoords = 0;
model->texcoords = NULL;
model->numfacetnorms = 0;
model->facetnorms = NULL;
model->numtriangles = 0;
model->triangles = NULL;
model->nummaterials = 0;
model->materials = NULL;
model->numtextures = 0;
model->textures = NULL;
model->numgroups = 0;
model->groups = NULL;
model->position[0] = 0.0;
model->position[1] = 0.0;
model->position[2] = 0.0;

/* make a first pass through the file to get a count of the number
of vertices, normals, texcoords & triangles */

glmFirstPass(model, file);

/* allocate memory */
model->vertices = (GLfloat*)malloc(sizeof(GLfloat) *
3 * (model->numvertices + 1));
model->triangles = (GLMtriangle*)malloc(sizeof(GLMtriangle) *
model->numtriangles);
if (model->numnormals) {
model->normals = (GLfloat*)malloc(sizeof(GLfloat) *
3 * (model->numnormals + 1));
}
if (model->numtexcoords) {
model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) *
2 * (model->numtexcoords + 1));
}

/* rewind to beginning of file and read in the data this pass */
rewind(file);

glmSecondPass(model, file);

/* facet normals are not in the file, we have to compute them anyway */
glmFacetNormals(model);

/* verify the indices */
for (i = 0; i < model->numtriangles; i++) {
if (T(i).findex != -1)
if (T(i).findex <= 0 || T(i).findex > model->numfacetnorms)
__glmFatalError("facet index for triangle %d out of bounds (%d > %d)\n", i, T(i).findex, model->numfacetnorms);
for (j=0; j<3; j++) {
if (T(i).nindices[j] != -1)
if (T(i).nindices[j] <= 0 || T(i).nindices[j] > model->numnormals)
__glmFatalError("normal index for triangle %d out of bounds (%d > %d)\n", i, T(i).nindices[j], model->numnormals);
if (T(i).vindices[j] != -1)
if (T(i).vindices[j] <= 0 || T(i).vindices[j] > model->numvertices)
__glmFatalError("vertex index for triangle %d out of bounds (%d > %d)\n", i, T(i).vindices[j], model->numvertices);
}
}

/* close the file */
fclose(file);

return model;
}

Share this post


Link to post
Share on other sites
I really appreciate the help so far, thanks.

I have just noticed that my alias to compile and run my opengl was suppressing error output. I'm constantly getting this error:

GLM: Warning: glmDraw() warning: texture render mode requested with no texture coordinates defined.





The object I am trying to load does seem to have a texture though:

# Mon Jun 17 10:04:54 1996
#
#

mtllib f-16.mtl

g
v -1.896410 3.055388 0.729943
v -1.912970 2.997458 0.729941
v -1.896410 2.994088 0.729943
...





And here's the code for the f-16.mtl file, in the same folder (which has standard 644 access)

newmtl glass
Ka 0.4000 0.4000 0.4000
Kd 0.3000 0.2302 0.2302
Ks 0.3000 0.3000 0.3000
illum 2
d 0.2100
Ns 117.0500


newmtl gray
Ka 0.4000 0.4000 0.4000
Kd 0.3000 0.2302 0.2302
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000


newmtl red
Ka 0.4000 0.4000 0.4000
Kd 0.3000 0.0343 0.0343
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000


newmtl blue
Ka 0.4000 0.4000 0.4000
Kd 0.0343 0.1861 0.3000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000


newmtl black
Ka 0.4000 0.4000 0.4000
Kd 0.0019 0.0101 0.0163
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000





First pass is defined as:

/* glmFirstPass: first pass at a Wavefront OBJ file that gets all the
* statistics of the model (such as #vertices, #normals, etc)
*
* model - properly initialized GLMmodel structure
* file - (fopen'd) file descriptor
*/

static GLvoid
glmFirstPass(GLMmodel* model, FILE* file)
{
GLuint numvertices; /* number of vertices in model */
GLuint numnormals; /* number of normals in model */
GLuint numtexcoords; /* number of texcoords in model */
GLuint numtriangles; /* number of triangles in model */
GLMgroup* group; /* current group */
unsigned v, n, t;
char buf[128];

/* make a default group */
group = glmAddGroup(model, "default");

numvertices = numnormals = numtexcoords = numtriangles = 0;
while(fscanf(file, "%s", buf) != EOF) {
switch(buf[0]) {
case '#': /* comment */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
case 'v': /* v, vn, vt */
switch(buf[1]) {
case '\0': /* vertex */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
numvertices++;
break;
case 'n': /* normal */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
numnormals++;
break;
case 't': /* texcoord */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
numtexcoords++;
break;
default:
__glmFatalError("glmFirstPass(): Unknown token \"%s\".", buf);
break;
}
break;
case 'm':
if(strncmp(buf, "mtllib", 6) != 0)
__glmFatalError("glmReadOBJ: Got \"%s\" instead of \"mtllib\"", buf);
fgets(buf, sizeof(buf), file);
sscanf(buf, "%s %s", buf, buf);
model->mtllibname = __glmStrStrip((char*)buf);
glmReadMTL(model, model->mtllibname);
break;
case 'u':
if(strncmp(buf, "usemtl", 6) != 0)
__glmFatalError("glmReadOBJ: Got \"%s\" instead of \"usemtl\"", buf);
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
case 'g': /* group */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
#if SINGLE_STRING_GROUP_NAMES
sscanf(buf, "%s", buf);
#else
buf[strlen(buf)-1] = '\0'; /* nuke '\n' */
#endif
group = glmAddGroup(model, buf);
break;
case 'f': /* face */
v = n = t = 0;
fscanf(file, "%s", buf);
/* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */
if (strstr(buf, "//")) {
/* v//n */
sscanf(buf, "%d//%d", &v, &n);
fscanf(file, "%d//%d", &v, &n);
fscanf(file, "%d//%d", &v, &n);
numtriangles++;
group->numtriangles++;
while(fscanf(file, "%d//%d", &v, &n) > 0) {
numtriangles++;
group->numtriangles++;
}
} else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) {
/* v/t/n */
fscanf(file, "%d/%d/%d", &v, &t, &n);
fscanf(file, "%d/%d/%d", &v, &t, &n);
numtriangles++;
group->numtriangles++;
while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) {
numtriangles++;
group->numtriangles++;
}
} else if (sscanf(buf, "%d/%d", &v, &t) == 2) {
/* v/t */
fscanf(file, "%d/%d", &v, &t);
fscanf(file, "%d/%d", &v, &t);
numtriangles++;
group->numtriangles++;
while(fscanf(file, "%d/%d", &v, &t) > 0) {
numtriangles++;
group->numtriangles++;
}
} else {
/* v */
fscanf(file, "%d", &v);
fscanf(file, "%d", &v);
numtriangles++;
group->numtriangles++;
while(fscanf(file, "%d", &v) > 0) {
numtriangles++;
group->numtriangles++;
}
}
break;

default:
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
}
}

/* set the stats in the model structure */
model->numvertices = numvertices;
model->numnormals = numnormals;
model->numtexcoords = numtexcoords;
model->numtriangles = numtriangles;

/* allocate memory for the triangles in each group */
group = model->groups;
while(group) {
group->triangles = (GLuint*)malloc(sizeof(GLuint) * group->numtriangles);
group->numtriangles = 0;
group = group->next;
}
}





Second pass is defined as:

/* glmSecondPass: second pass at a Wavefront OBJ file that gets all
* the data.
*
* model - properly initialized GLMmodel structure
* file - (fopen'd) file descriptor
*/

static GLvoid
glmSecondPass(GLMmodel* model, FILE* file)
{
GLuint numvertices; /* number of vertices in model */
GLuint numnormals; /* number of normals in model */
GLuint numtexcoords; /* number of texcoords in model */
GLuint numtriangles; /* number of triangles in model */
GLfloat* vertices; /* array of vertices */
GLfloat* normals; /* array of normals */
GLfloat* texcoords; /* array of texture coordinates */
GLMgroup* group; /* current group pointer */
GLuint material; /* current material */
unsigned int v, n, t;
char buf[128];

/* set the pointer shortcuts */
vertices = model->vertices;
normals = model->normals;
texcoords = model->texcoords;
group = model->groups;

/* on the second pass through the file, read all the data into the
allocated arrays */

numvertices = numnormals = numtexcoords = 1;
numtriangles = 0;
material = 0;
while(fscanf(file, "%s", buf) != EOF) {
switch(buf[0]) {
case '#': /* comment */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
case 'v': /* v, vn, vt */
switch(buf[1]) {
case '\0': /* vertex */
fscanf(file, "%f %f %f",
&vertices[3 * numvertices + 0],
&vertices[3 * numvertices + 1],
&vertices[3 * numvertices + 2]);
numvertices++;
break;
case 'n': /* normal */
fscanf(file, "%f %f %f",
&normals[3 * numnormals + 0],
&normals[3 * numnormals + 1],
&normals[3 * numnormals + 2]);
numnormals++;
break;
case 't': /* texcoord */
fscanf(file, "%f %f",
&texcoords[2 * numtexcoords + 0],
&texcoords[2 * numtexcoords + 1]);
numtexcoords++;
break;
}
break;
case 'u':
fgets(buf, sizeof(buf), file);
sscanf(buf, "%s %s", buf, buf);
material = glmFindMaterial(model, buf);
#ifdef MATERIAL_BY_FACE
if(!group->material && group->numtriangles)
group->material = material;
#else
group->material = material;
#endif
break;
case 'g': /* group */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
#if SINGLE_STRING_GROUP_NAMES
sscanf(buf, "%s", buf);
#else
buf[strlen(buf)-1] = '\0'; /* nuke '\n' */
#endif
group = glmFindGroup(model, buf);
#ifndef MATERIAL_BY_FACE
group->material = material;
#endif
break;
case 'f': /* face */
v = n = t = 0;
T(numtriangles).findex = -1;
#ifdef MATERIAL_BY_FACE
if(group->material == 0)
group->material = material;
T(numtriangles).material = material;
#endif
fscanf(file, "%s", buf);
/* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */
if (strstr(buf, "//")) {
/* v//n */
sscanf(buf, "%u//%u", &v, &n);
T(numtriangles).vindices[0] = v;
T(numtriangles).tindices[0] = -1;
T(numtriangles).nindices[0] = n;
fscanf(file, "%u//%u", &v, &n);
T(numtriangles).vindices[1] = v;
T(numtriangles).tindices[1] = -1;
T(numtriangles).nindices[1] = n;
fscanf(file, "%u//%u", &v, &n);
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = -1;
T(numtriangles).nindices[2] = n;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
while(fscanf(file, "%u//%u", &v, &n) > 0) {
#ifdef MATERIAL_BY_FACE
T(numtriangles).material = material;
#endif
T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0];
T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0];
T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2];
T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2];
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = -1;
T(numtriangles).nindices[2] = n;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
}
} else if (sscanf(buf, "%u/%u/%u", &v, &t, &n) == 3) {
/* v/t/n */
T(numtriangles).vindices[0] = v;
T(numtriangles).tindices[0] = t;
T(numtriangles).nindices[0] = n;
fscanf(file, "%u/%u/%u", &v, &t, &n);
T(numtriangles).vindices[1] = v;
T(numtriangles).tindices[1] = t;
T(numtriangles).nindices[1] = n;
fscanf(file, "%u/%u/%u", &v, &t, &n);
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = t;
T(numtriangles).nindices[2] = n;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
while(fscanf(file, "%u/%u/%u", &v, &t, &n) > 0) {
#ifdef MATERIAL_BY_FACE
T(numtriangles).material = material;
#endif
T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0];
T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0];
T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2];
T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2];
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = t;
T(numtriangles).nindices[2] = n;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
}
} else if (sscanf(buf, "%u/%u", &v, &t) == 2) {
/* v/t */
T(numtriangles).vindices[0] = v;
T(numtriangles).tindices[0] = t;
T(numtriangles).nindices[0] = -1;
fscanf(file, "%u/%u", &v, &t);
T(numtriangles).vindices[1] = v;
T(numtriangles).tindices[1] = t;
T(numtriangles).nindices[1] = -1;
fscanf(file, "%u/%u", &v, &t);
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = t;
T(numtriangles).nindices[2] = -1;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
while(fscanf(file, "%u/%u", &v, &t) > 0) {
#ifdef MATERIAL_BY_FACE
T(numtriangles).material = material;
#endif
T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0];
T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0];
T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2];
T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2];
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = t;
T(numtriangles).nindices[2] = -1;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
}
} else {
/* v */
sscanf(buf, "%u", &v);
T(numtriangles).vindices[0] = v;
T(numtriangles).tindices[0] = -1;
T(numtriangles).nindices[0] = -1;
fscanf(file, "%u", &v);
T(numtriangles).vindices[1] = v;
T(numtriangles).tindices[1] = -1;
T(numtriangles).nindices[1] = -1;
fscanf(file, "%u", &v);
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = -1;
T(numtriangles).nindices[2] = -1;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
while(fscanf(file, "%u", &v) > 0) {
#ifdef MATERIAL_BY_FACE
T(numtriangles).material = material;
#endif
T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0];
T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0];
T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2];
T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2];
T(numtriangles).vindices[2] = v;
T(numtriangles).tindices[2] = -1;
T(numtriangles).nindices[2] = -1;
group->triangles[group->numtriangles++] = numtriangles;
numtriangles++;
}
}
break;

default:
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
}
}

#if 0
/* announce the memory requirements */
__glmWarning(" Memory: %d bytes",
numvertices * 3*sizeof(GLfloat) +
numnormals * 3*sizeof(GLfloat) * (numnormals ? 1 : 0) +
numtexcoords * 3*sizeof(GLfloat) * (numtexcoords ? 1 : 0) +
numtriangles * sizeof(GLMtriangle));
#endif
}



Share this post


Link to post
Share on other sites
The error you're getting is pointing you in the right direction. The OBJ file doesn't have any Texture Coordinates specified in it (unless they're in part of the file that you've cropped).

The material doesn't link to a texture either, it provides a number of properties for a material (actually three), which are used in various formulae for light etc.

OpenGL doesn't automatically take care of this yourself, you need to do it. You can't just through a file at OpenGL and expect it to understand what it needs done with it.

You will need to set up the material properties in OpenGL using the information from the OBJ file. The easiest way to do this would be to use Shaders.

Share this post


Link to post
Share on other sites
Ahh thanks, I sorted it. I basically needed to enable lighting and change some images to png's to work with my libraries.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!