2012-03-27 6 views
0

Ich habe versucht, meine eigene grundlegende .obj (Wavefront) -Renderer mit dem OpenGL 3.x Kernprofil zu machen. Ich benutze die OpenGL SuperBible 5. Ausgabe. und die Swiftless Tutorials als Referenzmaterial.OpenGL 3.x .obj Loader mit ADS Phong "veiny-looking" Kugel

Die Geometrie scheint korrekt geladen zu werden, also versuche ich jetzt, ein ADS Phong Beleuchtungsmodell zum Laufen zu bringen, aber etwas ist verrückt, und ich denke, es hat etwas mit meinen OpenGL-Aufrufen zu tun oder auch den Weg Ich lade meine Normalen, aber ich kann nicht herausfinden, wie ich es beheben kann. (Es könnte auch ein anderes Problem sein, da ich kein OpenGL-Experte bin).

Wenn ein einfacher Würfel Rendering, sieht es fast richtig, aber es ist eine seltsame Lichtpunkt auf einer Seite:

picture of cube

Wenn eine Kugel-Rendering, die Beleuchtung zeigt sich mit „Adern“:

picture of sphere

Etwas ist offensichtlich sehr falsch mit meinem Code. Hier sind die Codeabschnitte, von denen ich denke, dass sie relevant sind. Ich werde glücklich sein, mehr/den ganzen Code bei Bedarf zu veröffentlichen ... lass mich wissen, ob ich mehr posten sollte.

Datei: objFileRenderer.cpp

#include "objFileRenderer.hpp" 

namespace def 
{ 

objFileRenderer::objFileRenderer(const char* fileToRender, float objScale) 
{ 
    windowWidth = 800; 
    windowHeight = 600; 
    settings.majorVersion = 3; 
    settings.minorVersion = 1; 
    app = NULL; 
    shader = NULL; 
    vaoID = NULL; 
    vboID = NULL; 
    iboID = NULL; 
    vaoID = new unsigned int[1]; 
    vboID = new unsigned int[3]; 
    iboID = new unsigned int[2]; 
    rotSpeed = 50.0f; 
    rot = 0.0f; 

    initSFML(); 
    initOpenGL(); 

    std::string objFilename(fileToRender); 
    std::vector<float> vertices; 
    std::vector< unsigned short > indices; 
    std::vector<float> normals; 
    std::vector< unsigned short > normalIndices; 

    loadObj(objFilename, vertices, indices, normals, normalIndices); 


    std::vector<float> colorA; 
    std::vector<float> colorD; 
    std::vector<float> colorS; 
    loadMtl(objFilename, colorA, colorD, colorS); 


    float* vertexArray = NULL; 
    int numVertices = 0; 
    unsigned short* indexArray = NULL; 
    int numFaces = 0; 
    vertexArray = vertexVectorToVertexArray(vertices, numVertices); 
    indexArray = indexVectorToIndexArray(indices, numFaces); 

    float* colorArrayA = NULL; 
    float* colorArrayD = NULL; 
    float* colorArrayS = NULL; 
    int numColoredObjects = 0; 
    colorVectorsToColorArrays(colorA, colorD, colorS, colorArrayA, colorArrayD, colorArrayS, numColoredObjects); 

    float* normalArray = NULL; 
    unsigned short* normalIndicesArray = NULL; 
    int numNormals = 0; 
    int numNormalIndices = 0; 
    normalVectorsToNormalArrays(normals, normalIndices, normalArray, normalIndicesArray, numNormals, numNormalIndices); 

    setupScene(); 

    putArraysIntoVAO(vertexArray, numVertices, indexArray, numFaces, normalArray, numNormals, normalIndicesArray, numNormalIndices); 

    mainLoop(numVertices, numFaces, colorArrayA, colorArrayD, colorArrayD, normalArray, objScale); 

    delete [] vertexArray; 
    delete [] indexArray; 
    delete [] colorArrayA; 
    delete [] colorArrayD; 
    delete [] colorArrayS; 
    delete [] normalArray; 
    delete [] normalIndicesArray; 
} 

objFileRenderer::~objFileRenderer() 
{ 
    shutdownSFML(); 
} 

void objFileRenderer::loadObj(std::string& objFilename, std::vector<float>& vertices, std::vector< unsigned short >& indices, std::vector<float>& normals, std::vector< unsigned short >& normalIndices) 
{ 
    std::ifstream objFile(objFilename.c_str()); 

    if (!objFile.is_open()) 
    { 
     std::cerr << "Error: unable to open .obj file: " << objFilename << std::endl; 
     exit(1); 
    } 

    std::string line; 
    while (objFile.good()) 
    { 
     getline(objFile, line); 

     // vertices 
     if (line[0] == 'v' && line[1] == ' ') // if line in .obj file contains vertices 
     { 
      std::vector<std::string> tmpStrVerts; 
      std::string subline; 
      subline = line.substr(2); 

      boost::split(tmpStrVerts, subline, boost::is_any_of("\t ")); 

      std::vector<std::string>::iterator it; 
      for (it = tmpStrVerts.begin(); it != tmpStrVerts.end(); it++) 
      { 
       float vertex; 
       std::stringstream ss; 
       ss << *it; 
       ss >> vertex; 
       vertices.push_back(vertex); 
      } 
     } 

     // normals 
     else if (line[0] == 'v' && line[1] == 'n') 
     { 
      std::vector<std::string> tmpStrNorms; 
      std::string subline; 
      subline = line.substr(3); 

      boost::split(tmpStrNorms, subline, boost::is_any_of("\t ")); 

      std::vector<std::string>::iterator it; 
      for (it = tmpStrNorms.begin(); it != tmpStrNorms.end(); it++) 
      { 
       float normal; 
       std::stringstream ss; 
       ss << *it; 
       ss >> normal; 
       normals.push_back(normal); 
       //std::cout << normal << std::endl; 
      } 
     } 

     // indices and normalIndices 
     else if (line[0] == 'f' && line[1] == ' ') // else if line in .obj file contains indices 
     { 
      std::vector<std::string> tmpStrIndices; 
      std::string subline; 
      subline = line.substr(2); 

      // indices 
      boost::split(tmpStrIndices, subline, boost::is_any_of("\t ")); 

      std::vector<std::string>::iterator it; 
      for (it = tmpStrIndices.begin(); it != tmpStrIndices.end(); it++) 
      { 
       unsigned short index; 
       std::stringstream ss; 
       ss << *it; 
       ss >> index; 
       indices.push_back(index); 
      } 

      // normalIndices 
      boost::split(tmpStrIndices, subline, boost::is_any_of("/")); 

      int count = 0; 
      std::vector<std::string>::iterator it2; 
      for (it2 = tmpStrIndices.begin(); it2 != tmpStrIndices.end(); it2++) 
      { 
       if (count == 2) 
       { 
        unsigned short index; 
        std::stringstream ss; 
        ss << *it2; 
        ss >> index; 
        normalIndices.push_back(index); 
        count = 0; 
       } 
       count++; 
      } 


     } 
    } 
    objFile.close(); 

    return; 
} 

void objFileRenderer::loadMtl(std::string& objFilename, std::vector<float>& colorA, std::vector<float>& colorD, std::vector<float>& colorS) 
{ 
    int extpos = objFilename.find('.'); 
    std::string mtlFilename = objFilename.substr(0, extpos+1) + "mtl"; 

    std::ifstream mtlFile(mtlFilename.c_str()); 

    if (!mtlFile.is_open()) 
    { 
     std::cerr << "Error: unable to open .mtl file: " << mtlFilename << std::endl; 
     exit(1); 
    } 

    std::string line; 
    while (mtlFile.good()) 
    { 
     getline(mtlFile, line); 

     if (line[0] == 'K' && line[1] == 'a') 
     { 
      std::vector<std::string> tmpStrColorA; 
      std::string subline; 
      subline = line.substr(3); 

      boost::split(tmpStrColorA, subline, boost::is_any_of("\t ")); 

      std::vector<std::string>::iterator it; 
      for (it = tmpStrColorA.begin(); it != tmpStrColorA.end(); it++) 
      { 
       float rgbValue; 
       std::stringstream ss; 
       ss << *it; 
       ss >> rgbValue; 
       colorA.push_back(rgbValue); 
      } 
     } 

     if (line[0] == 'K' && line[1] == 'd') 
     { 
      std::vector<std::string> tmpStrColorD; 
      std::string subline; 
      subline = line.substr(3); 

      boost::split(tmpStrColorD, subline, boost::is_any_of("\t ")); 

      std::vector<std::string>::iterator it; 
      for (it = tmpStrColorD.begin(); it != tmpStrColorD.end(); it++) 
      { 
       float rgbValue; 
       std::stringstream ss; 
       ss << *it; 
       ss >> rgbValue; 
       colorD.push_back(rgbValue); 
      } 
     } 

     if (line[0] == 'K' && line[1] == 's') 
     { 
      std::vector<std::string> tmpStrColorS; 
      std::string subline; 
      subline = line.substr(3); 

      boost::split(tmpStrColorS, subline, boost::is_any_of("\t ")); 

      std::vector<std::string>::iterator it; 
      for (it = tmpStrColorS.begin(); it != tmpStrColorS.end(); it++) 
      { 
       float rgbValue; 
       std::stringstream ss; 
       ss << *it; 
       ss >> rgbValue; 
       colorS.push_back(rgbValue); 
      } 
     } 

    } 
    mtlFile.close(); 

    return; 
} 

float* objFileRenderer::vertexVectorToVertexArray(std::vector<float>& vertices, int& numVertices) 
{ 
    numVertices = vertices.size()/3; 
    float* vertexArray = NULL; 
    vertexArray = new float[vertices.size()]; 

    for (unsigned int i = 0; i < vertices.size(); i++) 
    { 
     vertexArray[i] = vertices[i]; 
    } 

    return vertexArray; 
} 

unsigned short* objFileRenderer::indexVectorToIndexArray(std::vector< unsigned short >& indices, int& numFaces) 
{ 
    numFaces = indices.size()/3; 
    unsigned short* indexArray = NULL; 
    indexArray = new unsigned short[indices.size()]; 

    for (unsigned int i = 0; i < indices.size(); i++) 
    { 
     indexArray[i] = indices[i]-1; 
    } 

    return indexArray; 
} 

void objFileRenderer::colorVectorsToColorArrays(std::vector<float>& colorA, std::vector<float>& colorD, std::vector<float>& colorS, float*& colorArrayA, float*& colorArrayD, float*& colorArrayS, int& numColoredObjects) 
{ 
    numColoredObjects = colorA.size()/3; 

    colorArrayA = new float[numColoredObjects*3]; 
    colorArrayD = new float[numColoredObjects*3]; 
    colorArrayS = new float[numColoredObjects*3]; 

    for (int i = 0; i < numColoredObjects; i+=3) 
    { 
     colorArrayA[i] = colorA[i]; colorArrayA[i+1] = colorA[i+1]; colorArrayA[i+2] = colorA[i+2]; 
     colorArrayD[i] = colorD[i]; colorArrayD[i+1] = colorD[i+1]; colorArrayD[i+2] = colorD[i+2]; 
     colorArrayS[i] = colorS[i]; colorArrayS[i+1] = colorS[i+1]; colorArrayS[i+2] = colorS[i+2]; 
    } 

    return; 
} 

void objFileRenderer::normalVectorsToNormalArrays(std::vector<float>& normals, std::vector< unsigned short >& normalIndices, float*& normalArray, unsigned short*& normalIndicesArray, int& numNormals, int& numNormalIndices) 
{ 
    numNormals = normals.size()/3; 
    numNormalIndices = normalIndices.size(); 

    normalArray = new float[numNormalIndices]; 
    normalIndicesArray = new unsigned short[numNormalIndices]; 

    for (int i = 0; i < numNormalIndices; i+=3) 
    { 
     normalIndicesArray[i] = normalIndices[i]-1; 
     normalIndicesArray[i+1] = normalIndices[i+1]-1; 
     normalIndicesArray[i+2] = normalIndices[i+2]-1; 
    } 

    // load normals in index order 
    for (int i = 0; i < numNormalIndices; i+=3) 
    { 
     int index = normalIndicesArray[i]; 
     normalArray[i] = normals[index]; 
     normalArray[i+1] = normals[index+1]; 
     normalArray[i+2] = normals[index+2]; 
    } 

    return; 
} 

void objFileRenderer::putArraysIntoVAO(float* vertexArray, int& numVertices, unsigned short* indexArray, int& numFaces, float* normalArray, int& numNormals, unsigned short* normalIndicesArray, int& numNormalIndices) 
{ 
    glGenVertexArrays(1, &vaoID[0]); // create our vertex array object 
    glBindVertexArray(vaoID[0]); // bind our vertex array object so we can use it 

    glGenBuffers(2, &iboID[0]); // generate our index buffer object 
    glGenBuffers(2, &vboID[0]); // generate our vertex buffer object 

// normalArray holds normals in index order, so I shouldn't use this 
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID[1]); // bind our normal index buffer object 
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, (numNormalIndices) * sizeof(GLushort), normalIndicesArray, GL_STATIC_DRAW); // set the size and data of our IBO 

    glBindBuffer(GL_ARRAY_BUFFER, vboID[1]); // bind our normal vertex buffer object 
    glBufferData(GL_ARRAY_BUFFER, (numNormalIndices) * sizeof(GLfloat), normalArray, GL_STATIC_DRAW); // set the size and data of our VBO and set it to STATIC_DRAW 
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0); // set up our vertex attributes pointer 
    glEnableVertexAttribArray(1); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID[0]); // bind our index buffer object 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, (numFaces*3) * sizeof(GLushort), indexArray, GL_STATIC_DRAW); // set the size and data of our IBO 

    glBindBuffer(GL_ARRAY_BUFFER, vboID[0]); // bind our vertex buffer object 
    glBufferData(GL_ARRAY_BUFFER, (numVertices*3) * sizeof(GLfloat), vertexArray, GL_STATIC_DRAW); // set the size and data of our VBO and set it to STATIC_DRAW 
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // set up our vertex attributes pointer 
    glEnableVertexAttribArray(0); 

    glBindVertexArray(0); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

    return; 
} 

void objFileRenderer::setupScene() 
{ 
    app->setFramerateLimit(60); // max 60 FPS 

    glClearColor(0.4f, 0.6f, 0.9f, 0.0f); 
    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LEQUAL); 
    glEnable(GL_CULL_FACE); 

    shader = new Shader("shader.vert", "shader.frag"); 
    projectionMatrix = glm::perspective(60.0f, (float)windowWidth/(float)windowHeight, 0.1f, 100.0f); 

    return; 
} 

void objFileRenderer::renderScene(int& numVertices, int& numFaces, float*& colorArrayA, float*& colorArrayD, float*& colorArrayS, float*& normalArray, float objScale) 
{ 
    sf::Time elapsedTime = clock.getElapsedTime(); 
    clock.restart(); 

    if (rot > 360.0f) 
     rot = 0.0f; 
    rot += rotSpeed * elapsedTime.asSeconds(); 

    float lightPosition[3] = { -100.0, -100.0, 100.0 }; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -3.0f, -10.0f)); // move back by 5 units 
    modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(objScale)); // change last arg to 0.5f to shrink model by half 
    modelMatrix *= glm::rotate<float>(glm::mat4(1.0f), rot, glm::vec3(0, 1, 0)); 

    shader->bind(); 

    int projectionMatrixLocation = glGetUniformLocation(shader->id(), "projectionMatrix"); 
    int viewMatrixLocation   = glGetUniformLocation(shader->id(), "viewMatrix"); 
    int modelMatrixLocation   = glGetUniformLocation(shader->id(), "modelMatrix"); 
    int ambientLocation    = glGetUniformLocation(shader->id(), "ambientColor"); 
    int diffuseLocation    = glGetUniformLocation(shader->id(), "diffuseColor"); 
    int specularLocation   = glGetUniformLocation(shader->id(), "specularColor"); 
    int lightPositionLocation  = glGetUniformLocation(shader->id(), "lightPosition"); 
    int normalMatrixLocation  = glGetUniformLocation(shader->id(), "normalMatrix"); 

    glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]); 
    glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]); 
    glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]); 
    glUniform3fv(ambientLocation, 1, colorArrayA); 
    glUniform3fv(diffuseLocation, 1, colorArrayD); 
    glUniform3fv(specularLocation, 1, colorArrayS); 
    glUniform3fv(lightPositionLocation, 1, lightPosition); 
    glUniformMatrix3fv(normalMatrixLocation, 1, GL_FALSE, normalArray); 


    glBindVertexArray(vaoID[0]); 

    glDrawRangeElements(GL_TRIANGLES, 0, numFaces*3, numFaces*3, GL_UNSIGNED_SHORT, NULL); 

    glBindVertexArray(0); 

    shader->unbind(); 

    app->display(); 

    return; 
} 

void objFileRenderer::handleEvents() 
{ 
    sf::Event event; 

    while (app->pollEvent(event)) 
    { 
     if (event.type == sf::Event::Closed) 
     { 
      app->close(); 
     } 

     if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)) 
     { 
      app->close(); 
     } 

     if (event.type == sf::Event::Resized) 
     { 
      glViewport(0, 0, event.size.width, event.size.height); 
     } 
    } 

    return; 
} 

void objFileRenderer::mainLoop(int& numVertices, int& numFaces, float*& colorArrayA, float*& colorArrayD, float*& colorArrayS, float*& normalArray, float objScale) 
{ 
    while (app->isOpen()) 
    { 
     renderScene(numVertices, numFaces, colorArrayA, colorArrayD, colorArrayS, normalArray, objScale); 
     handleEvents(); 
    } 
} 


} 

Datei: shader.cpp

#include "shader.h" 
#include <string.h> 
#include <iostream> 
#include <stdlib.h> 

using namespace std; 

static char* textFileRead(const char *fileName) { 
    char* text = NULL; 

    if (fileName != NULL) { 
     FILE *file = fopen(fileName, "rt"); 

     if (file != NULL) { 
      fseek(file, 0, SEEK_END); 
      int count = ftell(file); 
      rewind(file); 

      if (count > 0) { 
       text = (char*)malloc(sizeof(char) * (count + 1)); 
       count = fread(text, sizeof(char), count, file); 
       text[count] = '\0'; 
      } 
      fclose(file); 
     } 
    } 
    return text; 
} 

Shader::Shader() { 

} 

Shader::Shader(const char *vsFile, const char *fsFile) { 
    init(vsFile, fsFile); 
} 

void Shader::init(const char *vsFile, const char *fsFile) { 
    shader_vp = glCreateShader(GL_VERTEX_SHADER); 
    shader_fp = glCreateShader(GL_FRAGMENT_SHADER); 

    const char* vsText = NULL; 
    const char* fsText = NULL; 
    vsText = textFileRead(vsFile); 
    fsText = textFileRead(fsFile); 

    if (vsText == NULL) 
    { 
     cerr << "Error: vertex shader file not found" << endl; 
    } 
    if (fsText == NULL) { 
     cerr << "Error: fragment shader file not found." << endl; 
    } 
    if (vsText == NULL || fsText == NULL) 
     return; 

    glShaderSource(shader_vp, 1, &vsText, 0); 
    glShaderSource(shader_fp, 1, &fsText, 0); 

    glCompileShader(shader_vp); 
    glCompileShader(shader_fp); 

    shader_id = glCreateProgram(); 
    glAttachShader(shader_id, shader_fp); 
    glAttachShader(shader_id, shader_vp); 
    glLinkProgram(shader_id); 

    glBindAttribLocation(shader_id, 0, "in_Position"); 
    //glBindAttribLocation(shader_id, 1, "in_Color"); 
    glBindAttribLocation(shader_id, 1, "in_Normal"); 
} 

Shader::~Shader() { 
    glDetachShader(shader_id, shader_fp); 
    glDetachShader(shader_id, shader_vp); 

    glDeleteShader(shader_fp); 
    glDeleteShader(shader_vp); 
    glDeleteProgram(shader_id); 
} 

unsigned int Shader::id() { 
    return shader_id; 
} 

void Shader::bind() { 
    glUseProgram(shader_id); 
} 

void Shader::unbind() { 
    glUseProgram(0); 
} 

Datei: shader.vert

#version 150 core 

in vec3 in_Position; 
in vec3 in_Normal; 

uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 modelMatrix; 
uniform vec3 lightPosition; 
uniform mat3 normalMatrix; 

smooth out vec3 vVaryingNormal; 
smooth out vec3 vVaryingLightDir; 

void main() 
{  
    // derive MVP and MV matrices 
    mat4 modelViewProjectionMatrix = projectionMatrix * viewMatrix * modelMatrix; 
    mat4 modelViewMatrix = viewMatrix * modelMatrix; 

    // get surface normal in eye coordinates 
    vVaryingNormal = normalMatrix * in_Normal; 

    // get vertex position in eye coordinates 
    vec4 vPosition4 = modelViewMatrix * vec4(in_Position, 1.0); 
    vec3 vPosition3 = vPosition4.xyz/vPosition4.w; 

    // get vector to light source 
    vVaryingLightDir = normalize(lightPosition - vPosition3); 


    // Set the position of the current vertex 
    gl_Position = modelViewProjectionMatrix * vec4(in_Position, 1.0); 

} 

Datei: shader.frag

#version 150 core 

out vec4 out_Color; 

uniform vec3 ambientColor; 
uniform vec3 diffuseColor; 
uniform vec3 specularColor; 

smooth in vec3 vVaryingNormal; 
smooth in vec3 vVaryingLightDir; 

void main() 
{ 
    // dot product gives us diffuse intensity 
    float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir))); 

    // multiply intensity by diffuse color, force alpha to 1.0 
    out_Color = vec4(diff * diffuseColor, 1.0); 

    // add in ambient light 
    out_Color += vec4(ambientColor, 1.0); 

    // specular light 
    vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir), normalize(vVaryingNormal))); 
    float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection)); 

    if (diff != 0) 
    { 
     float fSpec = pow(spec, 128.0); 
     // Set the output color of our current pixel 
     out_Color.rgb += vec3(fSpec, fSpec, fSpec); 
    } 
} 

Ich weiß, dass es viel zu sehen gibt, aber ich wäre sehr glücklich, Hilfe zu bekommen, um diesem Problem auf den Grund zu gehen, also danke im Voraus an jeden, der Zeit hat, mir dabei zu helfen, dies herauszufinden!

+1

Es ist für Ihr Problem nicht verwandt, aber Sie haben einen Speicherverlust. Sie löschen nie vsText oder psText in shader.cpp, obwohl Sie malloc verwenden, um Speicher für sie zuzuweisen. In der Tat sollten Sie nie Malloc verwenden müssen. In diesem Fall würde ich einen Verweis auf einen std :: vector übergeben, den Vektor auf die Größe der Datei skalieren, ihn füllen und dann diesen anstelle eines rohen Zeichens * verwenden. Sie könnten auch eine std :: shared_ptr verwenden, um Ihre char-Arrays zu halten und diese von der Funktion zu erhalten. Alles außer Malloc !!! :-). – Robinson

Antwort

2

Ich glaube nicht, dass Sie die Indizes richtig behandeln. OBJs sind schwierig zu analysieren in opengl, weil sie Daten in einem nutzlosen Multiple-Index-Format bereitstellen. Im Wesentlichen müssen Sie alle Scheitelpunkte und Normalen zerlegen und die Indizes so neu aufbauen, dass für jeden Scheitelpunkt die Position/Normal/Farbe/was auch immer derselbe Index ist. Es ist keine triviale Aufgabe, sie neu zu ordnen, aber wenn Sie online nach "obj vertex buffer" suchen, werden Sie sicherlich Hunderte von Referenzen und Posts darüber finden.

Versuchen Sie, diese zu lesen und zu sehen, ob es sinnvoller ist: http://aresio.blogspot.com/2009/07/wavefront-obj-files-vertex-buffer.html

+0

Ich denke du hast recht, dass ich die Normalen/normalen Indizes falsch mache. Es sieht aus wie in normalVectorsToNormalArrays() Ich füge nur eine Normale pro Gesicht hinzu. Was ich denke, ich sollte tun (und korrigieren Sie mich, wenn ich falsch liege), sollte ich eine Normale für jeden Eckpunkt hinzufügen. Ich werde versuchen, das morgen zu beheben und zu sehen, ob ich bessere Beleuchtungsergebnisse bekomme. Danke für den Zeiger! – Defcronyke

+0

Ich lade jetzt eine Normale für jeden Knoten (ist das richtig, oder sollte es für jedes Gesicht 1 normal sein?). Aber ich lade die Normalen in die Indexreihenfolge ihrer .obj-Datei, also funktioniert das offensichtlich immer noch nicht richtig, denn wie du sagtest, müssen die Normalen und die Vertices ** den gleichen Index haben ** ... ich bin es schwer zu verstehen, wie man dies erreicht, und der Pseudo-Code bei dem Link, den du mir gegeben hast, macht mir keinen großen Sinn (ich habe es immer wieder gelesen), noch kommt Google auf etwas Nützliches. Ich werde es weiter versuchen, aber könnten Sie mir mehr Rat geben? – Defcronyke

+1

Mein erster Ratschlag wäre nur, das Rad nicht neu zu erfinden und Assimp (http://assimp.sourceforge.net/) herunterzuladen, damit du mit interessanteren Dingen weitermachen kannst :). Ich habe keine Zeit für eine vollständige Erklärung, aber wenn Sie es selbst machen wollen, läuft es auf: Erstellen Sie einen neuen Vektor von Strukturen namens "Vertex", die Position, Normal, Texcoord, etc. enthalten. Dann gehen Sie durch das Obj Datei, und jedes Mal, wenn Sie ein eindeutiges Paar von Position/normal/Texcoord finden, kopieren Sie die Daten in einen neuen Scheitelpunkt, so dass es alles zusammen ist (eine STL-Karte ist nützlich für die Erkennung von Duplikaten). Verwenden Sie dann diesen neuen Vektor zum Zeichnen. – Tim