Guest
Rendern von .obj-Dateien mit OpenGL
Post
by Guest » 15 Jan 2025, 15:33
Ich hatte Probleme beim Rendern eines Modells in OpenGL. Ich habe mit glDrawElements meinen eigenen obj-Parser und eine Renderfunktion erstellt, kann das Problem jedoch nicht erkennen. Das ist meine Parser-Funktion:
Code: Select all
void load_obj(char *nom)
{
FILE *file = fopen(nom, "r");
int iv = 0, in = 0, it = 0, ifa = 0;
if(file != NULL)
{
while(1)
{
char lineHeader[128];
int res = fscanf(file, "%s", lineHeader);
if(res == EOF)
break;
if(strcmp(lineHeader, "v") == 0)
{
float vertex[3] = {0,0,0};
fscanf(file, "%f %f %f\n",
&vertex[0], &vertex[1], &vertex[2]);
vertices[iv] = vertex[0];
vertices[iv+1] = vertex[1];
vertices[iv+2] = vertex[2];
iv += 3;
}
else if(strcmp(lineHeader, "vt") == 0)
{
float tex_vert[2] = {0,0};
fscanf(file, "%f %f\n",
&tex_vert[0], &tex_vert[1]);
texturas[it] = tex_vert[0];
texturas[it+1] = tex_vert[1];
it += 2;
}
else if(strcmp(lineHeader, "vn") == 0)
{
float normal[3] = {0,0,0};
fscanf(file, "%f %f %f\n",
&normal[0], &normal[1], &normal[2]);
normales[in] = normal[0];
normales[in+1] = normal[1];
normales[in+2] = normal[2];
in += 3;
}
else if(strcmp(lineHeader, "f") == 0)
{
unsigned int vertexIndex[9] = {0,0,0,0,0,0,0,0,0};
fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &vertexIndex[1], &vertexIndex[2],
&vertexIndex[3], &vertexIndex[4], &vertexIndex[5],
&vertexIndex[6], &vertexIndex[7], &vertexIndex[8]);
vertTriangulos[ifa] = vertexIndex[0];
vertTriangulos[ifa+1] = vertexIndex[1];
vertTriangulos[ifa+2] = vertexIndex[2];
vertTriangulos[ifa+3] = vertexIndex[3];
vertTriangulos[ifa+4] = vertexIndex[4];
vertTriangulos[ifa+5] = vertexIndex[5];
vertTriangulos[ifa+6] = vertexIndex[6];
vertTriangulos[ifa+7] = vertexIndex[7];
vertTriangulos[ifa+8] = vertexIndex[8];
ifa += 9;
nTriangulos++;
}
}
}
Und das ist meine Zeichenfunktion:
Code: Select all
void draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturas);
glNormalPointer(GL_FLOAT, 0, normales);
glDrawElements(GL_TRIANGLES, nTriangulos*9, GL_UNSIGNED_INT, vertTriangulos);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
Die Variablen sind:
Code: Select all
long nTriangulos;
float *vertices, *normales, *texturas;
unsigned int *vertTriangulos;
Die OBJ-Datei, die ich verwende, ist ein einfacher Würfel, aber das Netz, das ich rendere, ist eine völlige Katastrophe.
BEARBEITEN:
Ich habe meinen Code geändert und jetzt sieht der Parser so aus:
Code: Select all
if(strcmp(lineHeader, "f") == 0)
{
unsigned int vertexIndex[9] = {0,0,0,0,0,0,0,0,0};
fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &vertexIndex[1], &vertexIndex[2],
&vertexIndex[3], &vertexIndex[4], &vertexIndex[5],
&vertexIndex[6], &vertexIndex[7], &vertexIndex[8]);
for(int i = 0; i < 9; i += 3)
{
bool cierto = true;
int pos = 0;
if(indexbuff.size() > 0)
{
for(int i = 0; i < registro.size(); i++)
{
if(vertexIndex[0] == registro[i].in1
&& vertexIndex[1] == registro[i].in2
&& vertexIndex[2] == registro[i].in3)
{
cierto = false;
pos = i;
}
}
}
if(cierto)
{
verticebuff.push_back(vertices[vertexIndex[i]]);
verticebuff.push_back(vertices[vertexIndex[i]+1]);
verticebuff.push_back(vertices[vertexIndex[i]+2]);
textbuff.push_back(texturas[vertexIndex[i+1]]);
textbuff.push_back(texturas[vertexIndex[i+1]+1]);
normalbuff.push_back(normales[vertexIndex[i+2]]);
normalbuff.push_back(normales[vertexIndex[i+2]+1]);
normalbuff.push_back(normales[vertexIndex[i+2]+2]);
indexbuff.push_back(verticebuff.size()/3);
index3 indice;
indice.in1 = vertexIndex[i];
indice.in2 = vertexIndex[i+1];
indice.in3 = vertexIndex[i+2];
registro.push_back(indice);
}
else
{
indexbuff.push_back(i);
}
}
}
Aber es scheint nicht richtig zu funktionieren.
1736951636
Guest
Ich hatte Probleme beim Rendern eines Modells in OpenGL. Ich habe mit glDrawElements meinen eigenen obj-Parser und eine Renderfunktion erstellt, kann das Problem jedoch nicht erkennen. Das ist meine Parser-Funktion: [code]void load_obj(char *nom) { FILE *file = fopen(nom, "r"); int iv = 0, in = 0, it = 0, ifa = 0; if(file != NULL) { while(1) { char lineHeader[128]; int res = fscanf(file, "%s", lineHeader); if(res == EOF) break; if(strcmp(lineHeader, "v") == 0) { float vertex[3] = {0,0,0}; fscanf(file, "%f %f %f\n", &vertex[0], &vertex[1], &vertex[2]); vertices[iv] = vertex[0]; vertices[iv+1] = vertex[1]; vertices[iv+2] = vertex[2]; iv += 3; } else if(strcmp(lineHeader, "vt") == 0) { float tex_vert[2] = {0,0}; fscanf(file, "%f %f\n", &tex_vert[0], &tex_vert[1]); texturas[it] = tex_vert[0]; texturas[it+1] = tex_vert[1]; it += 2; } else if(strcmp(lineHeader, "vn") == 0) { float normal[3] = {0,0,0}; fscanf(file, "%f %f %f\n", &normal[0], &normal[1], &normal[2]); normales[in] = normal[0]; normales[in+1] = normal[1]; normales[in+2] = normal[2]; in += 3; } else if(strcmp(lineHeader, "f") == 0) { unsigned int vertexIndex[9] = {0,0,0,0,0,0,0,0,0}; fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &vertexIndex[1], &vertexIndex[2], &vertexIndex[3], &vertexIndex[4], &vertexIndex[5], &vertexIndex[6], &vertexIndex[7], &vertexIndex[8]); vertTriangulos[ifa] = vertexIndex[0]; vertTriangulos[ifa+1] = vertexIndex[1]; vertTriangulos[ifa+2] = vertexIndex[2]; vertTriangulos[ifa+3] = vertexIndex[3]; vertTriangulos[ifa+4] = vertexIndex[4]; vertTriangulos[ifa+5] = vertexIndex[5]; vertTriangulos[ifa+6] = vertexIndex[6]; vertTriangulos[ifa+7] = vertexIndex[7]; vertTriangulos[ifa+8] = vertexIndex[8]; ifa += 9; nTriangulos++; } } } [/code] Und das ist meine Zeichenfunktion: [code]void draw() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertices); glTexCoordPointer(2, GL_FLOAT, 0, texturas); glNormalPointer(GL_FLOAT, 0, normales); glDrawElements(GL_TRIANGLES, nTriangulos*9, GL_UNSIGNED_INT, vertTriangulos); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); } [/code] Die Variablen sind: [code] long nTriangulos; float *vertices, *normales, *texturas; unsigned int *vertTriangulos; [/code] Die OBJ-Datei, die ich verwende, ist ein einfacher Würfel, aber das Netz, das ich rendere, ist eine völlige Katastrophe. [b]BEARBEITEN:[/b] Ich habe meinen Code geändert und jetzt sieht der Parser so aus: [code] if(strcmp(lineHeader, "f") == 0) { unsigned int vertexIndex[9] = {0,0,0,0,0,0,0,0,0}; fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &vertexIndex[1], &vertexIndex[2], &vertexIndex[3], &vertexIndex[4], &vertexIndex[5], &vertexIndex[6], &vertexIndex[7], &vertexIndex[8]); for(int i = 0; i < 9; i += 3) { bool cierto = true; int pos = 0; if(indexbuff.size() > 0) { for(int i = 0; i < registro.size(); i++) { if(vertexIndex[0] == registro[i].in1 && vertexIndex[1] == registro[i].in2 && vertexIndex[2] == registro[i].in3) { cierto = false; pos = i; } } } if(cierto) { verticebuff.push_back(vertices[vertexIndex[i]]); verticebuff.push_back(vertices[vertexIndex[i]+1]); verticebuff.push_back(vertices[vertexIndex[i]+2]); textbuff.push_back(texturas[vertexIndex[i+1]]); textbuff.push_back(texturas[vertexIndex[i+1]+1]); normalbuff.push_back(normales[vertexIndex[i+2]]); normalbuff.push_back(normales[vertexIndex[i+2]+1]); normalbuff.push_back(normales[vertexIndex[i+2]+2]); indexbuff.push_back(verticebuff.size()/3); index3 indice; indice.in1 = vertexIndex[i]; indice.in2 = vertexIndex[i+1]; indice.in3 = vertexIndex[i+2]; registro.push_back(indice); } else { indexbuff.push_back(i); } } } [/code] Aber es scheint nicht richtig zu funktionieren.