【问题标题】:OpenGL Skybox rendering wrongOpenGL Skybox 渲染错误
【发布时间】:2016-01-24 07:08:59
【问题描述】:

我正在尝试实现一个天空盒,然后使用天空盒的立方体贴图在我的场景中制作一个反射球体,并使用我找到的一些代码进行编辑以适合我的项目。天空盒显示,但图像看起来几乎损坏,有山脉的基本轮廓,但没有颜色,如您在图像中看到的那样。 http://i.imgur.com/kJT4aCV.jpg 我一直在努力确保活动纹理和我的着色器是正确的,但我就是想不通。

顶点和片段着色器

#version 330 core
layout (location = 0) in vec3 position;
out vec3 TexCoords;

uniform mat4 projection;
uniform mat4 view;


void main()
{
   vec4 pos = projection * view * vec4(position, 1.0);
   gl_Position = pos.xyww;
   TexCoords = position;
}  
#version 330 core
in vec3 TexCoords;
out vec4 color;

uniform samplerCube skybox;

void main()
{    
    color = texture(skybox, TexCoords);
}

加载立方体贴图

GLuint loadCubemap(std::vector<const GLchar*> faces)
{
    GLuint textureID;
    glGenTextures(1, &textureID);

    int width, height, numComponents;
    unsigned char* image;

    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
    for (GLuint i = 0; i < faces.size(); i++)
    {
        image = stbi_load(faces[i], &width, &height, &numComponents, 4);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
        stbi_image_free(image);
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    return textureID;
}

绘制天空盒

            glDepthFunc(GL_LEQUAL);  
            skyShader.Bind();
            skyShader.Update(transform, camera);
            view = glm::mat4(glm::mat3(camera.GetViewProjection()));
            glUniformMatrix4fv(glGetUniformLocation(skyShader.getProg(), "view"), 1, GL_FALSE, glm::value_ptr(view));
            glUniformMatrix4fv(glGetUniformLocation(skyShader.getProg(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));

            glBindVertexArray(skyboxVAO);
            glActiveTexture(GL_TEXTURE0);
            glUniform1i(glGetUniformLocation(skyShader.getProg(), "skybox"), 0);
            glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);
            glDrawArrays(GL_TRIANGLES, 0, 36);
            glBindVertexArray(0);
            glDepthFunc(GL_LESS);

让我知道是否还有其他有用的部分可以查看

【问题讨论】:

  • 我自己是 OpenGL 的初学者,所以我很可能是错的,但这看起来与读取纹理的方式以及 OpenGL 解释它的方式不匹配。我从未使用过 stb,但看起来您可能正在读取每个像素 4 个组件的纹理,但随后将其作为每个像素 3 个组件馈送到 OpenGL,导致每个第 3 个组件被解释为红色而不是 alpha,或者其他类似的东西那些行。
  • 你完全正确!我只是将其更改为 image = stbi_load(faces[i], &width, &height, &numComponents, 3);并解决了,非常感谢
  • 很高兴能帮上忙!
  • 我在尝试使用相同的立方体贴图进行反射时遇到了更多问题,可能又错过了一些小东西,因为我对此很陌生:stackoverflow.com/questions/34970832/…
  • 抱歉,希望我能用图形做到这一点。我在很久以后才做天空盒。现在我只关注基本纹理,我正在尝试找出照明模型和材质

标签: c++ opengl


【解决方案1】:

纹理被读入,并以每个像素的组件数量不一致的方式馈送到 OpenGL

image = stbi_load(faces[i], &amp;width, &amp;height, &amp;numComponents, 4);用4个组件读入图像

但是当你把它输入到 OpenGL 时,glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); 你把它作为一个纹理输入,每个像素有 3 个分量,导致每 4 个字节被解释为红色,而它本应该是别的东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2021-01-29
    相关资源
    最近更新 更多