4

したがって、この質問を編集する必要があります。コメントの1つで述べたように、バッファを使用するようにレンダリング方法に変更しました。ただし、ジオメトリが正しく描画されていません。同じバッファを使用して頂点を手動で描画すると、問題なく表示されます(ただし、テクスチャがないと、何かが台無しになります)。また、頂点情報だけでバッファを構築しようとしましたが、それはまったく役に立ちませんでした。

void ModelHandler::DrawModels(){


    //go through each of the models
    for(int i=0;i<Models3D.size();i++){

        //glEnableClientState(GL_VERTEX_ARRAY);
        //glVertexPointer(3, GL_FLOAT, 0, Models3D[i]->object.m_pVertice);


        //now draw all the material groups with their vertices for the model
        for(int j=0;j<Models3D[i]->object.mtlGroups.size();j++){


            //Drawing the vertices manually from the buffer object seems to work
            /*
            for(int lj=0;lj<Models3D[i]->object.mtlGroups[j]->m_vecgroupVerticeIndex.size();lj++){

                int mtlIndex2 = Models3D[i]->object.FindMaterial(Models3D[i]->object.mtlGroups[j]->mtlName);
                bool tOn = false;

                //check if there was a texture for this material
                if(Models3D[i]->object.materials[mtlIndex2]->texturePresent){

                    glEnable(GL_TEXTURE_2D);
                    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
                    glBindTexture(GL_TEXTURE_2D, Models3D[i]->object.materials[mtlIndex2]->textureIDDiffuse);
                    tOn = true;


                }

                if(tOn){
                    glBegin (GL_QUADS);
                    glTexCoord2f (0.0, 0.0);
                    glVertex3f (0.0+5, 0.0, -2.0f);
                    glTexCoord2f (1.0, 0.0);
                    glVertex3f (1.4f+5, 0.0, -2.0f);
                    glTexCoord2f (1.0, 1.0);
                    glVertex3f (1.4f+5, -1.0, -2.0f);
                    glTexCoord2f (0.0, 1.0);
                    glVertex3f (0.0f+5, -1.0, -2.0f);
                    glEnd ();               
                }



                glBegin(GL_TRIANGLES);

                glColor3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3].colour[0],Models3D[i]->object.mtlGroups[j]->VBO[lj*3].colour[1],Models3D[i]->object.mtlGroups[j]->VBO[lj*3].colour[2]);
                if(tOn){
                glTexCoord2f (Models3D[i]->object.mtlGroups[j]->VBO[lj*3].tex[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3].tex[1]);
                }
                glVertex3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3].location[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3].location[1], Models3D[i]->object.mtlGroups[j]->VBO[lj*3].location[2]);


                glColor3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].colour[0],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].colour[1],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].colour[2]);
                if(tOn){
                glTexCoord2f (Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].tex[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].tex[1]);
                }
                glVertex3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].location[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].location[1], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].location[2]);


                glColor3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].colour[0],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].colour[1],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].colour[2]);
                if(tOn){
                glTexCoord2f (Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].tex[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].tex[1]);
                }
                glVertex3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].location[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].location[1], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].location[2]);

                glEnd();


            }
            glDisable(GL_TEXTURE_2D);
            */

            //####
            glBindBuffer(GL_ARRAY_BUFFER, Models3D[i]->object.mtlGroups[j]->vboID);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Models3D[i]->object.mtlGroups[j]->indexvboID);


            /*
            //this could also be used BUT if glDrawElements uses the indices (m_pgroupVerticeIndex), we will need to give the array with all the 
            //vertices to glVertexPointer. That array would be m_pVertice
            //glVertexPointer(3, GL_FLOAT, 5, Models3D[i]->object.mtlGroups[j]->buffer);
            */


            glEnableClientState(GL_COLOR_ARRAY);
            glEnableClientState(GL_NORMAL_ARRAY);
            glEnableClientState(GL_VERTEX_ARRAY);


            //Get the material that belongs to this mtlGroup
            int mtlIndex = Models3D[i]->object.FindMaterial(Models3D[i]->object.mtlGroups[j]->mtlName);


            //check if there was a texture for this material
            if(Models3D[i]->object.materials[mtlIndex]->texturePresent){

                glEnable(GL_TEXTURE_2D);
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
                glBindTexture(GL_TEXTURE_2D, Models3D[i]->object.materials[mtlIndex]->textureIDDiffuse);

                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
                //glTexCoordPointer(2, GL_FLOAT, 5, Models3D[i]->object.mtlGroups[j]->buffer);
                //glTexCoordPointer(2, GL_FLOAT, 0, Models3D[i]->object.m_pTexture);

            }


            // Resetup our pointers.  This doesn't reinitialise any data, only how we walk through it
            glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(20));
            glColorPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(32));
            glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));



            glDrawElements(GL_TRIANGLES, Models3D[i]->object.mtlGroups[j]->m_vecgroupVerticeIndex.size()*3, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));

            //glDrawElements(GL_TRIANGLES, Models3D[i]->object.mtlGroups[j]->m_vecgroupVerticeIndex.size()*3, GL_UNSIGNED_INT,  Models3D[i]->object.mtlGroups[j]->m_pgroupVerticeIndex);


            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisableClientState(GL_COLOR_ARRAY);
            glDisableClientState(GL_NORMAL_ARRAY);
            glDisableClientState(GL_VERTEX_ARRAY);

            glDisable(GL_TEXTURE_2D);

        }


    }


}

私のバッファには頂点(頂点構造体の配列)が含まれています:

struct Vertex {

    GLfloat location[3];
    GLfloat tex[2];
    GLfloat normal[3];
    GLfloat colour[3];
    GLubyte padding[20];        //apparently to get 64 bytes -> improved performance


};

そして、これが私が各材料のバッファを初期化/生成する方法です:

//This function was implemented based on the tutorial shown at
//http://sdickinson.com/wordpress/?p=122

void CObjLoader::GenerateVBO(){


    for(int mj=0;mj<mtlGroups.size();mj++){

        glGenBuffers(1, &mtlGroups[mj]->vboID);
        //printf("bufferID: %d", mtlGroups[mj]->vboID);

        glBindBuffer(GL_ARRAY_BUFFER, mtlGroups[mj]->vboID); // Bind the buffer (vertex array data)

        // Allocate space.  We could pass the mesh in here (where the NULL is), but it's actually faster to do it as a 
        // seperate step.  We also define it as GL_STATIC_DRAW which means we set the data once, and never 
        // update it.  This is not a strict rule code wise, but gives hints to the driver as to where to store the data
        glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * mtlGroups[mj]->m_vecgroupVerticeIndex.size()*3, NULL, GL_STATIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * mtlGroups[mj]->m_vecgroupVerticeIndex.size()*3, mtlGroups[mj]->VBO); // Actually upload the data

        // Set the pointers to our data.  Except for the normal value (which always has a size of 3), we must pass 
        // the size of the individual component.  ie. A vertex has 3 points (x, y, z), texture coordinates have 2 (u, v) etc.
        // Basically the arguments are (ignore the first one for the normal pointer), Size (many components to 
        // read), Type (what data type is it), Stride (how far to move forward - in bytes - per vertex) and Offset 
        // (where in the buffer to start reading the data - in bytes)

        // Make sure you put glVertexPointer at the end as there is a lot of work that goes on behind the scenes
        // with it, and if it's set at the start, it has to do all that work for each gl*Pointer call, rather than once at
        // the end.
        glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
        glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(20));
        glColorPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(32));
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));

        // When we get here, all the vertex data is effectively on the card

        // Our Index Buffer, same as above, the variable needs to be accessible wherever we draw
        glGenBuffers(1, &mtlGroups[mj]->indexvboID); // Generate buffer
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mtlGroups[mj]->indexvboID); // Bind the element array buffer
        // Upload the index array, this can be done the same way as above (with NULL as the data, then a 
        // glBufferSubData call, but doing it all at once for convenience)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, mtlGroups[mj]->m_vecgroupVerticeIndex.size()*3*sizeof(GLubyte), mtlGroups[mj]->index, GL_STATIC_DRAW);

    }


}

簡単にするために、私のインデックス配列は次のようになります:0、1、2、3、4、5、...。これは、バッファにいくつかの頂点が2回含まれていることを意味します。したがって、VBOとインデックスの長さは同じです。

たぶん私は初期化で何かを台無しにしていますか?

4

1 に答える 1

1

したがって、エラーは次のとおりです(解決策を説明する以前のコメントをコピーします):

わかりました、エラーが見つかりました。どうやら、インデックスにGLubyteを使用していたようで、私の場合、255を超える頂点があります。Gluint に変更すると、問題が解決しました。ただし、テクスチャがまだオブジェクトに正しく描画されません。オブジェクトは灰色のままです。しかし、色は機能しているようです。

.obj ローダーは現在、より良い結果を生み出しており、より単純なモデルで問題ありません。さらにテストを行い、問題が発生した場合は戻ってきます。

于 2012-11-14T17:14:03.413 に答える