opengl 纹理无法正确渲染

Posted

技术标签:

【中文标题】opengl 纹理无法正确渲染【英文标题】:opengl texture not rendering properly 【发布时间】:2012-12-11 00:53:01 【问题描述】:

我正在尝试渲染狼模型。我已经让模型正确渲染。但是,纹理我还没有开始工作。我正在使用 OpenGL 和 AssImp。

这是狼的样子:

狼应该是这样的:

这是加载模型的代码:

IModel* ModelManager::loadModel(const std::string filename) 

    if (models_[filename] != 0) 
        BOOST_LOG_TRIVIAL(debug) << "Model found.";
        return models_[filename].get();
    

    const aiScene* scene = aiImportFile(filename.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);

    if (scene == 0) 
        BOOST_LOG_TRIVIAL(debug) << "Unable to load model...";
        return 0;       
    

    models_[filename] = std::unique_ptr<Model>( new Model(scene) );

    aiReleaseImport(scene);

    BOOST_LOG_TRIVIAL(debug) << "Done loading model '" << filename << "'.";

    return models_[filename].get();

这是为模型加载网格的代码:

Mesh::Mesh(const aiMesh* mesh) 
uint32 currentIndex = 0;

    for (uint32 t = 0; t < mesh->mNumFaces; ++t) 
        const aiFace* face = &mesh->mFaces[t];
        GLenum face_mode;

        switch(face->mNumIndices) 
            case 1: face_mode = GL_POINTS; break;
            case 2: face_mode = GL_LINES; break;
            case 3: face_mode = GL_TRIANGLES; break;
            default: face_mode = GL_POLYGON; break;
        

        uint32 numIndices = face->mNumIndices;

        vertices_.resize( currentIndex + numIndices );
        normals_.resize( currentIndex + numIndices );
        textureCoordinates_.resize( currentIndex + numIndices );
        colors_.resize( currentIndex + numIndices );

        for(uint32 i = 0; i < numIndices; i++) 
            // get group index for current index
            int vertexIndex = face->mIndices[i];

            if (mesh->mNormals != 0) 
                vertices_[currentIndex + i]     = glm::vec3( mesh->mVertices[vertexIndex].x, mesh->mVertices[vertexIndex].y, mesh->mVertices[vertexIndex].z );
                normals_[currentIndex + i]      = glm::vec3( mesh->mNormals[vertexIndex].x, mesh->mNormals[vertexIndex].y, mesh->mNormals[vertexIndex].z );
            

            if (mesh->HasTextureCoords(0)) 
                textureCoordinates_[currentIndex + i] = glm::vec2( mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y );
            

            //utilities::AssImpUtilities::color4_to_vec4(&mesh->mColors[0][vertexIndex], colors_[colors_.size() + i]);
            if (mesh->mColors[0] != 0) 
                colors_[currentIndex + i]           = glm::vec4(
                                                        (float)mesh->mColors[0][vertexIndex].a,
                                                        (float)mesh->mColors[0][vertexIndex].b,
                                                        (float)mesh->mColors[0][vertexIndex].g,
                                                        (float)mesh->mColors[0][vertexIndex].r
                                                    );
                       
        

        currentIndex += 3;
    

这是加载纹理的代码:

void Texture::loadTexture(utilities::Image* image) 
glGenTextures(1, &textureId_);

    glBindTexture(GL_TEXTURE_2D, textureId_);

    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    // i don't combine the color with the original surface color, use only the texture map.
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

这是模型的渲染代码:

for (uint32 i=0; i < meshes_.size(); i++) 
        textures_[i]->bind();
        meshes_[i]->render();
    

这是纹理的“绑定”代码:

void Texture::bind() 
glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable( GL_TEXTURE_2D );
    glBindTexture(GL_TEXTURE_2D, textureId_);

最后,这是 Mesh 的渲染代码:

void Mesh::render() 
glBegin( GL_TRIANGLES );

    for (uint32 i = 0; i < vertices_.size(); i++) 
        glTexCoord2fv( &textureCoordinates_[i].x );
        glVertex3fv( &vertices_[i].x );
        glNormal3fv( &normals_[i].x );
    

    glEnd();

我没有看到任何明显的错误。有没有人看到我做错了什么??

【问题讨论】:

你能告诉我们纹理应该是什么样子吗?也许在正确渲染时上传它的图像? @Tommy 当然 - 现已添加。 纹理在映射到对象之前是什么样子的? 哇,那真是太离谱了。嗯,你肯定需要反转 y - OpenGL 是方格纸样式,OBJ 是英文阅读顺序样式 - 但除此之外,是否有可能是因为有效地丢弃了网格颜色? @JohnD,我不确定纹理图像上的许可证是什么,所以我宁愿不发布:\ 【参考方案1】:

GAH,我想通了...问题是在加载网格时:

for(uint32 i = 0; i < numIndices; i++) 
            // get group index for current index
            int vertexIndex = face->mIndices[i];

            ...

            if (mesh->HasTextureCoords(0)) 
                textureCoordinates_[currentIndex + i] = glm::vec2( mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y );
            

            ...
                       
        

应该使用mesh-&gt;mTextureCoords[0][vertexIndex].x 而不是mesh-&gt;mTextureCoords[0][i].x(对于 y 索引也是如此)...

所以,只是在每个循环中使用了错误的纹理坐标索引,因此纹理坐标对于每个正在渲染的三角形都是相同的 3 个坐标:S

感谢所有关注此问题的人!

【讨论】:

以上是关于opengl 纹理无法正确渲染的主要内容,如果未能解决你的问题,请参考以下文章

为什么我的2D OpenGL纹理无法正确加载? [关闭]

无法使用 OpenGL 渲染 FBX 导入的纹理模型

无法从 OpenGL 中的着色器访问先前渲染的纹理

OpenGL - 纹理加载不正确

OpenGL + QT:渲染到纹理并显示回来

OpenGL不使用纹理渲染