2

プログラムは頂点を読み取り、テキスタイルを形成するインデックスを作成し、頂点をベクトルに格納し、インデックスを配列に格納します。これがquad.txtです-

4 2 numVertices numIndices

-1 -1 0 v1 v2 v3

1 -1 0

1 1 0

-1 1 0

1 2 3

1 3 4

次に、オブジェクトを画面にレンダリングします-問題ありません。しかし、法線を計算してオブジェクトをフラットシェーディングしようとすると、問題が発生します。オブジェクトはGL_TRINANGLESでレンダリングされます。このhttp://imgur.com/wnKWPのように見えます(直接アップロードするのに十分な評判がありませんでした...)

三角形が別々にシェーディングされるようなものです...とにかくここにコードがあります:

#include "Object.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <cstring>
#include <glm.hpp>


using namespace std;

const int NMAX = 20000;

GLuint indicesArr[NMAX];

vector<glm::vec3> drawFigure;   glm::vec3 figure;
vector<glm::vec3>Vertices;      glm::vec3 vertex;
vector<glm::vec3>Normals;       glm::vec3 normal;
vector<glm::vec3>Temp;          glm::vec3 temp;


int numVertices, numIndices;

//slices = number of subdivisions around the axis
Object::Object() :
mIsInitialised(false)
{
}

Object::~Object()
{
if(mIsInitialised)
{
    drawFigure.clear();
    Vertices.clear();
    Normals.clear();
    Temp.clear();
}
}


bool Object::loadTxtFile(const string &filename)
{
ifstream in(filename);
in >> numVertices >> numIndices;

while (!in.eof())
{
    for (unsigned int i = 1; i <= numVertices; i++)
    {
        in >> vertex.x >> vertex.y >> vertex.z;
        Vertices.push_back(vertex);
    }

    for (unsigned int i = 1; i <= numIndices * 3; i++)
        in >> indicesArr[i];
}

for (unsigned int i = 1; i <= (numIndices * 3); i++)
{
    figure.x = Vertices[indicesArr[i] - 1].x;
    figure.y = Vertices[indicesArr[i] - 1].y;
    figure.z = Vertices[indicesArr[i] - 1].z;
    drawFigure.push_back(figure);
}

for (unsigned int i = 0; i < (numIndices * 3); i+=3)
{
    temp.x = drawFigure[i].x;
    temp.y = drawFigure[i].y;
    temp.z = drawFigure[i].z;
    Temp.push_back(temp);

    temp.x = drawFigure[i + 1].x;
    temp.y = drawFigure[i + 1].y;
    temp.z = drawFigure[i + 1].z;
    Temp.push_back(temp);

    temp.x = drawFigure[i + 2].x;
    temp.y = drawFigure[i + 2].y;
    temp.z = drawFigure[i + 2].z;
    Temp.push_back(temp);

    normal = glm::normalize(glm::cross(Temp[i + 2] - Temp[i], Temp[i + 1] - Temp[i]));
    Normals.push_back(normal);
}
mIsInitialised = true;
return true;  //Return true if successfully loaded
}


void Object::draw()
{

if(!mIsInitialised) { return; }

//Tell OpenGL about our vertex and colour data
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &drawFigure.front());

glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, &Normals.front());

//draw the .txt-file
glDrawArrays(GL_TRIANGLES, 0, (numIndices * 3));

//restore the state GL back
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
4

1 に答える 1

3

頂点ごとに1つの法線が必要です。現在計算しているのは、三角形ごとに1つの法線です。法線の計算に関する次の投稿をご覧ください:http://devmaster.net/forums/topic/1065-calculating-normals-of-a-mesh/

投稿で説明されているように、頂点ごとの法線を計算する方法は2つあります。

  1. 頂点法線は、隣接する面の法線の平均です(devmasterの投稿の#1を参照)。
  2. 頂点法線は、隣接する面法線の角度加重平均です(devmaster投稿の#6を参照)。
于 2012-10-21T20:12:04.787 に答える