J'ai une configuration OpenGL très spécifique où la géométrie 3D de la scène n'est pas rendue. Il y a un état lié à la profondeur dans le contexte OpenGL qui m'influe.Le tampon de profondeur OpenGL ou le test de profondeur ne fonctionne pas lors du rendu avec un contexte partagé
Ceci est dans un moteur de production au travail où nous avons ajouté la prise en charge du contexte partagé avec plusieurs contextes de fenêtre. Nous effectuons le rendu vers un objet framebuffer appartenant au contexte partagé, puis nous passons le renderbuffer de la pièce jointe couleur à une fenêtre en utilisant un contexte différent. La couleur claire est montrée dans le blit résultant à la fenêtre, mais pas la géométrie de la scène 3D elle-même, donc nous savons que les objets framebuffer et renderbuffer sont au moins partiellement corrects. Pour illustrer, j'ai refactored un échantillon du site Web LearnOpenGL pour illustrer mon bogue. Ça se voit là aussi, alors je suis clair que c'est quelque chose qui me manque.
Voici le projet GitHub où j'ai fait trois commits à un échantillon framebuffer de travail afin qu'il a rendu au framebuffer en utilisant un contexte partagé et Blits le résultat: Framebuffer Shared Context Experiment
est ici la plupart du code source qui produit le résultat buggy. J'ai coupé quelques sections qui sont restées inchangées.
// glfw dummy window creation
// --------------------
GLFWwindow* dummy = NULL;
#if USE_SHARED_CONTEXT
dummy = glfwCreateWindow(1, 1, "Dummy", NULL, NULL);
if (dummy == NULL)
{
std::cout << "Failed to create dummy GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(dummy);
#endif
// glfw window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, dummy);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwShowWindow(window);
#if !USE_SHARED_CONTEXT
glfwMakeContextCurrent(window);
#endif
// <snip creation of shared resources>
// <snip creation of un-shared vertex array>
// framebuffer configuration
// -------------------------
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
#if 1
// create a color attachment render buffer
unsigned int Colorbuffer;
glGenRenderbuffers(1, &Colorbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, Colorbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Colorbuffer); // now actually attach it
#else
// create a color attachment texture
unsigned int textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, 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, textureColorbuffer, 0);
#endif
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_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)
cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// render loop
// -----------
while (!glfwWindowShouldClose(window))
{
// <snip timing and input>
#if USE_SHARED_CONTEXT
// use shared context because that is what is holding our framebuffer and vao.
// -----
glfwMakeContextCurrent(dummy);
#endif
// render
// ------
// bind to framebuffer and draw scene as we normally would to color texture
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
// make sure we clear the framebuffer's content
glClearColor(1.0f, 0.1f, 0.1f, 1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// following render is unchanged
shader.use();
glm::mat4 model;
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 100.0f);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
// cubes
glBindVertexArray(cubeVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
model = glm::mat4();
model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
// floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
#if 1
#if USE_SHARED_CONTEXT
// use window context for presentation via blit.
// -----
glfwMakeContextCurrent(window);
// temorary framebuffer for visible window since framebuffers are not shared
// -------------------------
unsigned int readFramebuffer;
glGenFramebuffers(1, &readFramebuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, Colorbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, SCR_WIDTH, SCR_HEIGHT);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Colorbuffer);
#endif
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
#if USE_SHARED_CONTEXT
glDeleteFramebuffers(1, &readFramebuffer);
#endif
#else
// now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.
// clear all relevant buffers
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
glClear(GL_COLOR_BUFFER_BIT);
screenShader.use();
glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // use the color attachment texture as the texture of the quad plane
glDrawArrays(GL_TRIANGLES, 0, 6);
#endif
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// <snip epilog>
Vous pouvez activer ou désactiver le commutateur de compilation USE_SHARED_CONTEXT pour enlever le peu de code qui affiche à l'aide d'un contexte partagé.