渲染透明物体

Rendering transparent objects

我正在尝试通过使用 alpha 值调整对象的半透明度来制作玻璃平面。目前,它是一个黑色平面,因为我的 alpha 值对我的对象没有影响。请看图:

glEnable(GL_BLEND); 什么都不做

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); 让我的所有物品消失

fragment shader:

#version 330 core

// interpolated values from the vertex shaders
in vec3 vNormal;
in vec3 vPosition;
in vec2 vTexCoord;

// uniform input data
struct LightProperties
{
    vec4 position;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    float shininess;
};

struct MaterialProperties
{
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
};

uniform LightProperties uLightingProperties;
uniform MaterialProperties uMaterialProperties;
uniform vec3 uViewPoint;

uniform sampler2D uTextureSampler;

// uniform input data
uniform float uAlpha;

// output data
out vec4 fColor;

void main()
{
    // calculate vectors for lighting
    vec3 N = normalize(vNormal);
    vec3 L;

    // determine whether the light is a point light source or directional light
    if(uLightingProperties.position.w == 0.0f)
        L = normalize((uLightingProperties.position).xyz);
    else
        L = normalize((uLightingProperties.position).xyz - vPosition);

    vec3 V = normalize(uViewPoint - vPosition);
    vec3 R = reflect(-L, N);

    vec3 colour = vec3(0.0f, 0.0f, 0.0f);

    // calculate Phong lighting
    vec4 ambient = uLightingProperties.ambient * uMaterialProperties.ambient;
    vec4 diffuse = uLightingProperties.diffuse * uMaterialProperties.diffuse * max(dot(L, N), 0.0);
    vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f);

    if(dot(L, N) > 0.0f)
    {
        specular = uLightingProperties.specular * uMaterialProperties.specular 
            * pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
    }

    // set output color
    colour = (diffuse + specular + ambient).rgb;    
    colour *= texture(uTextureSampler, vTexCoord).rgb;
    fColor = vec4(colour, uAlpha);
    //fColor = texture(uTextureSampler, vTexCoord).rgb;
}

这给了我一个不透明的黑色平面,而我想要的是半透明的黑色平面。

static void init(GLFWwindow* window)
{
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    //glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
    //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);

    // read image data
    g_texImage[0] = readBitmapRGBImage("images/check.bmp", &imageWidth[0], &imageHeight[0]);
    g_texImage[1] = readBitmapRGBImage("images/smile.bmp", &imageWidth[1], &imageHeight[1]);
    g_texImage[2] = readBitmapRGBImage("images/Fieldstone.bmp", &imageWidth[2], &imageHeight[2]);
    g_texImage[3] = readBitmapRGBImage("images/sunflower.bmp", &imageWidth[3], &imageHeight[3]);
    g_texImage[4] = readBitmapRGBImage("images/painting.bmp", &imageWidth[4], &imageHeight[4]);

    // create and compile GLSL program from the shader files
    g_shaderProgramID[0] = loadShaders("vertex_shaderL.vert", "fragment_shaderL.frag");
    g_shaderProgramID[1] = loadShaders("vertex_shaderT.vert", "fragment_shaderT.frag");

    // find the locations of shader variables
    GLuint positionIndex[2];
    positionIndex[0] = glGetAttribLocation(g_shaderProgramID[0], "aPosition");
    GLuint normalIndex = glGetAttribLocation(g_shaderProgramID[0], "aNormal");
    GLuint texCoordIndex = glGetAttribLocation(g_shaderProgramID[0], "aTexCoord");

    g_MVP_Index = glGetUniformLocation(g_shaderProgramID[0], "uModelViewProjectionMatrix");
    g_M_Index = glGetUniformLocation(g_shaderProgramID[0], "uModelMatrix");
    g_viewPointIndex = glGetUniformLocation(g_shaderProgramID[0], "uViewPoint");
    g_alphaIndex = glGetUniformLocation(g_shaderProgramID[0], "uAlpha");

    g_texSampler_Index[0] = glGetUniformLocation(g_shaderProgramID[0], "uTextureSampler");

    g_lightPositionIndex = glGetUniformLocation(g_shaderProgramID[0], "uLightingProperties.position");
    g_lightAmbientIndex = glGetUniformLocation(g_shaderProgramID[0], "uLightingProperties.ambient");
    g_lightDiffuseIndex = glGetUniformLocation(g_shaderProgramID[0], "uLightingProperties.diffuse");
    g_lightSpecularIndex = glGetUniformLocation(g_shaderProgramID[0], "uLightingProperties.specular");
    g_lightShininessIndex = glGetUniformLocation(g_shaderProgramID[0], "uLightingProperties.shininess");

    g_materialAmbientIndex = glGetUniformLocation(g_shaderProgramID[0], "uMaterialProperties.ambient");
    g_materialDiffuseIndex = glGetUniformLocation(g_shaderProgramID[0], "uMaterialProperties.diffuse");
    g_materialSpecularIndex = glGetUniformLocation(g_shaderProgramID[0], "uMaterialProperties.specular");

    positionIndex[1] = glGetAttribLocation(g_shaderProgramID[1], "aPosition");
    g_texSampler_Index[1] = glGetUniformLocation(g_shaderProgramID[1], "uTextureSampler");
    g_renderDepth_Index = glGetUniformLocation(g_shaderProgramID[1], "uRenderDepth");

    // initialise model matrices
    g_mm_floor = translate(vec3(0.2f, -4.0f, 0.0f));
    g_mm_cube = translate(vec3(0.0f, -4.0f, 0.0f)) * scale(vec3(2.0f, 2.0f, 2.0f));
    for (int i = 0; i < 4; i++)
    {
        g_mm_wall[i] = mat4(1.0f);
    }
    g_mm_painting[0] = mat4(1.0f);
    g_mm_painting[1] = mat4(1.0f);
    g_mm_glass = mat4(1.0f);
    g_mm_torus = mat4(1.0f);

    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    float aspectRatio = static_cast<float>(width) / height;

    // camera
    g_camera.setViewMatrix(vec3(0, 1, 10), vec3(0, 0, -10), vec3(0, 1, 0));
    g_camera.setProjectionMatrix(perspective(45.0f, aspectRatio, 0.1f, 100.0f));

    // initialise light and material properties
    g_lightProperties.position = vec4(7.0f, 5.0f, 0.0f, 1.0f);
    g_lightProperties.ambient = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_lightProperties.diffuse = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_lightProperties.specular = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_lightProperties.shininess = 10.0f;

    g_materialProperties[0].ambient = vec4(0.3f, 0.3f, 0.3f, 1.0f);
    g_materialProperties[0].diffuse = vec4(0.8f, 0.8f, 0.4f, 1.0f);
    g_materialProperties[0].specular = vec4(0.8f, 0.8f, 0.4f, 1.0f);

    g_materialProperties[1].ambient = vec4(0.3f, 0.3f, 0.3f, 1.0f);
    g_materialProperties[1].diffuse = vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties[1].specular = vec4(0.2f, 0.7f, 1.0f, 1.0f);

    g_materialProperties[2].ambient = vec4(0.3f, 0.3f, 0.3f, 1.0f);
    g_materialProperties[2].diffuse = vec4(0.2f, 0.7f, 0.2f, 1.0f);
    g_materialProperties[2].specular = vec4(0.2f, 0.7f, 0.2f, 1.0f);

    // generate identifier for texture object and set texture properties
    // checkered floor
    glGenTextures(10, g_textureID);
    glBindTexture(GL_TEXTURE_2D, g_textureID[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth[0], imageHeight[0], 0, GL_BGR, GL_UNSIGNED_BYTE, g_texImage[0]);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // smiley face
    glBindTexture(GL_TEXTURE_2D, g_textureID[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth[1], imageHeight[1], 0, GL_BGR, GL_UNSIGNED_BYTE, g_texImage[1]);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // fieldstone wallpaper
    glBindTexture(GL_TEXTURE_2D, g_textureID[2]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth[2], imageHeight[2], 0, GL_BGR, GL_UNSIGNED_BYTE, g_texImage[2]);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // sunflower painting
    glBindTexture(GL_TEXTURE_2D, g_textureID[3]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth[3], imageHeight[3], 0, GL_BGR, GL_UNSIGNED_BYTE, g_texImage[3]);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // other painting
    glBindTexture(GL_TEXTURE_2D, g_textureID[4]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth[4], imageHeight[4], 0, GL_BGR, GL_UNSIGNED_BYTE, g_texImage[4]);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // textures to be rendered to (i.e. render-to-texture)
    glBindTexture(GL_TEXTURE_2D, g_textureID[6]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, g_windowWidth, g_windowHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glBindTexture(GL_TEXTURE_2D, g_textureID[7]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, g_windowWidth, g_windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // set up framebuffer object
    glGenFramebuffers(1, &g_FBO);
    glBindFramebuffer(GL_FRAMEBUFFER, g_FBO);

    GLuint depthRenderBufferID;
    glGenRenderbuffers(1, &depthRenderBufferID);
    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBufferID);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, g_windowWidth, g_windowHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBufferID);

    // associate respective textures with framebuffer attachments
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, g_textureID[6], 0);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, g_textureID[7], 0);

    // number of draw buffers
    GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
    glDrawBuffers(1, drawBuffers);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        exit(EXIT_FAILURE);

    // generate identifier for VBOs and copy data to GPU
    glGenBuffers(10, g_VBO);
    glGenVertexArrays(10, g_VAO);

    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);

    glBindVertexArray(g_VAO[0]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
    glVertexAttribPointer(positionIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
    glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
    glVertexAttribPointer(texCoordIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, texCoord)));

    glEnableVertexAttribArray(positionIndex[0]);
    glEnableVertexAttribArray(normalIndex);
    glEnableVertexAttribArray(texCoordIndex);

    // to display the render-to-texture's texture on a screen space quad
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_screenspaceQuad), g_screenspaceQuad, GL_STATIC_DRAW);

    glBindVertexArray(g_VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
    glVertexAttribPointer(positionIndex[1], 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(positionIndex[1]);

    // torus mesh
    load_mesh("models/torus.obj", 0);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices[0], g_pMeshVertices[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[3]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces[0], g_pMeshIndices[0], GL_STATIC_DRAW);

    glBindVertexArray(g_VAO[2]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[3]);
    glVertexAttribPointer(positionIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
    glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));

    glEnableVertexAttribArray(positionIndex[0]);
    glEnableVertexAttribArray(normalIndex);
}

static void render_scene()
{
    // draw to frame buffer object
    glBindFramebuffer(GL_FRAMEBUFFER, g_FBO);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(g_shaderProgramID[0]);

    glBindVertexArray(g_VAO[0]);

    // set lighting properties
    glUniform4fv(g_lightPositionIndex, 1, &g_lightProperties.position[0]);
    glUniform4fv(g_lightAmbientIndex, 1, &g_lightProperties.ambient[0]);
    glUniform4fv(g_lightDiffuseIndex, 1, &g_lightProperties.diffuse[0]);
    glUniform4fv(g_lightSpecularIndex, 1, &g_lightProperties.specular[0]);
    glUniform1fv(g_lightShininessIndex, 1, &g_lightProperties.shininess);

    // set uniform shader variables
    mat4 MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_glass;
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_glass[0][0]);
    glUniform1f(g_alphaIndex, 0.5);

    // set material properties
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[0].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[0].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[0].specular[0]);

    // draw glass
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // set uniform shader variables
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_cube;
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_cube[0][0]);
    glUniform1f(g_alphaIndex, 1.0);

    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[2].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[2].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[2].specular[0]);

    // draw cube
    glBindTexture(GL_TEXTURE_2D, g_textureID[1]);
    glDrawArrays(GL_TRIANGLES, 6, 36);

    // set uniform shader variables
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_floor;
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_floor[0][0]);
    glUniform1f(g_alphaIndex, 1.0);

    // set material properties
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[0].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[0].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[0].specular[0]);

    // draw floor
    glBindTexture(GL_TEXTURE_2D, g_textureID[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    for (int i = 0; i < 3; i++)
    {
        // set uniform shader variables
        MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_wall[i];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_wall[i][0][0]);
        glUniform1f(g_alphaIndex, 1.0);

        // set material properties
        glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[1].ambient[0]);
        glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[1].diffuse[0]);
        glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[1].specular[0]);

        // draw walls
        glBindTexture(GL_TEXTURE_2D, g_textureID[2]);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }

    // set uniform shader variables
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_painting[0];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_painting[0][0][0]);
    glUniform1f(g_alphaIndex, 1.0);

    // set material properties
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[2].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[2].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[2].specular[0]);

    // draw apples painting
    glBindTexture(GL_TEXTURE_2D, g_textureID[3]);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // set uniform shader variables
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_painting[1];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_painting[1][0][0]);
    glUniform1f(g_alphaIndex, 1.0);

    // set material properties
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[2].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[2].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[2].specular[0]);

    // draw other painting
    if (newpainting == false)
        glBindTexture(GL_TEXTURE_2D, g_textureID[4]);
    else
        glBindTexture(GL_TEXTURE_2D, g_textureID[5]);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // set uniform shader variables
    glBindVertexArray(g_VAO[2]);
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_torus;
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_mm_torus[0][0]);
    glUniform1f(g_alphaIndex, 1.0);

    // set material properties
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties[0].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties[0].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties[0].specular[0]);

    // draw torus
    glDrawElements(GL_TRIANGLES, g_numberOfFaces[0] * 3, GL_UNSIGNED_INT, 0);

    // draw to normal display
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(g_shaderProgramID[1]);

    glBindVertexArray(g_VAO[1]);

    glUniform1i(g_texSampler_Index[1], 0);

    // draw screenspace quad
    glActiveTexture(GL_TEXTURE0);

    if (g_bRenderDepth)
    {
        glUniform1i(g_renderDepth_Index, 1);
        glBindTexture(GL_TEXTURE_2D, g_textureID[7]);
    }
    else
    {
        glUniform1i(g_renderDepth_Index, 0);
        glBindTexture(GL_TEXTURE_2D, g_textureID[6]);
    }

    glDrawArrays(GL_TRIANGLES, 0, 6);

    glFlush();
}

渲染透明对象时,以正确的顺序渲染所有内容很重要。即:

  1. 渲染所有不透明对象
  2. 渲染所有透明对象(如果有多个,则必须将它们从后向前排序。

目前,您首先渲染玻璃对象,这会在深度缓冲区中设置深度值。永远不会绘制玻璃后面的所有对象,因为它们未通过 z 检验。