深度测试丢弃自定义帧缓冲区上的片段
Depth test discards fragments on custom framebuffer
在我的程序中,我将多个矩阵渲染到不同的帧缓冲区。最后,我将帧缓冲区创建的纹理渲染为三个 2D 四边形。问题是深度测试丢弃了自定义帧缓冲区的所有片段,除了第一个被渲染的片段。
这里我初始化帧缓冲区:
unsigned int* framebufferArray = new unsigned int[(input_view.size()+output_view.size()+1)];
unsigned int* framebufferTextureArray = new unsigned int[(input_view.size() + output_view.size() + 1)];
for (int i = 0; i < (input_view.size()+output_view.size()+1); ++i)
{
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
unsigned int fBufferTexture;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
unsigned int fBufferTexture;
glGenTextures(1, &fBufferTexture);
glBindTexture(GL_TEXTURE_2D, fBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window_width, window_height, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fBufferTexture, 0);
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, window_width, window_height); // use a single renderbuffer object for both a depth AND stencil buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it
// now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
framebufferArray[i] = framebuffer;
framebufferTextureArray[i] = fBufferTexture;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
我在这里渲染矩阵:
for (int i = 0; i < input_view.size(); ++i)
{
float alphaFactor = 1;
glBindFramebuffer(GL_FRAMEBUFFER, framebufferArray[i + 1]);
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glUseProgram(solidShaderID);
std::vector<float> Cachecolor = { CacheColorInfo[cacheLayerCount - 1][0], CacheColorInfo[cacheLayerCount - 1][1], CacheColorInfo[cacheLayerCount - 1][2] };
glBindTexture(GL_TEXTURE_2D, solidTexture);
mat4 translationMatrix = glm::translate(mat4(1.0f), glm::vec3(ThreadTranslateVector[0], ThreadTranslateVector[1], ThreadTranslateVector[2] + 6));
glUniformMatrix4fv(glGetUniformLocation(solidShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glUniform3fv(glGetUniformLocation(solidShaderID, "tint"), 1, &Cachecolor[0]);
glUniform1f(glGetUniformLocation(solidShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);
glBindVertexArray(inputViewVAOs[i][1]);
glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][1] * 3);
glBindVertexArray(0);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(transShaderID);
glBindTexture(GL_TEXTURE_2D, transparentTexture);
translationMatrix = glm::translate(mat4(1.0f), vec3(0, matsizeN, 0));
glUniformMatrix4fv(glGetUniformLocation(transShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glUniform3fv(glGetUniformLocation(transShaderID, "tint"), 1, &matColor[0]);
glUniform1f(glGetUniformLocation(transShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);
glUniform1fv(glGetUniformLocation(transShaderID, "alphaFac"), 1, &alphaFactor);
glBindVertexArray(inputViewVAOs[i][0]);
glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][0] * 3);
glBindVertexArray(0);
}
这里我渲染了三个四边形:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[0]);
glUseProgram(matrix2dShaderID);
mat4 translationMatrix = glm::mat4(1.0f);
//translationMatrix = glm::translate(translationMatrix, glm::vec3((float)(window_width - 200) / (float)window_width, 0, 0));
translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0.6,0));
translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize/(float)window_height,(float)viewSize/(float)window_height,1));
glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[1]);
glUseProgram(matrix2dShaderID);
translationMatrix = glm::mat4(1.0f);
translationMatrix = glm::translate(translationMatrix, glm::vec3(0, -0.6, 0));
translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[2]);
glUseProgram(matrix2dShaderID);
translationMatrix = glm::mat4(1.0f);
translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0, 0));
translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
这是启用深度测试的输出:
并且禁用了深度测试:
似乎深度测试只是丢弃了第一个帧缓冲区之后的所有内容。
问题是由于禁用写入深度缓冲区引起的:
glDepthMask(GL_FALSE);
glDepthMask
sets a global state and specifies whether a depth buffer is enabled or disabled for writing. This also effects operations glClear
。如果深度缓冲区被禁止写入,那么深度缓冲区也不能被清除。
请注意,状态是全局的,并且会一直保留到再次更改为止。当调用 glClear
时,将评估 glDepthMask
标志的当前状态。
启用写入深度缓冲区,清除前:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
在我的程序中,我将多个矩阵渲染到不同的帧缓冲区。最后,我将帧缓冲区创建的纹理渲染为三个 2D 四边形。问题是深度测试丢弃了自定义帧缓冲区的所有片段,除了第一个被渲染的片段。
这里我初始化帧缓冲区:
unsigned int* framebufferArray = new unsigned int[(input_view.size()+output_view.size()+1)];
unsigned int* framebufferTextureArray = new unsigned int[(input_view.size() + output_view.size() + 1)];
for (int i = 0; i < (input_view.size()+output_view.size()+1); ++i)
{
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
unsigned int fBufferTexture;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
unsigned int fBufferTexture;
glGenTextures(1, &fBufferTexture);
glBindTexture(GL_TEXTURE_2D, fBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window_width, window_height, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fBufferTexture, 0);
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, window_width, window_height); // use a single renderbuffer object for both a depth AND stencil buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it
// now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
framebufferArray[i] = framebuffer;
framebufferTextureArray[i] = fBufferTexture;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
我在这里渲染矩阵:
for (int i = 0; i < input_view.size(); ++i)
{
float alphaFactor = 1;
glBindFramebuffer(GL_FRAMEBUFFER, framebufferArray[i + 1]);
glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glUseProgram(solidShaderID);
std::vector<float> Cachecolor = { CacheColorInfo[cacheLayerCount - 1][0], CacheColorInfo[cacheLayerCount - 1][1], CacheColorInfo[cacheLayerCount - 1][2] };
glBindTexture(GL_TEXTURE_2D, solidTexture);
mat4 translationMatrix = glm::translate(mat4(1.0f), glm::vec3(ThreadTranslateVector[0], ThreadTranslateVector[1], ThreadTranslateVector[2] + 6));
glUniformMatrix4fv(glGetUniformLocation(solidShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glUniform3fv(glGetUniformLocation(solidShaderID, "tint"), 1, &Cachecolor[0]);
glUniform1f(glGetUniformLocation(solidShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);
glBindVertexArray(inputViewVAOs[i][1]);
glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][1] * 3);
glBindVertexArray(0);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(transShaderID);
glBindTexture(GL_TEXTURE_2D, transparentTexture);
translationMatrix = glm::translate(mat4(1.0f), vec3(0, matsizeN, 0));
glUniformMatrix4fv(glGetUniformLocation(transShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glUniform3fv(glGetUniformLocation(transShaderID, "tint"), 1, &matColor[0]);
glUniform1f(glGetUniformLocation(transShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);
glUniform1fv(glGetUniformLocation(transShaderID, "alphaFac"), 1, &alphaFactor);
glBindVertexArray(inputViewVAOs[i][0]);
glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][0] * 3);
glBindVertexArray(0);
}
这里我渲染了三个四边形:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[0]);
glUseProgram(matrix2dShaderID);
mat4 translationMatrix = glm::mat4(1.0f);
//translationMatrix = glm::translate(translationMatrix, glm::vec3((float)(window_width - 200) / (float)window_width, 0, 0));
translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0.6,0));
translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize/(float)window_height,(float)viewSize/(float)window_height,1));
glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[1]);
glUseProgram(matrix2dShaderID);
translationMatrix = glm::mat4(1.0f);
translationMatrix = glm::translate(translationMatrix, glm::vec3(0, -0.6, 0));
translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[2]);
glUseProgram(matrix2dShaderID);
translationMatrix = glm::mat4(1.0f);
translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0, 0));
translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
这是启用深度测试的输出:
并且禁用了深度测试:
似乎深度测试只是丢弃了第一个帧缓冲区之后的所有内容。
问题是由于禁用写入深度缓冲区引起的:
glDepthMask(GL_FALSE);
glDepthMask
sets a global state and specifies whether a depth buffer is enabled or disabled for writing. This also effects operations glClear
。如果深度缓冲区被禁止写入,那么深度缓冲区也不能被清除。
请注意,状态是全局的,并且会一直保留到再次更改为止。当调用 glClear
时,将评估 glDepthMask
标志的当前状态。
启用写入深度缓冲区,清除前:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);