2012-03-27 7 views
0

OpenGL 3.xコアプロファイルを使用して独自の.obj(Wavefront)レンダラーを作成しようとしています。私はOpenGL SuperBible第5版を使用しています。参考資料としてのSwiftlessチュートリアルを参照してください。OpenGL 3.x ADS Phongの "veiny-looking"球付きローダー。

ジオメトリが正しく読み込まれているように見えるので、今はADS Phongの照明モデルを動作させようとしていますが、何かがうんざりです。私は、OpenGL呼び出しやそれ以外の方法私は法線を読み込んでいますが、それを修正する方法を見つけることはできません。 (私はOpenGLの専門家ではないので、他の問題もあるかもしれませんね。

シンプルなキューブをレンダリングする場合、それはほとんど右に見えますが、片側の光の奇妙な点があります:

picture of cube

球体をレンダリングする場合、照明は「静脈」と現れる:

picture of sphere

明らかに私のコードでは間違っています。ここには、関連性があると思われるコードのセクションがあります。必要に応じてもっとコードを投稿してもよろしいです...もっと投稿する必要がある場合はお知らせください。

ファイル: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(); 
    } 
} 


} 

ファイル: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); 
} 

ファイル: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); 

} 

ファイル: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); 
    } 
} 

私はそれを見るのが大変だと知っていますが、私はこの問題の底を知るために何か助けを得ることができてとてもうれしく思います。

+1

をそれはあなたの問題に関連していないのですが、あなたはメモリリークを持っています。 shader.cppのvsTextまたはpsTextは決して削除しませんが、mallocを使用してそれらにメモリを割り当てます。実際、mallocをまったく使用する必要はありません。この場合、私はstd :: vector への参照を渡し、ベクトルのサイズをファイルのサイズに変更し、それを埋めてからraw char *の代わりに使用します。また、std :: shared_ptr を使用して、char配列を保持し、それを関数から受け取ることもできます。 malloc以外何もありません! :-) – Robinson

答えて

2

私はあなたがインデックスを正しく扱っているとは思わない。 OBJは、無用な複数インデックス形式を使ってデータを提供するため、OpenGLで解析するのは難しいです。基本的には、すべての頂点と法線を分解して、すべての頂点に対して同じインデックスを共有している位置/通常/色/すべてのインデックスを再構築する必要があります。並べ替えるのは簡単なことではありませんが、「obj頂点バッファ」をオンラインで見ると、何百もの参照とその記事を見つけることができます。

は、これを読んで試してみて、それがより多くの意味になりかどうかを確認:http://aresio.blogspot.com/2009/07/wavefront-obj-files-vertex-buffer.html

+0

私はあなたが正常であると私は思っています正常/正常な指数を間違っています。 normalVectorsToNormalArrays()のように見えます。私は1面につき1つしか追加しません。私がしなければならないと思うこと(私が間違っている場合は私を修正する)は、私は各頂点の法線を追加する必要があります。私は明日それを修正しようとし、私はより良い照明結果を得るかどうかを確認します。ポインタありがとう! – Defcronyke

+0

私は今すべての頂点の法線をロードしています(そうですか、それとも各面の法線が1であるべきですか?)。しかし、私は彼らの.objファイルのインデックス順で法線をロードしていますので、これは明らかに正しく動作していません。あなたが言ったように、法線と頂点は同じインデックスを共有する必要があります** ...あなたが私に与えたリンクでこれを達成する方法と擬似コードを視覚化しようとするのは苦労しています(私はそれを何度も読んできました)何か役に立つ。私は物事を試し続けますが、あなた(または誰か)が私にもっとアドバイスを与えることができますか? – Defcronyke

+1

私の最初のアドバイスは、ホイールを再開発せずにAssimp(http://assimp.sourceforge.net/)をダウンロードして、もっと興味深いものを手に入れることができるようにすることです:)。私は完全な吹き飛ばされた説明のための時間がありませんが、それを自分自身でやってみたい場合は、位置、通常、テクスチャなどを含む「頂点」という構造体の新しいベクトルを作成します。次にobjファイルと、位置/法線/テクスチャの固有のペアが見つかるたびに、データを新しい頂点にコピーして、すべてが一緒になるようにします(STLマップは重複を検出するのに便利です)。次に、この新しいベクトルを使って描画します。 – Tim

関連する問題