Messed up VBO model loading code through lib3ds

I created a simple 3DSMax object of two spheres to test the lib3ds library, this is how it looks:

I struggled to find resources for how to load a lib3ds file into a VBO for OpenGL but I eventually managed to conjure up the following code:

model.h:

#include <stdlib.h>
#include <string.h>
#include <gl/gl.h>
#include "../lib/lib3ds/lib3ds.h"

typedef struct {
	Lib3dsFile *file;
	unsigned int faceCount;
	GLuint vertices;
	GLuint normalVertices;
} TModel;

extern TModel playerModel;

short loadModel(TModel *model, char *filename);

model.c:

#include <gl/gl.h>
#include "../lib/glext.h"

#include "model.h"

#include "init.h"

TModel playerModel;

short loadModel(TModel *model, char *filename) {
	model->file = (Lib3dsFile*)lib3ds_file_open(filename);
	if(!model->file) return 0;
	
	{
		unsigned int i;
		for(i = 0; i < model->file->nmeshes; i++) {
			model->faceCount += model->file->meshes[i]->nfaces;
		}
	}
	
	{
		size_t malloced = 0;
		
		float (*vertices)[3];
		float (*normals)[3];
		
		vertices = (float(*)[3])malloc(sizeof(float) * 9 * model->faceCount);
		if(vertices == NULL) return 0;
		
		normals = (float(*)[3])malloc(sizeof(float) * 9 * model->faceCount);
		if(normals == NULL) return 0;
		
		unsigned int i, j;
		for(i = 0; i < model->file->nmeshes; i++) {
			/*float (*vertices)[3];
			vertices = (float(*)[3])malloc(sizeof(float) * 3 * model->file->meshes[i]->nvertices);
			float (*normals)[3];
			normals = (float(*)[3])malloc(sizeof(float) * 9 * model->file->meshes[i]->nfaces);*/
			lib3ds_mesh_calculate_vertex_normals(model->file->meshes[i], normals + malloced / sizeof(float));
			for(j = 0; j < model->file->meshes[i]->nfaces; j++) {
				memcpy(vertices + malloced, model->file->meshes[i]->vertices, sizeof(float) * 3 * model->file->meshes[i]->nvertices);
			}
			malloced += sizeof(float) * 3 * model->file->meshes[i]->nvertices;
		}
		glGenBuffers(1, &model->vertices);
			glBindBuffer(GL_ARRAY_BUFFER, model->vertices);
			glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9 * /* faces */ model->faceCount, vertices, GL_STATIC_DRAW);
			
			glGenBuffers(1, &model->normalVertices);
			glBindBuffer(GL_ARRAY_BUFFER, model->normalVertices);
			glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9 * model->faceCount, normals, GL_STATIC_DRAW);
			
		free(vertices);
		free(normals);
	}
	
	lib3ds_file_free(model->file);
	model->file = NULL;
	
	return 1;
}

Then I load it like this:

loadModel(&playerModel, "models/player.3ds");

Here is the code I use to display it:

glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glBindBuffer(GL_ARRAY_BUFFER, playerModel.normalVertices);
	glNormalPointer(GL_FLOAT, 0, NULL);
	glVertexPointer(3, GL_FLOAT, 0, NULL);
	glDrawArrays(GL_TRIANGLES, 0, playerModel.faceCount * 3);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

And this is how it renders in my application:

Any ideas as to what’s wrong?

At a glance, you’re missing the

glBindBuffer(GL_ARRAY_BUFFER, playerModel.vertices);

Before the glVertexPointer() call. Also the glEnableClientState() calls are not necessary with VBOs, but that shouldn’t break anything.

Thanks for your help. Using this code to draw the object:

glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glBindBuffer(GL_ARRAY_BUFFER, playerModel.normalVertices);
	glNormalPointer(GL_FLOAT, 0, NULL);
	glBindBuffer(GL_ARRAY_BUFFER, playerModel.vertices);
	glVertexPointer(3, GL_FLOAT, 0, NULL);
	glDrawArrays(GL_TRIANGLES, 0, playerModel.faceCount * 3);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

It now looks like this:

So I’m sure it must be something with my loadModel function.

I added a memset 0 to vertices and normals like so:

vertices = (float(*)[3])malloc(sizeof(float) * 9 * model->faceCount);
		if(vertices == NULL) return 0;
		memset(vertices, 0, sizeof(float) * 9 * model->faceCount);
		
		normals = (float(*)[3])malloc(sizeof(float) * 9 * model->faceCount);
		if(normals == NULL) return 0;
		memset(normals, 0, sizeof(float) * 9 * model->faceCount);

Same result as before.

I replaced my previous model with a simple cube, and am getting this:

Maybe I’m missing something, it seems that it’s got the right size, but wrong locations.

  • BUMP *

Is there maybe another forum I should post this on?