OpenTK GlControl,深度剥离,黑色视口
OpenTK GlControl, depth peeling, black viewport
我正在使用 OpenTK 在 c# 中制作一个 opengl 程序,实现简单对象的透明效果,使用深度剥离算法。在 NVIDIA 的网络中有一个 depth peeling 的示例代码,在 c++ 中,我对其进行了简化并且工作正常。但是当我将代码移植到 c# 时,视口变成纯黑色。我多次比较c++和c#代码,不认为代码有任何问题或意外差异。
渲染循环:
while (!done)
{
/* --------------------------------------------------------------------- */
/* 1. Peel the first layer */
/* --------------------------------------------------------------------- */
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glUseProgram(program_shaderPeelingInit);
// setUniform1f()
glUniform1f(glGetUniformLocation(program_shaderPeelingInit, "uAlpha"), opacity);
drawModel(program_shaderPeelingInit);
glUseProgram(0);
/* --------------------------------------------------------------------- */
/* 2. Depth Peeling + Blending */
/* --------------------------------------------------------------------- */
for (int32_t layer = 1; true && layer < MAX_PEELED_LAYERS; layer++)
{
/* --------------------------------------------------------------------- */
/* 2.1. Peel the next depth layer */
/* --------------------------------------------------------------------- */
int32_t currId = layer % 2;
int32_t prevId = 1 - currId;
glBindFramebuffer(GL_FRAMEBUFFER, frontFboId[currId]);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBeginQuery(GL_SAMPLES_PASSED, queryId);
glUseProgram(program_shaderPeelingPeel);
// bindTextureRect()
glUniform1i(glGetUniformLocation(program_shaderPeelingPeel, "DepthTex"), 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontDepthTexId[prevId]);
// setUniform1f()
glUniform1f(glGetUniformLocation(program_shaderPeelingPeel, "uAlpha"), opacity);
drawModel(program_shaderPeelingPeel);
glUseProgram(0);
glEndQuery(GL_SAMPLES_PASSED);
/* --------------------------------------------------------------------- */
/* 2.2. Blend the current layer */
/* --------------------------------------------------------------------- */
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
// UNDER operator
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE,
GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(program_shaderPeelingBlend);
// bindTextureRect()
glUniform1i(glGetUniformLocation(program_shaderPeelingBlend, "TempTex"), 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontColorTexId[currId]);
// renderFullscreenQuad()
glUniformMatrix4fv(glGetUniformLocation(program_shaderPeelingBlend, "uModelViewMatrix"), 1, false, glm::value_ptr(glm::mat4()));
drawQuadGL(0);
glUseProgram(0);
glDisable(GL_BLEND);
GLuint sample_count;
glGetQueryObjectuiv(queryId, GL_QUERY_RESULT, &sample_count);
if (sample_count == 0)
{
break;
}
}
/* --------------------------------------------------------------------- */
/* 3. Compositing Pass */
/* --------------------------------------------------------------------- */
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
glDisable(GL_DEPTH_TEST);
glUseProgram(program_shaderPeelingFinal);
// setUniform3f()
glUniform3f(glGetUniformLocation(program_shaderPeelingFinal, "uBackgroundColor"),
backgroundColor[0], backgroundColor[1], backgroundColor[2]);
// bindTextureRect()
glUniform1i(glGetUniformLocation(program_shaderPeelingFinal, "ColorTex"), 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontColorBlenderTexId);
// renderFullscreenQuad()
glUniformMatrix4fv(glGetUniformLocation(program_shaderPeelingFinal, "uModelViewMatrix"), 1, false, glm::value_ptr(glm::mat4()));
drawQuadGL(0);
glUseProgram(0);
}
初始化:
glGenTextures(2, frontDepthTexId);
glGenTextures(2, frontColorTexId);
glGenFramebuffers(2, frontFboId);
for (int i = 0; i < 2; i++)
{
glBindTexture(GL_TEXTURE_RECTANGLE, frontDepthTexId[i]);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT32F_NV,
WIDTH, HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE, frontColorTexId[i]);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, WIDTH, HEIGHT,
0, GL_RGBA, GL_FLOAT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, frontFboId[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_RECTANGLE, frontDepthTexId[i], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_RECTANGLE, frontColorTexId[i], 0);
}
glGenTextures(1, &frontColorBlenderTexId);
glBindTexture(GL_TEXTURE_RECTANGLE, frontColorBlenderTexId);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, WIDTH, HEIGHT,
0, GL_RGBA, GL_FLOAT, 0);
glGenFramebuffers(1, &frontColorBlenderFboId);
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_RECTANGLE, frontDepthTexId[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_RECTANGLE, frontColorBlenderTexId, 0);
绘制函数:
void drawModel(GLuint program)
{
glUniformMatrix4fv(glGetUniformLocation(program, "uNormalMatrix"), 1, false, glm::value_ptr(normalMat));
glUniformMatrix4fv(glGetUniformLocation(program, "uModelViewMatrix"), 1, false, glm::value_ptr(mvp));
glBindVertexArray(cubesVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
numGeoPasses++;
}
void drawQuadGL(GLuint posIndex)
{
const float position[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);
glEnableVertexAttribArray(posIndex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(posIndex);
}
当我用 opengl 调试器(RenderDoc 和 apitrace)调试我的 exe 时,它告诉我渲染很好,即纹理对象填充了所需的图像,但我不知道为什么场景是黑色的: (
谁能告诉我我的代码有什么问题吗?或者有什么想法?提前致谢
如果需要任何其他详细信息,请告诉我编辑问题。
问题已解决。
问题是关于 OpenGL 版本的,它的作用是函数 drawQuadGL(GLuint posIndex)
在这一行:
glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);
这个函数可以得到两种类型的输入,作为最后一个参数。它可以获取指向数组的指针,或获取一个整数作为偏移量。从 OpenGL 版本 3.2 开始,指针类型已被弃用。所以,我将最后一个参数更改为 0
并解决了问题。
我正在使用 OpenTK 在 c# 中制作一个 opengl 程序,实现简单对象的透明效果,使用深度剥离算法。在 NVIDIA 的网络中有一个 depth peeling 的示例代码,在 c++ 中,我对其进行了简化并且工作正常。但是当我将代码移植到 c# 时,视口变成纯黑色。我多次比较c++和c#代码,不认为代码有任何问题或意外差异。
渲染循环:
while (!done)
{
/* --------------------------------------------------------------------- */
/* 1. Peel the first layer */
/* --------------------------------------------------------------------- */
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glUseProgram(program_shaderPeelingInit);
// setUniform1f()
glUniform1f(glGetUniformLocation(program_shaderPeelingInit, "uAlpha"), opacity);
drawModel(program_shaderPeelingInit);
glUseProgram(0);
/* --------------------------------------------------------------------- */
/* 2. Depth Peeling + Blending */
/* --------------------------------------------------------------------- */
for (int32_t layer = 1; true && layer < MAX_PEELED_LAYERS; layer++)
{
/* --------------------------------------------------------------------- */
/* 2.1. Peel the next depth layer */
/* --------------------------------------------------------------------- */
int32_t currId = layer % 2;
int32_t prevId = 1 - currId;
glBindFramebuffer(GL_FRAMEBUFFER, frontFboId[currId]);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBeginQuery(GL_SAMPLES_PASSED, queryId);
glUseProgram(program_shaderPeelingPeel);
// bindTextureRect()
glUniform1i(glGetUniformLocation(program_shaderPeelingPeel, "DepthTex"), 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontDepthTexId[prevId]);
// setUniform1f()
glUniform1f(glGetUniformLocation(program_shaderPeelingPeel, "uAlpha"), opacity);
drawModel(program_shaderPeelingPeel);
glUseProgram(0);
glEndQuery(GL_SAMPLES_PASSED);
/* --------------------------------------------------------------------- */
/* 2.2. Blend the current layer */
/* --------------------------------------------------------------------- */
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
// UNDER operator
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE,
GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(program_shaderPeelingBlend);
// bindTextureRect()
glUniform1i(glGetUniformLocation(program_shaderPeelingBlend, "TempTex"), 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontColorTexId[currId]);
// renderFullscreenQuad()
glUniformMatrix4fv(glGetUniformLocation(program_shaderPeelingBlend, "uModelViewMatrix"), 1, false, glm::value_ptr(glm::mat4()));
drawQuadGL(0);
glUseProgram(0);
glDisable(GL_BLEND);
GLuint sample_count;
glGetQueryObjectuiv(queryId, GL_QUERY_RESULT, &sample_count);
if (sample_count == 0)
{
break;
}
}
/* --------------------------------------------------------------------- */
/* 3. Compositing Pass */
/* --------------------------------------------------------------------- */
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
glDisable(GL_DEPTH_TEST);
glUseProgram(program_shaderPeelingFinal);
// setUniform3f()
glUniform3f(glGetUniformLocation(program_shaderPeelingFinal, "uBackgroundColor"),
backgroundColor[0], backgroundColor[1], backgroundColor[2]);
// bindTextureRect()
glUniform1i(glGetUniformLocation(program_shaderPeelingFinal, "ColorTex"), 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontColorBlenderTexId);
// renderFullscreenQuad()
glUniformMatrix4fv(glGetUniformLocation(program_shaderPeelingFinal, "uModelViewMatrix"), 1, false, glm::value_ptr(glm::mat4()));
drawQuadGL(0);
glUseProgram(0);
}
初始化:
glGenTextures(2, frontDepthTexId);
glGenTextures(2, frontColorTexId);
glGenFramebuffers(2, frontFboId);
for (int i = 0; i < 2; i++)
{
glBindTexture(GL_TEXTURE_RECTANGLE, frontDepthTexId[i]);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT32F_NV,
WIDTH, HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE, frontColorTexId[i]);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, WIDTH, HEIGHT,
0, GL_RGBA, GL_FLOAT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, frontFboId[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_RECTANGLE, frontDepthTexId[i], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_RECTANGLE, frontColorTexId[i], 0);
}
glGenTextures(1, &frontColorBlenderTexId);
glBindTexture(GL_TEXTURE_RECTANGLE, frontColorBlenderTexId);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, WIDTH, HEIGHT,
0, GL_RGBA, GL_FLOAT, 0);
glGenFramebuffers(1, &frontColorBlenderFboId);
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_RECTANGLE, frontDepthTexId[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_RECTANGLE, frontColorBlenderTexId, 0);
绘制函数:
void drawModel(GLuint program)
{
glUniformMatrix4fv(glGetUniformLocation(program, "uNormalMatrix"), 1, false, glm::value_ptr(normalMat));
glUniformMatrix4fv(glGetUniformLocation(program, "uModelViewMatrix"), 1, false, glm::value_ptr(mvp));
glBindVertexArray(cubesVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
numGeoPasses++;
}
void drawQuadGL(GLuint posIndex)
{
const float position[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);
glEnableVertexAttribArray(posIndex);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(posIndex);
}
当我用 opengl 调试器(RenderDoc 和 apitrace)调试我的 exe 时,它告诉我渲染很好,即纹理对象填充了所需的图像,但我不知道为什么场景是黑色的: (
谁能告诉我我的代码有什么问题吗?或者有什么想法?提前致谢
如果需要任何其他详细信息,请告诉我编辑问题。
问题已解决。
问题是关于 OpenGL 版本的,它的作用是函数 drawQuadGL(GLuint posIndex)
在这一行:
glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);
这个函数可以得到两种类型的输入,作为最后一个参数。它可以获取指向数组的指针,或获取一个整数作为偏移量。从 OpenGL 版本 3.2 开始,指针类型已被弃用。所以,我将最后一个参数更改为 0
并解决了问题。