簡體   English   中英

Crisis Nanosuit中的多個紋理-使用Assimp加載模型

[英]Multiple textures in Crisis Nanosuit - Model loading using Assimp

我想在OpenGL / GLSL中使用Assimp加載Crisis Nanosuit模型 該模型具有多個網格,如assimp中的節點樹所描述。 每個網格與一個或多個紋理(漫反射或鏡面反射等)關聯。 如何在模型上渲染紋理,並且仍然通過一次繪制調用來完成呢?

到目前為止,我已經能夠加載沒有紋理的模型。 這就是我的操作方式:我使用節點樹找出模型中存在多少個網格,並使用結構數組將它們堆疊。 這包含位置,法線,Texcoords,Color_Ambient,Color_diffuse,Color_specular和Shininess的浮點值到緩沖區VBO中。 由於網格是堆疊在一起的,因此每個網格的索引數組都發生了偏移。 最后,只需進行一次繪制調用,即可成功渲染模型。 這是完整的代碼 ,相關部分如下

struct Vertex
{
    glm::vec3 position;
    glm::vec3 normal;
    glm::vec2 texcoord;
    glm::vec3 colorambient;
    glm::vec3 colordiffuse;
    glm::vec3 colorspecular;
    float shininess;
};

// Creating a nodestack of all the meshes
void modelloader::NodeTreeTraversal(aiNode *node)
{
    if(node->mNumChildren==0)
        nodestack.push_back(node);
    else
        for(unsigned int i=0; i<node->mNumChildren; i++)
            this->NodeTreeTraversal(node->mChildren[i]);
}

// Look into assimp data structures for data and populate them into opengl's vbo's and ebo.
void modelloader::ProcessMeshes()
{
    // currently this method loads vertex positions, normals, textures;
    // also loads material info such as ambient, diffuse and specular colors with shininess as 16.0f
    Vertex vertex;
    unsigned int offset_faces=0;

    for(unsigned int i=0; i<this->nodestack.size(); i++)
    {
        aiNode *node = nodestack[i];
        for(unsigned int j=0; j<node->mNumMeshes; j++)
        {
            aiMesh *mesh = this->scene->mMeshes[node->mMeshes[j]];

            aiColor4D ambient;
            aiColor4D diffuse;
            aiColor4D specular;

            if(this->scene->HasMaterials()) {
                aiMaterial *mtl = scene->mMaterials[mesh->mMaterialIndex];
                aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient);
                aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse);
                aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular);
            }

            // load all mesh data
            for(unsigned int k=0; k<mesh->mNumVertices; k++)
            {
                // positions and normals
                vertex.position = glm::vec3(mesh->mVertices[k].x, mesh->mVertices[k].y, mesh->mVertices[k].z); // load positions
                vertex.normal = glm::vec3(mesh->mNormals[k].x, mesh->mNormals[k].y, mesh->mNormals[k].z); // load normals

                // load textures
                if(this->scene->HasTextures())
                    vertex.texcoord = glm::vec2(mesh->mTextureCoords[0][k].x, mesh->mTextureCoords[0][k].y);
                else vertex.texcoord = glm::vec2(0.0f, 0.0f);

                // load materials
                vertex.colorambient = glm::vec3(ambient.r, ambient.g, ambient.b);
                vertex.colordiffuse = glm::vec3(diffuse.r, diffuse.g, diffuse.b);
                vertex.colorspecular = glm::vec3(specular.r, specular.g, specular.b);
                vertex.shininess = 16.0f;

                // push back all the data for each vertex
                meshdata.push_back(vertex);
            }

            // create index data
            for(unsigned int l=0; l<mesh->mNumFaces; l++) {
                this->indices.push_back(mesh->mFaces[l].mIndices[0]+offset_faces);
                this->indices.push_back(mesh->mFaces[l].mIndices[1]+offset_faces);
                this->indices.push_back(mesh->mFaces[l].mIndices[2]+offset_faces);
            }
            offset_faces = offset_faces+mesh->mNumVertices;
        }
    }
    this->MeshData = &meshdata[0].position.x;
    this->MeshDataSize = meshdata.size() * 18 * sizeof(float);

    this->Indices = indices.data();
    this->IndicesSize = indices.size()*sizeof(unsigned int);
}
// draw call
void modelloader::RenderModel()
{
    glBindVertexArray(this->VAO);
    glDrawElements(GL_TRIANGLES, this->IndicesSize/sizeof(unsigned int), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

這是輸出圖像

現在,當加載紋理(為身體的每個部位分離圖像文件)時,當我激活所有紋理時,它將每個紋理文件拉伸到整個身體。 如何正確執行?

我的初步想法是:激活所有紋理文件。 在VBO中添加一個名為“ mesh_number”的屬性,在片段着色器中,使用與“ mesh_number”相對應的適當紋理。 我不知道這是否行得通。 通常如何做? 您有代碼示例嗎?

當為完成繪制調用應用到每個網格模型中的這個問題被解決在這里 1)但是抽獎電話並不昂貴嗎? 我不應該一次繪制整個網格嗎? 2)我應該創建一個拼貼所有身體部位的圖像文件嗎? 很像一張雪碧紙嗎?

您需要通過以下方式激活每個紋理:

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, <cour texture id>);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, <cour texture id>);

因此,所有紋理都可以為繪制調用渲染。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM