1

インデックス作成を使用しているため、VBO で法線を正しくレンダリングするのに少し問題があります。通常のポインターのオフセットに何か問題があると確信していますが、数学は私に加算されるようです。

データの保存方法:

struct MyVertex
{
    float x, y, z;        //Vertex
    float nx, ny, nz;     //Normal
};

以下は、VBOのセットアップ方法です。

GLuint VertexVBOID, IndexVBOID;
glGenBuffers(1, &VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*NumOfV, &ModelV[0].x, GL_STATIC_DRAW);

glGenBuffers(1, &IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*NumOfF*3, &ModelI[0], GL_STATIC_DRAW);

私のレンダリングコード:

if(UsingVBO == false)
{
    glRotatef(Timer.getElapsedTime().asSeconds() * 10, 0, 1, 0);
    glBegin(GL_TRIANGLES);
        for(int i = 0; i < NumOfF*3; i+=3)
        {
            glNormal3f(ModelV[ModelI[i]].nx, ModelV[ModelI[i]].ny, ModelV[ModelI[i]].nz);
            glVertex3f(ModelV[ModelI[i]].x, ModelV[ModelI[i]].y, ModelV[ModelI[i]].z);

            glNormal3f(ModelV[ModelI[i+1]].nx, ModelV[ModelI[i+1]].ny, ModelV[ModelI[i+1]].nz);
            glVertex3f(ModelV[ModelI[i+1]].x, ModelV[ModelI[i+1]].y, ModelV[ModelI[i+1]].z);

            glNormal3f(ModelV[ModelI[i+2]].nx, ModelV[ModelI[i+2]].ny, ModelV[ModelI[i+2]].nz);
            glVertex3f(ModelV[ModelI[i+2]].x, ModelV[ModelI[i+2]].y, ModelV[ModelI[i+2]].z);
        }
    glEnd();
}
else
{
    glRotatef(Timer.getElapsedTime().asSeconds() * 10, 0, 1, 0);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);

    glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), 0);
    glNormalPointer(GL_FLOAT, sizeof(MyVertex), (void*)(NumOfV*sizeof(float)));//Number of vertices times size of float
    glDrawElements(GL_TRIANGLES, NumOfF*3, GL_UNSIGNED_INT, 0);//number of indices

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
}

VBO を使用しないレンダリング:

写真1

VBO によるレンダリング:

写真2

4

1 に答える 1

2
glNormalPointer(GL_FLOAT, sizeof(MyVertex), (void*)(NumOfV*sizeof(float)));//Number of vertices times size of float

あなたのオフセットはここで間違っています。最初の 3 つの float が位置で、次の 3 つの float が法線になるように、インターリーブされた頂点データを提供しています。したがって、法線のベース オフセットは 3 float 相当のバイトです (位置をスキップするため)。はモデル全体NumOfVの頂点の数であり、データ構造内の位置の float の数ではありません。MyVertex

これはoffsetofマクロを使用して行うのが最適です。

glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), (void*)offsetof(MyVertex, x));
glNormalPointer(GL_FLOAT, sizeof(MyVertex), (void*)offsetof(MyVertex, nx));
于 2012-11-16T22:24:27.827 に答える