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?