OpenGL 4.4 变换反馈布局说明符

问题描述 投票:0回答:1

我在使用

OpenGL version 4.4.
的变换反馈缓冲区时遇到问题 我正在使用几何着色器输出来捕获和绘制三角形。 三角形将被几何着色器中的某种算法剔除,我想捕获生成的三角形。 所以结果三角形计数应该小于输入计数。

当我指定着色器内布局说明符(

xfb_buffer
等)时,没有捕获图元。 我将其改回 glTransformFeedbackVaryings,现在正在捕获图元,但不是每个三角形3 个顶点(9 个浮点数) 它捕获较少,因为结果缓冲区的大小不能被 3 整除。

初始化:

    // ---------------
    // VERTEX BUFFER
    // ---------------
    glGenBuffers(1, &vertexBufferObjectId_);
    // Init vertex data
    unsigned int numVerts = width * height;
    size_t vertexSize = (3 + 2) * sizeof(GLfloat); // position, texcoord
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId_);
    glBufferData(GL_ARRAY_BUFFER, numVerts * vertexSize, 0, GL_STATIC_DRAW);
    uint8_t* vertices = (uint8_t*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    for (unsigned int y = 0; y < height; ++y)
    {
        for (unsigned int x = 0; x < width; ++x)
        {
            *(float*)(vertices+0) = x; // x
            *(float*)(vertices+4) = y; // y
            *(float*)(vertices+8) = 0; // z
            *(float*)(vertices+12) = (float)x / (width - 1);  // u
            *(float*)(vertices+16) = (float)y / (height - 1); // v
            vertices += vertexSize;
        }
    }
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // ---------------
    // INDEX BUFFER
    // ---------------
    glGenBuffers(1, &indexBufferObjectId_);
    glEnable(GL_PRIMITIVE_RESTART);
    glPrimitiveRestartIndex(-1); // accepts GLuint, so this will be the largest possible value
    // Init index data
    unsigned int numPolys = 2 * (width - 1) * (height - 1) * 2;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObjectId_);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numPolys * 3 * sizeof(GLuint), 0, GL_STATIC_DRAW);
    GLuint* indices = (GLuint*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
    for (unsigned int y = 0; y < height-1; ++y)
    {
        for (unsigned int x = 0; x < width-1; ++x)
        {
            // i11 is at (x,y)
            //         i20
            //     i11 i21 i31
            // i02 i12 i22
            //     i13

            uint32_t i20 = get_index(width,height,x+1,y-1);
            uint32_t i11 = get_index(width,height,x,y);
            uint32_t i21 = get_index(width,height,x+1,y);
            uint32_t i31 = get_index(width,height,x+2,y);
            uint32_t i02 = get_index(width,height,x-1,y+1);
            uint32_t i12 = get_index(width,height,x,y+1);
            uint32_t i22 = get_index(width,height,x+1,y+1);
            uint32_t i13 = get_index(width,height,x,y+2);

            // first triangle: i12,i22,i21
            //         i21
            //     i12 i22

            // with adjacency: i12,i13,i22,i31,i21,i11
            //     i11 i21 i31
            //     i12 i22
            //     i13
            *(indices++) = i12;
            *(indices++) = i13;
            *(indices++) = i22;
            *(indices++) = i31;
            *(indices++) = i21;
            *(indices++) = i11;

            // second triangle: i12,i21,i11
            //     i11 i21
            //     i12

            // with adjacency: i12,i22,i21,i20,i11,i02
            //         i20
            //     i11 i21
            // i02 i12 i22

            *(indices++) = i12;
            *(indices++) = i22;
            *(indices++) = i21;
            *(indices++) = i20;
            *(indices++) = i11;
            *(indices++) = i02;
        }
    }
    glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // ---------------
    // TRANSFORM FEEDBACK BUFFER
    // ---------------
    if (feedbackVertexBufferObjectId_)
        glDeleteBuffers(1, &feedbackVertexBufferObjectId_);

    glGenBuffers(1, &feedbackVertexBufferObjectId_);
    glBindBuffer(GL_ARRAY_BUFFER, feedbackVertexBufferObjectId_);
    glBufferData(GL_ARRAY_BUFFER, numPolys * 3 * 3 * sizeof(GLfloat), 0, GL_STREAM_READ);

效果图:

    meshRenderShader_.enable();
    // Set to write to the framebuffer.
    glBindFramebuffer(GL_FRAMEBUFFER, camData.framebuffer_.framebufferId_);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // ----------------------------------
    // Render projected mesh

    // Binding vertex buffer
    size_t vertexSize = (3 + 2) * sizeof(GLfloat);
    glBindBuffer(GL_ARRAY_BUFFER, camData.mesh_.vertexBufferObjectId_);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 3));

    // Binding index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, camData.mesh_.indexBufferObjectId_);

    // Bind transform feedback and target buffer
    glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, camData.mesh_.feedbackVertexBufferObjectId_);

    GLuint query;
    glGenQueries(1, &query);

    //      glEnable(GL_RASTERIZER_DISCARD);

    // Begin transform feedback
    glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
    glBeginTransformFeedback(GL_TRIANGLES);

    // Set shader uniforms
    meshRenderShader_.setUniformMat4("ModelViewProjection", (viewProjMatrix * camData.transform_).data());

    // Binding texture
    meshRenderShader_.setUniformTexture("colorTexture", camData.mesh_.textureId_, 0);
    meshRenderShader_.setUniformTexture("depthTexture", camData.mesh_.depthTextureId_, 1);
    meshRenderShader_.setUniform2f("depthSize", camData.intrinsic_.width, camData.intrinsic_.height);
    meshRenderShader_.setUniform2f("intrinsic_f", camData.intrinsic_.fx, camData.intrinsic_.fy);
    meshRenderShader_.setUniform2f("intrinsic_c", camData.intrinsic_.cx, camData.intrinsic_.cy);

    // Drawing elements to textures
    glDrawElements(GL_TRIANGLES_ADJACENCY, camData.mesh_.numPolys_ * 3, GL_UNSIGNED_INT, (const GLvoid*) 0);

    // End transform feedback
    glEndTransformFeedback();
    glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
    //      glDisable(GL_RASTERIZER_DISCARD);
    //      glFlush();


    glGetQueryObjectuiv(query, GL_QUERY_RESULT, &camData.mesh_.primitivesWritten_);

    //      glDrawTransformFeedback(GL_TRIANGLES_ADJACENCY, camData.mesh_.feedbackbufferId_);

    glDeleteQueries(1, &query);

    // Unbinding buffers
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindFramebuffer(GL_FRAMEBUFFER,0);

    // Disable shader
    meshRenderShader_.disable();

GLSL几何着色器的相关部分:

layout(xfb_buffer = 0) out vec3 xPosition;

if (cull)
{
    gl_Position = ModelViewProjection * gl_in[0].gl_Position;
    fTexCoord = gTexCoord[0];
    xPosition = gl_Position.xyz;
    EmitVertex();
    gl_Position = ModelViewProjection * gl_in[2].gl_Position;
    fTexCoord = gTexCoord[2];
    xPosition = gl_Position.xyz;
    EmitVertex();
    gl_Position = ModelViewProjection * gl_in[4].gl_Position;
    fTexCoord = gTexCoord[4];
    xPosition = gl_Position.xyz;
    EmitVertex();
    EndPrimitive();
}

有什么解决办法?

opengl glsl shader geometry-shader
1个回答
0
投票

当您指定变换反馈限定符时,

xfb_buffer
需要伴随着
xfb_offset
。来自OpenGL Wiki

变量可以有

xfb_buffer
分配给他们没有
xfb_offset
。这什么都不做,将被忽略。

简而言之,将着色器更改为以下应该避免调用

glTransformFeedbackVaryings()

layout(xfb_buffer = 0, xfb_offset = 0) out vec3 xPosition;
© www.soinside.com 2019 - 2024. All rights reserved.