Funkcja wczytująca .obj i przekazywanie tablic:
void loadobj(char* filename, GLfloat* vertices, GLfloat* normals, GLfloat* textures, GLuint* faces)
{
int vc=0, fc=0, nc=0, tc=0, v=0, n=0, t=0, f=0; // Indeksy tablic
char line[64];
FILE *file;
file = fopen(filename, "r"); // Open file
setvbuf(file, NULL, _IOFBF, 1024*256); // Assume 256 KB buffer
while(!feof(file))
{
fgets(line, 64, file); // linijka z pliku
if(strstr(line, "v ") == line)
{
++vc;
}
else if(strstr(line, "vn") == line)
{
++nc;
}
else if(strstr(line, "vt") == line)
{
++tc;
}
else if(strstr(line, "f ") == line)
{
++fc;
}
}
fseek(file, 0, SEEK_SET);
vertices = (GLfloat*)calloc(3*vc, sizeof(GLfloat));
normals = (GLfloat*)calloc(3*nc, sizeof(GLfloat));
textures = (GLfloat*)calloc(3*tc, sizeof(GLfloat));
faces = (GLuint*)calloc(9*fc, sizeof(GLuint));
while(!feof(file))
{
fgets(line, 64, file);
if(strstr(line, "v ") == line) // wierzchołki
{
sscanf(line+2, "%f %f %f", &vertices[v], &vertices[v+1], &vertices[v+2]);
vertices[v] /= 10000;
vertices[v+1] /= 10000;
vertices[v+2] /= 10000;
v+=3;
}
else if(strstr(line, "vn") == line) // normalne
{
sscanf(line+2, "%f %f %f", &normals[n], &normals[n+1], &normals[n+2]);
n+=3;
}
else if(strstr(line, "vt") == line) // współrzędne tekstur
{
sscanf(line+2, "%f %f %f", &textures[t], &textures[t+1], &textures[t+2]);
t+=3;
}
else if(strstr(line, "f ") == line) // figury (numery wierzchołków, normalnych, tekstur)
{
sscanf(line+2, "%u/%u/%u %u/%u/%u %u/%u/%u", &faces[f], &faces[f+3], &faces[f+6], &faces[f+1], &faces[f+4], &faces[f+7], &faces[f+2], &faces[f+5], &faces[f+8]);
f+=9; // format: v1/n1/t1 v2/n2/t2 v3/n3/t3
}
}
fclose(file);
}
// To nasze tablice
GLfloat *V, *N, *T;
GLuint *F;
// Tutaj wczytujemy plik do tablic
void init()
{
loadobj("plik.obj", V, N, T, F);
}
// A tu wyświetlamy
void render(void)
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 1, V);
glNormalPointer(3, GL_FLOAT, N);
glTexCoordPointer(3, GL_FLOAT, 1, T);
glDrawElements(GL_TRIANGLES, sizeof(F)/sizeof(int)/9, GL_UNSIGNED_INT, F);
glDisableClientState(GL_VERTEX_ARRAY); // to już nie wykonuje się
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
Niestety, nie ma żadnego śladu po obiekcie. Nawet ustawienie kolorów nic nie daje. Czy da się to w ogóle zrobić tak, jak powyżej? Jaka jest najlepszy i najbardziej wydajny sposób, żeby wyświetlić obiekt składający się z wielu wierzchołków?