使用OpenGL模板缓冲区

时间:2016-09-24 14:20:38

标签: c++ opengl

我正在尝试在OpenGL中创建透视窗口效果。 通过背景四边形,我渲染背景纹理。之后,我在顶部渲染透视窗口纹理,并在窗口所在的位置填充模板缓冲区。最后,我只在模板缓冲区有一个网格的地方渲染一个网格。

这是我的OpenGL初始化代码和我的Draw方法:

// OpenGL state
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);



// Draw method
auto virtual Draw() -> void override
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Update camera UBO
    ...

    // Render background
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_DEPTH_TEST);
    prg_texture2D->UseProgram();
        prg_texture2D->SetUniform("modelMatrix", glm::mat4());
        glActiveTexture(GL_TEXTURE0);
            tex_image->Bind();
                backgroundQuad->Render();
            tex_image->Unbind();
    prg_texture2D->UnUseProgram();
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Render window
    double x, y;
    glfwGetCursorPos(m_window, &x, &y);
    glViewport(x - 150, m_windowDimensions.y - y - 150, 300, 300); // see-through window size = 300
    glClear(GL_STENCIL_BUFFER_BIT);
    glStencilFunc(GL_ALWAYS, 1, 0xFF);
    glStencilMask(0xFF);
    glDisable(GL_DEPTH_TEST);
    prg_texture2D->UseProgram();
        prg_texture2D->SetUniform("modelMatrix", glm::mat4());
        glActiveTexture(GL_TEXTURE0);
            tex_window->Bind();
                backgroundQuad->Render();
            tex_window->Unbind();
    prg_texture2D->UnUseProgram();
    glEnable(GL_DEPTH_TEST);
    backgroundQuad->UpdatePositions(vec_positions);
    glViewport(0, 0, m_windowDimensions.x, m_windowDimensions.y);

    // Update camera UBO
    ...

    // Render skull
    glStencilFunc(GL_EQUAL, 1, 0xFF);
    glStencilMask(0x00);
    prg_lighting->UseProgram();
        skull->ResetModelMatrix();
        skull->ScaleModel(glm::vec3(0.005f, 0.005f, 0.005f));
        skull->RotateModel(glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
        prg_lighting->SetUniform("modelMatrix", skull->GetModelMatrix());
        skull->Render(GL_TRIANGLES);
    prg_lighting->UnUseProgram();

如果没有调用glViewport,透明纹理就会在整个屏幕上拉伸,这不是什么,因为窗口应该是可移动的。但是,在这种情况下,模板功能可以正常工作,并且只有在透视窗口后面才能看到网格(我可以旋转,平移等)。

通过调用glViewport,行为非常奇怪,模板测试通过屏幕的每个部分,自程序启动以来透视窗口已被移动,即如果我移动在整个屏幕上的透视窗口,网格始终可见。

我还尝试更新背景四边形的顶点位置,而不是更改视口,我用它来将纹理渲染到屏幕上。但是,效果完全相同。以下是使用背景四元组更新的代码:

// Render window
double x, y;
glfwGetCursorPos(m_window, &x, &y);
float p = 0.1; // size of see-through window
std::array<glm::vec3, 6> vec_windowPositions = // All in the range of [-1, 1]
{
    // First triangle
    glm::vec3(2 * (x / m_windowDimensions.x - p / 2) - 1, 2 * ((m_windowDimensions.y - y) / m_windowDimensions.y - p / 2) - 1, 0.0f), // {0}
    glm::vec3(2 * (x / m_windowDimensions.x + p / 2) - 1, 2 * ((m_windowDimensions.y - y) / m_windowDimensions.y - p / 2) - 1, 0.0f), // {1}
    glm::vec3(2 * (x / m_windowDimensions.x + p / 2) - 1, 2 * ((m_windowDimensions.y - y) / m_windowDimensions.y + p / 2) - 1, 0.0f), // {2}

     // Second triangle
    glm::vec3(2 * (x / m_windowDimensions.x + p / 2) - 1, 2 * ((m_windowDimensions.y - y) / m_windowDimensions.y + p / 2) - 1, 0.0f), // {2}
    glm::vec3(2 * (x / m_windowDimensions.x - p / 2) - 1, 2 * ((m_windowDimensions.y - y) / m_windowDimensions.y + p / 2) - 1, 0.0f), // {3}
    glm::vec3(2 * (x / m_windowDimensions.x - p / 2) - 1, 2 * ((m_windowDimensions.y - y) / m_windowDimensions.y - p / 2) - 1, 0.0f)  // {0}
};
backgroundQuad->UpdatePositions(vec_windowPositions); // Update new vertex positions
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);
glDisable(GL_DEPTH_TEST);
prg_texture2D->UseProgram();
    prg_texture2D->SetUniform("modelMatrix", glm::mat4());
    glActiveTexture(GL_TEXTURE0);
        tex_window->Bind();
            backgroundQuad->Render();
        tex_window->Unbind();
prg_texture2D->UnUseProgram();
glEnable(GL_DEPTH_TEST);
backgroundQuad->UpdatePositions(vec_positions); // Update to old, fulscreen vertex positions

以下是它的外观截图。有任何建议如何解决这个问题?

enter image description here

0 个答案:

没有答案