opengl vbo 纹理

发布于 2024-10-30 13:07:11 字数 11112 浏览 3 评论 0原文

我还是 vbo 的初学者,我想渲染一个 collada 模型。从cae文件中获取有关顶点、法线和纹理的所有所需信息以及分别用于顶点、法线和纹理的索引后,我将它们作为模型对象放置在内存中。剩下的事情是如何使用 vbo 和纹理来渲染这个对象。我成功地渲染了对象,方法是获取顶点和索引,然后在 vbo 渲染的情况下应用drawlelement。但是,当我尝试渲染纹理时,它会失败,而使用显示列表渲染它们可以正常工作,那是因为我正在遍历每个三角形并根据顶点索引和纹理索引正确应用顶点和纹理坐标。那么我如何应用在 vbo 中的对象中找到的纹理索引以便正确渲染纹理?

这是该项目的代码:

#include "bmp.h"

    struct mdl_vert
    {
        float x,y,z;
    };
    struct mdl_normal
    {
        float x,y,z;
    };
    struct mdl_texCoord
    {
        float u,v;
    };
    struct mdl_capacity
    {
        int vertsSize,indicesSize,normalsSize,texCoordsSize;
    };
    struct mdl_indices
    {
        int *vertIndices;
        int *normalIndices;
        int *texIndices;
    };

    class Group
    {
    public:
        mdl_capacity capacity;
        mdl_vert *verts;
        mdl_normal *normals;
        mdl_texCoord *texCoords;
        mdl_indices indices;
        char grp_name[64];

        Group()
        {
            capacity.texCoordsSize=0;
            capacity.normalsSize=0;
            capacity.indicesSize=0;
            capacity.vertsSize=0;
            verts=NULL;
            normals=NULL;
            texCoords=NULL;
            indices.vertIndices=NULL;
            indices.normalIndices=NULL;
            indices.texIndices=NULL;
            for(int i=0;i<64;i++)
                grp_name[i]='\0';
        }
    };

    class Model
    {
    public:
        char tex_name[512];
        std::string Name;
        Group **groups;
        int groupsSize;
    }
    #define VBO_BUFFER_SIZE 4
    struct GroupObject
    {
        GLuint *buffer;
    };
    class ModelObject
    {
    private:
        GLuint displayList;
        GroupObject *groupBuffer;
        bool isLoaded;
        GLuint tex;
        float ang,iniRotX,iniRotY,iniRotZ;
        Model *mdl;
        bool Hide;
        AUX_RGBImageRec* m_pTextureImage;                   // Heightmap Data
    public:
        ModelObject(Model* mdl)
        {
            this->mdl=mdl;
            Redraw();
        }
        void Redraw()
        {
            Hide=false;
            ang=-0;
            iniRotX=1;
            iniRotY=0;
            iniRotZ=0;
            if(displayList!=-1)
                displayList=-1;
            groupBuffer=NULL;
        }

        void BuildTexture(int i)
        {
            if(mdl->groups[i]->capacity.texCoordsSize>0)
            {
                try
                {
                    m_pTextureImage = auxDIBImageLoad( mdl->tex_name );             // Utilize GLaux's Bitmap Load Routine
                    glGenTextures( 1, &tex );                   // Get An Open ID
                    glBindTexture( GL_TEXTURE_2D, tex );                // Bind The Texture
                    glTexImage2D( GL_TEXTURE_2D, 0, 3, m_pTextureImage->sizeX, m_pTextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, m_pTextureImage->data );
                    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

                    // Free The Texture Data
                    if( m_pTextureImage )
                    {
                        if( m_pTextureImage->data )
                            free( m_pTextureImage->data );
                        free( m_pTextureImage );
                    }
                }
                catch(std::exception &ex)
                {
                }
            }
        }

        void BuildVBO()
        {
            int index=0;
            groupBuffer=new GroupObject[mdl->groupsSize];

            for(int i=0;i<mdl->groupsSize;i++)
            {
                BuildTexture(i);
                groupBuffer[i].buffer=new GLuint[VBO_BUFFER_SIZE];
                // Generate And Bind The Vertex Buffer
                glGenBuffersARB( 1, &groupBuffer[i].buffer[0] );                            // Get A Valid Name
                glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[0] );           // Bind The Buffer
                glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.vertsSize*sizeof(mdl_vert), mdl->groups[i]->verts, GL_STATIC_DRAW_ARB );
                // Generate And Bind The Normal Buffer
                glGenBuffersARB( 1, &groupBuffer[i].buffer[1] );                            // Get A Valid Name
                glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[1] );           // Bind The Buffer
                glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.normalsSize*sizeof(mdl_normal),  mdl->groups[i]->normals, GL_STATIC_DRAW_ARB );
                // Generate And Bind The Texture Buffer
                glGenBuffersARB( 1, &groupBuffer[i].buffer[2] );                            // Get A Valid Name
                glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[2] );           // Bind The Buffer
                glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.texCoordsSize*sizeof(mdl_texCoord),  mdl->groups[i]->texCoords, GL_STATIC_DRAW_ARB );
                // Generate And Bind The Index Buffer
                glGenBuffersARB(1, &groupBuffer[i].buffer[3]);
                glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[3]);
                glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mdl->groups[i]->capacity.indicesSize*sizeof(unsigned int),  mdl->groups[i]->indices.vertIndices, GL_STATIC_DRAW_ARB);
            }
        }

        void render()
        {
            if(!Hide)
            {
                if(Drawer.vboSupported())
                {
                    if(groupBuffer==NULL)
                        BuildVBO();
                    glRotatef(ang,iniRotX,iniRotY,iniRotZ);
                    for(int i=0;i<mdl->groupsSize;i++)
                    {
                        // Enable Pointers
                        glEnableClientState( GL_VERTEX_ARRAY );                 // Disable Vertex Arrays
                        glEnableClientState( GL_NORMAL_ARRAY );             // Enable Normal Arrays
                        glEnableClientState( GL_TEXTURE_COORD_ARRAY );              // Enable Texture Coord Arrays

                        glBindBufferARB(  GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[0] );
                        glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

                        glBindBufferARB(  GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[1] );
                        glNormalPointer(GL_FLOAT,0, BUFFER_OFFSET(0));

                        glClientActiveTexture(GL_TEXTURE0);
                        glBindBufferARB(  GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[2] );
                        glTexCoordPointer(2,GL_FLOAT,0,BUFFER_OFFSET(0));

                        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, groupBuffer[i].buffer[3]);
                        glIndexPointer(GL_UNSIGNED_INT,0,BUFFER_OFFSET(0));
                        glDrawElements( GL_TRIANGLES, mdl->groups[i]->capacity.indicesSize,GL_UNSIGNED_INT, 0); // Draw All Of The Triangles At Once

                        // Disable Pointers
                        glDisableClientState( GL_VERTEX_ARRAY );                    // Disable Vertex Arrays
                        glDisableClientState( GL_NORMAL_ARRAY );                // Enable Normal Arrays
                        glDisableClientState( GL_TEXTURE_COORD_ARRAY );             // Enable Texture Coord Arrays
                    }
                    glRotatef(-ang,iniRotX,iniRotY,iniRotZ);
                }
                else
                {
                    if(this->displayList==-1)
                    {
                        displayList = glGenLists(1);
                        glNewList(displayList,GL_COMPILE_AND_EXECUTE);
                        glRotatef(ang,iniRotX,iniRotY,iniRotZ);
                        for(int j=0;j<mdl->groupsSize;j++)
                        {
                            glEnable(GL_TEXTURE_2D);
                            glBindTexture(GL_TEXTURE_2D, tex);
                            // Enable Pointers
                            BuildTexture(j);
                            //glColor3f(((float)(rand()%256)/256.0f),((float)(rand()%256)/256.0f),((float)(rand()%256)/256.0f));
                            for(int i=0;i<mdl->groups[j]->capacity.indicesSize;i+=3)
                            {
                                int iv1=mdl->groups[j]->indices.vertIndices[i];
                                int in1=mdl->groups[j]->indices.normalIndices[i];
                                int it1=mdl->groups[j]->indices.texIndices[i];
                                int iv2=mdl->groups[j]->indices.vertIndices[i+1];
                                int in2=mdl->groups[j]->indices.normalIndices[i+1];
                                int it2=mdl->groups[j]->indices.texIndices[i+1];
                                int iv3=mdl->groups[j]->indices.vertIndices[i+2];
                                int in3=mdl->groups[j]->indices.normalIndices[i+2];
                                int it3=mdl->groups[j]->indices.texIndices[i+2];
                                glBegin(GL_TRIANGLES);
                                    glTexCoord2f(mdl->groups[j]->texCoords[it1].u,mdl->groups[j]->texCoords[it1].v);
                                    glNormal3f(mdl->groups[j]->normals[in1].x,mdl->groups[j]->normals[in1].y,mdl->groups[j]->normals[in1].z);
                                    glVertex3f(mdl->groups[j]->verts[iv1].x,mdl->groups[j]->verts[iv1].y,mdl->groups[j]->verts[iv1].z);
                                    glTexCoord2f(mdl->groups[j]->texCoords[it2].u,mdl->groups[j]->texCoords[it2].v);
                                    glNormal3f(mdl->groups[j]->normals[in2].x,mdl->groups[j]->normals[in2].y,mdl->groups[j]->normals[in2].z);
                                    glVertex3f(mdl->groups[j]->verts[iv2].x,mdl->groups[j]->verts[iv2].y,mdl->groups[j]->verts[iv2].z);
                                    glTexCoord2f(mdl->groups[j]->texCoords[it3].u,mdl->groups[j]->texCoords[it3].v);
                                    glNormal3f(mdl->groups[j]->normals[in3].x,mdl->groups[j]->normals[in3].y,mdl->groups[j]->normals[in3].z);
                                    glVertex3f(mdl->groups[j]->verts[iv3].x,mdl->groups[j]->verts[iv3].y,mdl->groups[j]->verts[iv3].z);
                                glEnd();
                            }
                            glDisable(GL_TEXTURE_2D);
                        }
                        glRotatef(-ang,iniRotX,iniRotY,iniRotZ);
                        glEndList();
                        glCallList(displayList);
                    }
                    else
                        glCallList(displayList);
                }
            }
        }

I am still a beginner in vbo and I want to render a collada model. After taking all the needed info from the cae file about the vertices, normals and textures and indices for the vertices, normals and textures respectively, then i placed them in memory as a Model object. the thing that remained is how to render this object using vbo with the textures. I managed to render the object successfully by taking the vertices and indices then applying drawlelement for that in case of vbo render. But when I try to render textures it fails while rendering them using the display list works correctly thats because I am passing through every triangle and applying the vertex and texcoord correctly according to the vertex index and texture index. So how can i apply the texture indices found in the object in vbo in order for the texture to be rendered correctly?

This is the code for the project:

#include "bmp.h"

    struct mdl_vert
    {
        float x,y,z;
    };
    struct mdl_normal
    {
        float x,y,z;
    };
    struct mdl_texCoord
    {
        float u,v;
    };
    struct mdl_capacity
    {
        int vertsSize,indicesSize,normalsSize,texCoordsSize;
    };
    struct mdl_indices
    {
        int *vertIndices;
        int *normalIndices;
        int *texIndices;
    };

    class Group
    {
    public:
        mdl_capacity capacity;
        mdl_vert *verts;
        mdl_normal *normals;
        mdl_texCoord *texCoords;
        mdl_indices indices;
        char grp_name[64];

        Group()
        {
            capacity.texCoordsSize=0;
            capacity.normalsSize=0;
            capacity.indicesSize=0;
            capacity.vertsSize=0;
            verts=NULL;
            normals=NULL;
            texCoords=NULL;
            indices.vertIndices=NULL;
            indices.normalIndices=NULL;
            indices.texIndices=NULL;
            for(int i=0;i<64;i++)
                grp_name[i]='\0';
        }
    };

    class Model
    {
    public:
        char tex_name[512];
        std::string Name;
        Group **groups;
        int groupsSize;
    }
    #define VBO_BUFFER_SIZE 4
    struct GroupObject
    {
        GLuint *buffer;
    };
    class ModelObject
    {
    private:
        GLuint displayList;
        GroupObject *groupBuffer;
        bool isLoaded;
        GLuint tex;
        float ang,iniRotX,iniRotY,iniRotZ;
        Model *mdl;
        bool Hide;
        AUX_RGBImageRec* m_pTextureImage;                   // Heightmap Data
    public:
        ModelObject(Model* mdl)
        {
            this->mdl=mdl;
            Redraw();
        }
        void Redraw()
        {
            Hide=false;
            ang=-0;
            iniRotX=1;
            iniRotY=0;
            iniRotZ=0;
            if(displayList!=-1)
                displayList=-1;
            groupBuffer=NULL;
        }

        void BuildTexture(int i)
        {
            if(mdl->groups[i]->capacity.texCoordsSize>0)
            {
                try
                {
                    m_pTextureImage = auxDIBImageLoad( mdl->tex_name );             // Utilize GLaux's Bitmap Load Routine
                    glGenTextures( 1, &tex );                   // Get An Open ID
                    glBindTexture( GL_TEXTURE_2D, tex );                // Bind The Texture
                    glTexImage2D( GL_TEXTURE_2D, 0, 3, m_pTextureImage->sizeX, m_pTextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, m_pTextureImage->data );
                    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

                    // Free The Texture Data
                    if( m_pTextureImage )
                    {
                        if( m_pTextureImage->data )
                            free( m_pTextureImage->data );
                        free( m_pTextureImage );
                    }
                }
                catch(std::exception &ex)
                {
                }
            }
        }

        void BuildVBO()
        {
            int index=0;
            groupBuffer=new GroupObject[mdl->groupsSize];

            for(int i=0;i<mdl->groupsSize;i++)
            {
                BuildTexture(i);
                groupBuffer[i].buffer=new GLuint[VBO_BUFFER_SIZE];
                // Generate And Bind The Vertex Buffer
                glGenBuffersARB( 1, &groupBuffer[i].buffer[0] );                            // Get A Valid Name
                glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[0] );           // Bind The Buffer
                glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.vertsSize*sizeof(mdl_vert), mdl->groups[i]->verts, GL_STATIC_DRAW_ARB );
                // Generate And Bind The Normal Buffer
                glGenBuffersARB( 1, &groupBuffer[i].buffer[1] );                            // Get A Valid Name
                glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[1] );           // Bind The Buffer
                glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.normalsSize*sizeof(mdl_normal),  mdl->groups[i]->normals, GL_STATIC_DRAW_ARB );
                // Generate And Bind The Texture Buffer
                glGenBuffersARB( 1, &groupBuffer[i].buffer[2] );                            // Get A Valid Name
                glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[2] );           // Bind The Buffer
                glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.texCoordsSize*sizeof(mdl_texCoord),  mdl->groups[i]->texCoords, GL_STATIC_DRAW_ARB );
                // Generate And Bind The Index Buffer
                glGenBuffersARB(1, &groupBuffer[i].buffer[3]);
                glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[3]);
                glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mdl->groups[i]->capacity.indicesSize*sizeof(unsigned int),  mdl->groups[i]->indices.vertIndices, GL_STATIC_DRAW_ARB);
            }
        }

        void render()
        {
            if(!Hide)
            {
                if(Drawer.vboSupported())
                {
                    if(groupBuffer==NULL)
                        BuildVBO();
                    glRotatef(ang,iniRotX,iniRotY,iniRotZ);
                    for(int i=0;i<mdl->groupsSize;i++)
                    {
                        // Enable Pointers
                        glEnableClientState( GL_VERTEX_ARRAY );                 // Disable Vertex Arrays
                        glEnableClientState( GL_NORMAL_ARRAY );             // Enable Normal Arrays
                        glEnableClientState( GL_TEXTURE_COORD_ARRAY );              // Enable Texture Coord Arrays

                        glBindBufferARB(  GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[0] );
                        glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

                        glBindBufferARB(  GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[1] );
                        glNormalPointer(GL_FLOAT,0, BUFFER_OFFSET(0));

                        glClientActiveTexture(GL_TEXTURE0);
                        glBindBufferARB(  GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[2] );
                        glTexCoordPointer(2,GL_FLOAT,0,BUFFER_OFFSET(0));

                        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, groupBuffer[i].buffer[3]);
                        glIndexPointer(GL_UNSIGNED_INT,0,BUFFER_OFFSET(0));
                        glDrawElements( GL_TRIANGLES, mdl->groups[i]->capacity.indicesSize,GL_UNSIGNED_INT, 0); // Draw All Of The Triangles At Once

                        // Disable Pointers
                        glDisableClientState( GL_VERTEX_ARRAY );                    // Disable Vertex Arrays
                        glDisableClientState( GL_NORMAL_ARRAY );                // Enable Normal Arrays
                        glDisableClientState( GL_TEXTURE_COORD_ARRAY );             // Enable Texture Coord Arrays
                    }
                    glRotatef(-ang,iniRotX,iniRotY,iniRotZ);
                }
                else
                {
                    if(this->displayList==-1)
                    {
                        displayList = glGenLists(1);
                        glNewList(displayList,GL_COMPILE_AND_EXECUTE);
                        glRotatef(ang,iniRotX,iniRotY,iniRotZ);
                        for(int j=0;j<mdl->groupsSize;j++)
                        {
                            glEnable(GL_TEXTURE_2D);
                            glBindTexture(GL_TEXTURE_2D, tex);
                            // Enable Pointers
                            BuildTexture(j);
                            //glColor3f(((float)(rand()%256)/256.0f),((float)(rand()%256)/256.0f),((float)(rand()%256)/256.0f));
                            for(int i=0;i<mdl->groups[j]->capacity.indicesSize;i+=3)
                            {
                                int iv1=mdl->groups[j]->indices.vertIndices[i];
                                int in1=mdl->groups[j]->indices.normalIndices[i];
                                int it1=mdl->groups[j]->indices.texIndices[i];
                                int iv2=mdl->groups[j]->indices.vertIndices[i+1];
                                int in2=mdl->groups[j]->indices.normalIndices[i+1];
                                int it2=mdl->groups[j]->indices.texIndices[i+1];
                                int iv3=mdl->groups[j]->indices.vertIndices[i+2];
                                int in3=mdl->groups[j]->indices.normalIndices[i+2];
                                int it3=mdl->groups[j]->indices.texIndices[i+2];
                                glBegin(GL_TRIANGLES);
                                    glTexCoord2f(mdl->groups[j]->texCoords[it1].u,mdl->groups[j]->texCoords[it1].v);
                                    glNormal3f(mdl->groups[j]->normals[in1].x,mdl->groups[j]->normals[in1].y,mdl->groups[j]->normals[in1].z);
                                    glVertex3f(mdl->groups[j]->verts[iv1].x,mdl->groups[j]->verts[iv1].y,mdl->groups[j]->verts[iv1].z);
                                    glTexCoord2f(mdl->groups[j]->texCoords[it2].u,mdl->groups[j]->texCoords[it2].v);
                                    glNormal3f(mdl->groups[j]->normals[in2].x,mdl->groups[j]->normals[in2].y,mdl->groups[j]->normals[in2].z);
                                    glVertex3f(mdl->groups[j]->verts[iv2].x,mdl->groups[j]->verts[iv2].y,mdl->groups[j]->verts[iv2].z);
                                    glTexCoord2f(mdl->groups[j]->texCoords[it3].u,mdl->groups[j]->texCoords[it3].v);
                                    glNormal3f(mdl->groups[j]->normals[in3].x,mdl->groups[j]->normals[in3].y,mdl->groups[j]->normals[in3].z);
                                    glVertex3f(mdl->groups[j]->verts[iv3].x,mdl->groups[j]->verts[iv3].y,mdl->groups[j]->verts[iv3].z);
                                glEnd();
                            }
                            glDisable(GL_TEXTURE_2D);
                        }
                        glRotatef(-ang,iniRotX,iniRotY,iniRotZ);
                        glEndList();
                        glCallList(displayList);
                    }
                    else
                        glCallList(displayList);
                }
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

网白 2024-11-06 13:07:11

OpenGL 中没有纹理索引。这种位置和纹理的分离在建模软件中很常见,因为它更易于管理。但在 OpenGL 中,您需要拥有与位置完全相同的纹理坐标计数,因此可以使用相同的索引对它们进行索引。

这将要求您重建所有缓冲区,以便模型中出现的顶点索引、法线索引和纹理坐标索引的每个组合都可以映射到用于 OpenGL 渲染的单个索引。我将尝试编写一些伪代码:

struct Trinity {
    int iv, in, it;

    bool operator <(const Trinity &t) const // implement less-than operator as required by std::map
    {
        return iv < t.iv || (iv == t.iv && (in < t.in || (in == t.in && it < t.it)));
    }
};

#include <map>
#include <vector>

for(int j=0;j<mdl->groupsSize;j++) { // for each object ...
    int next_index = 0; // next index to be assigned

    std::map<int, Trinity> index_map; // map of collada indices to OpenGL indices

    std::vector<int> new_indices; // new indices that can be used for drawing with OpenGL
    std::vector<float> new_positions, new_texcoords, new_normals; // other arrays

    for(int i=0;i<mdl->groups[j]->capacity.indicesSize;i++) { // for each vertex ...
        Trinity t;
        t.iv = mdl->groups[j]->indices.vertIndices[i];
        t.in = mdl->groups[j]->indices.normalIndices[i];
        t.it = mdl->groups[j]->indices.texIndices[i];
        // go through all the vertices' indices

        int index;
        if(index_map.find(t) != index_map.end())
            index = index_map[t]; // we already saw this combination of indices, reuse it
        else {
            index = next_index; // this is new; assign a new index
            ++ next_index;
            index_map[t] = index; // store the index in the map

            new_positions.push_back(mdl->groups[j]->verts[t.iv].x);
            new_positions.push_back(mdl->groups[j]->verts[t.iv].y);
            new_positions.push_back(mdl->groups[j]->verts[t.iv].z);

            new_texcoords.push_back(mdl->groups[j]->texCoords[t.it].u);
            new_texcoords.push_back(mdl->groups[j]->texCoords[t.it].v);

            new_normals.push_back(mdl->groups[j]->normals[t.in].x);
            new_normals.push_back(mdl->groups[j]->normals[t.in].y);
            new_normals.push_back(mdl->groups[j]->normals[t.in].z);
            // add this particular combination of coordinates at the end of the buffers
        }
        // translate the combination of iv, in, it to a single index

        new_indices.push_back(index);
        // store it in the array
    }

    // object data ready to pass to VBOs
}

现在您可以将 new_indices、new_positions、new_normals 和 new_texcoords 放入 VBO 并渲染它们。我希望这有帮助...

There are no texture indices in OpenGL. This separation of positions and textures is quite common in modelling software, as it is simpler to manage. But in OpenGL, you need to have the exactly same count of texture coordinates as there are positions, so they could both be indexed using the same index.

This will require you to rebuild all the buffers, so that every combination of vertex index, normal index and texcoord index that occurs in your model can be mapped to a single index for OpenGL rendering. I'll try and write some pseudocode:

struct Trinity {
    int iv, in, it;

    bool operator <(const Trinity &t) const // implement less-than operator as required by std::map
    {
        return iv < t.iv || (iv == t.iv && (in < t.in || (in == t.in && it < t.it)));
    }
};

#include <map>
#include <vector>

for(int j=0;j<mdl->groupsSize;j++) { // for each object ...
    int next_index = 0; // next index to be assigned

    std::map<int, Trinity> index_map; // map of collada indices to OpenGL indices

    std::vector<int> new_indices; // new indices that can be used for drawing with OpenGL
    std::vector<float> new_positions, new_texcoords, new_normals; // other arrays

    for(int i=0;i<mdl->groups[j]->capacity.indicesSize;i++) { // for each vertex ...
        Trinity t;
        t.iv = mdl->groups[j]->indices.vertIndices[i];
        t.in = mdl->groups[j]->indices.normalIndices[i];
        t.it = mdl->groups[j]->indices.texIndices[i];
        // go through all the vertices' indices

        int index;
        if(index_map.find(t) != index_map.end())
            index = index_map[t]; // we already saw this combination of indices, reuse it
        else {
            index = next_index; // this is new; assign a new index
            ++ next_index;
            index_map[t] = index; // store the index in the map

            new_positions.push_back(mdl->groups[j]->verts[t.iv].x);
            new_positions.push_back(mdl->groups[j]->verts[t.iv].y);
            new_positions.push_back(mdl->groups[j]->verts[t.iv].z);

            new_texcoords.push_back(mdl->groups[j]->texCoords[t.it].u);
            new_texcoords.push_back(mdl->groups[j]->texCoords[t.it].v);

            new_normals.push_back(mdl->groups[j]->normals[t.in].x);
            new_normals.push_back(mdl->groups[j]->normals[t.in].y);
            new_normals.push_back(mdl->groups[j]->normals[t.in].z);
            // add this particular combination of coordinates at the end of the buffers
        }
        // translate the combination of iv, in, it to a single index

        new_indices.push_back(index);
        // store it in the array
    }

    // object data ready to pass to VBOs
}

Now you can put new_indices, new_positions, new_normals and new_texcoords to VBOs and render them. I hope this helps ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文