I am making an opengl program in c# using OpenTK, implementing transparent effect on simple objects, using depth peeling algorithm. There is a sample code of depth peeling in web from NVIDIA, in c++, I simplified it and worked fine. But when I port the code to c#, the viewport become solid black. I compared c++ and c# code multiple times and don't think there is any problem with code or accidental differences.
Rendering loop:
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);
}
Inits:
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);
Draw functions:
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);
}
When I debug my exe with opengl debuggers (RenderDoc and apitrace) it shows me that the renderings are fine, i.e. the texture objects are filled with the desired images, but I don't know why the scene is black :(
Can anyone tell me please whats wrong with my code? Or any idea? Thanks in advance
If any additional details is needed please tell me to edit the question.
Problem solved.
The problem is about OpenGL version, and it's effect is in function drawQuadGL(GLuint posIndex)
at this line:
glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);
This function can get two types of input, as the last parameter. It can get pointer to an array, or get an integer as offset. The pointer type is deprecated as of OpenGL version 3.2. So, I changed the last parameter to 0
and problem solved.