我如何在 OpenGL 中拥有 2 个天空盒?

问题描述

我正在尝试制作一个可以通过按钮改变的天空盒。 我对此的解决方案是通过以下方式绑定我的天空盒并加载我的纹理:

//SkyBox
    gluint skyBoxVBO,skyBoxVAO;
    glGenVertexArrays(1,&skyBoxVAO);
    glGenBuffers(1,&skyBoxVBO);
    glBindVertexArray(skyBoxVAO);
    glBindBuffer(GL_ARRAY_BUFFER,skyBoxVBO);
    glBufferData(GL_ARRAY_BUFFER,sizeof(skyBoxVertices),&skyBoxVertices,GL_STATIC_DRAW);
    glEnabLevertexAttribArray(0);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3 * sizeof(GLfloat),(GLvoid *)0);

    // Load textures
    vector<const GLchar*> facesN;
    facesN.push_back("SkyBox/night/right.tga");
    facesN.push_back("SkyBox/night/left.tga");
    facesN.push_back("SkyBox/night/top.tga");
    facesN.push_back("SkyBox/night/bottom.tga");
    facesN.push_back("SkyBox/night/back.tga");
    facesN.push_back("SkyBox/night/front.tga");

    gluint cubemapTextureN = TextureLoading::LoadCubemap(facesN);

    vector<const GLchar*> faces;
    faces.push_back("SkyBox/day/right.tga");
    faces.push_back("SkyBox/day/left.tga");
    faces.push_back("SkyBox/day/top.tga");
    faces.push_back("SkyBox/day/bottom.tga");
    faces.push_back("SkyBox/day/back.tga");
    faces.push_back("SkyBox/day/front.tga");

    gluint cubemapTexture = TextureLoading::LoadCubemap(faces);

然后,在程序循环中,我使用以下内容绘制天空盒:

// Draw skyBox as last
        glDepthFunc(GL_LEQUAL);  // Change depth function so depth test passes when values are equal to depth buffer's content
        SkyBoxshader.Use();
        view = glm::mat4(glm::mat3(camera.GetViewMatrix()));    // Remove any translation component of the view matrix
        gluniformMatrix4fv(glGetUniformlocation(SkyBoxshader.Program,"view"),1,glm::value_ptr(view));
        gluniformMatrix4fv(glGetUniformlocation(SkyBoxshader.Program,"projection"),glm::value_ptr(projection));

        // skyBox cube
        glBindVertexArray(skyBoxVAO);
        glActiveTexture(GL_TEXTURE1);
        if (daytime == 1.0f) {
            glBindTexture(GL_TEXTURE_CUBE_MAP,cubemapTexture);
        }
        else {
            glBindTexture(GL_TEXTURE_CUBE_MAP,cubemapTextureN);
        }
        glDrawArrays(GL_TRIANGLES,36);
        glBindVertexArray(0);
        glDepthFunc(GL_LESS); // Set depth function back to default

理论上,每当我按下更改 daytime 值的按钮时,天空盒都应将其纹理更改为 cubemapTextureN,然后再次按下该按钮,更改回 {{1} }.相反,它只是绘制最后加载的纹理,在本例中为 cubemapTexture。 我已经测试了 cubemapTexture 并且它确实发生了变化,所以不是那样。

另外,我尝试在 daytime 之后加载 cubemapTextureN 并且这样做 cubemapTexture 被绘制,但仍然没有变化。我假设在加载第二个纹理时,第一个纹理得到更新,这不应该发生,因为它们有不同的名称,除非我理解错了。

简单的解决方案是制作整个天空盒的模型并使用它,但如果可能的话,我想看看我是否可以使用这个解决方案。

编辑: 这些是天空盒的着色器。 片段着色器:

cubemapTextureN

顶点着色器:

#version 330 core
in vec3 TexCoords;
out vec4 color;

uniform samplerCube skyBox;

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

以及它们的用途: #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; }

另外,如果这有用的话,这是具有Shader SkyBoxshader("Shaders/SkyBox.vs","Shaders/SkyBox.frag");定义的标题,其中包含TextureLoading

LoadCubemap

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)