[Assimp] Texturierung kaputt
Verfasst: 24.10.2010, 22:41
Hallo Menschen,
ich arbeite seit vorgestern mit Assimp, um Collada-Models in ein OpenGL-Programm zu laden. Die Zielversion ist OpenGL 2.1, allerdings ohne Immediate Mode, deshalb lade ich die von aiMesh bereitgestellten Arrays mit einem zusätzlichen Indexarray in eine Hilfsklasse Mesh, von woaus ich sie dann als Vertex Attribute Data binde. Auch die Shader sollen ohne Fixed Function Pipeline auskommen. Eigentlich funktioniert alles sehr gut, nur texturiert werden die von mir geladenen Models völlig wirr:
Image is gone.
Im Assimp Viewer wird es korrekt texturiert, wie alle anderen Models auch. Für mich sieht es so aus, als wären bei mir die Texturkoordinaten falsch. Da ich aber keinen Fehler in meinem Code erkennen kann (was vielleicht auch daran liegt, dass ich einfach schon zu lange darauf starre), gehe ich davon aus, dass ich irgendwas an dem Umgang Assimps mit Texturkoordinaten falsch verstanden habe. Vorweg: Ich arbeite überhaupt nicht mit Materials - meinem Verständnis nach sind die zum Anzeigen einer Textur nicht nötig.
Die Fehlerbehandlung etc. mal weggelassen, ist das der komplette Code für die Arrays:
Wenn ich mir die Texturkoordinaten ausgeben lasse, kommen recht vernünftige Werte raus:
Zeichnen tu ich die einzelnen Meshes folgendermaßen:
In den Shadern dann entsprechend:
Sieht einer, wo der Fehler liegt? Ich habe mit den Postprocessing-Flags schon ein bisschen rumgespielt, weil ich gelesen habe, dass es da Probleme geben könnte, aber selbst, wenn ich 0 angebe, bleibt das Problem. Deshalb denke ich, dass der Fehler eigentlich nur in dem Teil liegen kann, wo ich die Arrays kopiere, aber ich entdecke keine Flüchtigkeitsfehler durch falsche Indizes oder so. Ist es allgemein der richtige Weg, die Texturkoordinaten direkt aus aiMesh auszulesen? Denn ich kenne auch Formate, die Texturkoordinaten in einem separaten Array speichern und dann zu den Vertices selbst nur einen Index auf dieses Array legen.
Ich würde mich wirklich sehr über Hilfe freuen!
Gruß
mOfl
ich arbeite seit vorgestern mit Assimp, um Collada-Models in ein OpenGL-Programm zu laden. Die Zielversion ist OpenGL 2.1, allerdings ohne Immediate Mode, deshalb lade ich die von aiMesh bereitgestellten Arrays mit einem zusätzlichen Indexarray in eine Hilfsklasse Mesh, von woaus ich sie dann als Vertex Attribute Data binde. Auch die Shader sollen ohne Fixed Function Pipeline auskommen. Eigentlich funktioniert alles sehr gut, nur texturiert werden die von mir geladenen Models völlig wirr:
Image is gone.
Im Assimp Viewer wird es korrekt texturiert, wie alle anderen Models auch. Für mich sieht es so aus, als wären bei mir die Texturkoordinaten falsch. Da ich aber keinen Fehler in meinem Code erkennen kann (was vielleicht auch daran liegt, dass ich einfach schon zu lange darauf starre), gehe ich davon aus, dass ich irgendwas an dem Umgang Assimps mit Texturkoordinaten falsch verstanden habe. Vorweg: Ich arbeite überhaupt nicht mit Materials - meinem Verständnis nach sind die zum Anzeigen einer Textur nicht nötig.
Die Fehlerbehandlung etc. mal weggelassen, ist das der komplette Code für die Arrays:
Code: Alles auswählen
aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT);
scene = aiImportFile("C:\\Users\\Dani\\Desktop\\assimp--1.1.700-sdk\\test\\models\\Collada\\duck.dae", aiProcessPreset_TargetRealtime_MaxQuality);
textures = new GLuint[scene->mNumMaterials];
for (int i = 0; i < (int) scene->mNumMaterials; i++) {
SDL_Surface* tex = SDL_LoadBMP("C:\\Users\\_\\Desktop\\assimp--1.1.700-sdk\\test\\models\\Collada\\duck.bmp");
glGenTextures(1, &textures[i]);
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, tex->w, tex->h, GL_BGR, GL_UNSIGNED_BYTE, tex->pixels);
SDL_FreeSurface(tex);
}
for (int i = 0; i < numMeshes; i++) {
aiMesh* currentMesh = scene->mMeshes[i];
Mesh* newMesh = new Mesh();
meshes.push_back(newMesh);
newMesh->numFaces = currentMesh->mNumFaces;
newMesh->numVertices = currentMesh->mNumVertices;
newMesh->materialIndex = currentMesh->mMaterialIndex;
newMesh->vertices = new glm::vec4[newMesh->numVertices];
newMesh->normals = new glm::vec3[newMesh->numVertices];
newMesh->colors = new glm::vec4[newMesh->numVertices];
newMesh->texCoords = new glm::vec2[newMesh->numVertices];
newMesh->indices = new GLint[newMesh->numFaces * 3];
for (int j = 0; j < newMesh->numVertices; j++) {
newMesh->vertices[j].x = currentMesh->mVertices[j].x;
newMesh->vertices[j].y = currentMesh->mVertices[j].y;
newMesh->vertices[j].z = currentMesh->mVertices[j].z;
newMesh->vertices[j].w = 1.0f;
newMesh->normals[j].x = currentMesh->mNormals[j].x;
newMesh->normals[j].y = currentMesh->mNormals[j].y;
newMesh->normals[j].z = currentMesh->mNormals[j].z;
newMesh->colors[j].r = currentMesh->mColors[j]->r;
newMesh->colors[j].g = currentMesh->mColors[j]->g;
newMesh->colors[j].b = currentMesh->mColors[j]->b;
newMesh->colors[j].a = currentMesh->mColors[j]->a;
if (currentMesh->mTextureCoords[0][j] != NULL) {
newMesh->texCoords[j].x = currentMesh->mTextureCoords[0][j].x;
newMesh->texCoords[j].y = currentMesh->mTextureCoords[0][j].y;
}
}
for (int j = 0; j < newMesh->numFaces; j++) {
newMesh->indices[j * 3] = currentMesh->mFaces[j].mIndices[0];
newMesh->indices[j * 3 + 1] = currentMesh->mFaces[j].mIndices[1];
newMesh->indices[j * 3 + 2] = currentMesh->mFaces[j].mIndices[2];
}
}
Code: Alles auswählen
0.544365, 0.975068
0.274953, 0.941360
0.412382, 0.948959
0.078614, 0.893197
0.159929, 0.926191
0.045546, 0.712112
0.029763, 0.775258
0.174568, 0.589926
0.093871, 0.647648
...
Code: Alles auswählen
for (int i = 0; i < (int) numMeshes; i++) {
Mesh* mesh = meshes.at(i);
glEnableVertexAttribArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, mesh->vertices);
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, 0, mesh->normals);
glEnableVertexAttribArray(texCoordLocation);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, mesh->texCoords);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[mesh->materialIndex]);
glUniform1i(textureLocation, 0);
glDrawElements(GL_TRIANGLES, mesh->numFaces * 3, GL_UNSIGNED_INT, mesh->indices);
}
Code: Alles auswählen
Vertex Shader:
attribute vec2 inTexCoord;
varying vec2 outTexCoord;
void main() {
...
outTexCoord = inTexCoord;
}
Fragment Shader:
uniform sampler2D texture;
varying vec2 outTexCoord;
void main() {
...
gl_FragColor = texture2D(texture, outTexCoord);
}
Ich würde mich wirklich sehr über Hilfe freuen!
Gruß
mOfl