C++ 基于动态几何的OpenGL变换反馈

C++ 基于动态几何的OpenGL变换反馈,c++,opengl,geometry-shader,transform-feedback,C++,Opengl,Geometry Shader,Transform Feedback,我目前正在尝试使用几何体着色器进行变换反馈。“几何体”着色器获取一个三角形,将其制成一个棱镜,并在其顶部放置一个四边形(将其视为一个方尖塔,但只有3条边,而不是4条边) 我使用一次变换反馈得到正确的结果。然而,我想用变换反馈创建额外的几何体。我想为Tetraeder的每个三角形执行几何体着色器过程 第一次通过后的结果 第二次通过后的结果 因此,在第二遍中,黑色部分不是无限大,而是应该有另一个分支,你可以看到左右,但那个分支朝向相机 我做错了什么?我不知道如何处理两个顶点缓冲区对象的数据量总是在

我目前正在尝试使用几何体着色器进行变换反馈。“几何体”着色器获取一个三角形,将其制成一个棱镜,并在其顶部放置一个四边形(将其视为一个方尖塔,但只有3条边,而不是4条边)

我使用一次变换反馈得到正确的结果。然而,我想用变换反馈创建额外的几何体。我想为Tetraeder的每个三角形执行几何体着色器过程

第一次通过后的结果

第二次通过后的结果 因此,在第二遍中,黑色部分不是无限大,而是应该有另一个分支,你可以看到左右,但那个分支朝向相机

我做错了什么?我不知道如何处理两个顶点缓冲区对象的数据量总是在增加,我可能在这方面做了一些错误的事情。我们将不胜感激

在主窗口循环之前转换反馈:

glUseProgram(transformShaderProgram);

glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO);
glBindVertexArray(transformVAO);
glEnable(GL_RASTERIZER_DISCARD);

glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfQuery);
glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_TRIANGLES, 0, 3);
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
glDisable(GL_RASTERIZER_DISCARD);

GLuint numPrimitivesWritten = 0;
glGetQueryObjectuiv(tfQuery, GL_QUERY_RESULT, &numPrimitivesWritten);
printf("Number of PrimitivesWritten %i\n", numPrimitivesWritten);
glUseProgram(feedbackShaderProgram);
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();
    CalcDeltaTime();
    doMovement();

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (doTransformFeedback && (currentNumberOfTransformFeedback < maxNumberOfTransformFeedback)) {
        glUseProgram(transformShaderProgram);

        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO);
        glBindVertexArray(feedbackVAO);
        glEnable(GL_RASTERIZER_DISCARD);

        glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfQuery);
        glBeginTransformFeedback(GL_TRIANGLES);
        glDrawArrays(GL_TRIANGLES, 0, numPrimitivesWritten * 5);
        glEndTransformFeedback();
        glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
        glDisable(GL_RASTERIZER_DISCARD);

        GLuint numPrimitivesWritten2 = 0;
        glGetQueryObjectuiv(tfQuery, GL_QUERY_RESULT, &numPrimitivesWritten2);
        numPrimitivesWritten += numPrimitivesWritten2;

        doTransformFeedback = false;
        currentNumberOfTransformFeedback++;
        glUseProgram(feedbackShaderProgram);
    }
    glBindVertexArray(feedbackVAO);
    glDrawArrays(GL_TRIANGLES, 0, numPrimitivesWritten * 5 );
    glBindVertexArray(0);

    glfwSwapBuffers(window);
}
主窗口循环期间的变换反馈:

glUseProgram(transformShaderProgram);

glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO);
glBindVertexArray(transformVAO);
glEnable(GL_RASTERIZER_DISCARD);

glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfQuery);
glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_TRIANGLES, 0, 3);
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
glDisable(GL_RASTERIZER_DISCARD);

GLuint numPrimitivesWritten = 0;
glGetQueryObjectuiv(tfQuery, GL_QUERY_RESULT, &numPrimitivesWritten);
printf("Number of PrimitivesWritten %i\n", numPrimitivesWritten);
glUseProgram(feedbackShaderProgram);
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();
    CalcDeltaTime();
    doMovement();

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (doTransformFeedback && (currentNumberOfTransformFeedback < maxNumberOfTransformFeedback)) {
        glUseProgram(transformShaderProgram);

        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO);
        glBindVertexArray(feedbackVAO);
        glEnable(GL_RASTERIZER_DISCARD);

        glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, tfQuery);
        glBeginTransformFeedback(GL_TRIANGLES);
        glDrawArrays(GL_TRIANGLES, 0, numPrimitivesWritten * 5);
        glEndTransformFeedback();
        glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
        glDisable(GL_RASTERIZER_DISCARD);

        GLuint numPrimitivesWritten2 = 0;
        glGetQueryObjectuiv(tfQuery, GL_QUERY_RESULT, &numPrimitivesWritten2);
        numPrimitivesWritten += numPrimitivesWritten2;

        doTransformFeedback = false;
        currentNumberOfTransformFeedback++;
        glUseProgram(feedbackShaderProgram);
    }
    glBindVertexArray(feedbackVAO);
    glDrawArrays(GL_TRIANGLES, 0, numPrimitivesWritten * 5 );
    glBindVertexArray(0);

    glfwSwapBuffers(window);
}
glUseProgram(反馈haderprogram);
而(!glfwWindowShouldClose(窗口))
{
glfwPollEvents();
calcdelatime();
doMovement();
glClearColor(0.2f、0.3f、0.3f、1.0f);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
if(DotTransfermFeedback&(currentNumberOfTransformFeedback
可以在读取顶点数据的同一缓冲区中执行变换反馈操作。在读取的顶点数据之上执行变换反馈操作是不正确的

这就是你在第二次手术中要做的

您需要做的是使用
glBindBufferBase
在第二个TF操作中偏移反馈缓冲区,以便它写入新的顶点数据

你做错的另一件事是你把错误的三角形传递给了你的反馈操作。根据您对所需内容的描述,您只希望在方尖碑最上面的三角形上执行该过程。但是,您可以在TF渲染代码中传递整个过程。您需要隔离要展开的特定三角形,并仅渲染它们


变换反馈将写入三角形。因此,您需要隔离这些特定的三角形,只对它们执行反馈操作。

感谢您的回复。我应该注意,我有一个三角形的长度参数,几何体着色器会计算该参数,并为所有不需要展开的三角形设置为0。如果我使用glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,numprimitiveswrited,TBO),我仍然会得到相同的结果;如果我理解正确的话,我应该这么做?@LeoldeWire:偏移量是以字节为单位的,而不是以编写的原语为单位。您还需要确保缓冲区中有足够的空间容纳所有这些数据。所以我尝试使用glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,sizeof(GLFloat)*5*numprimitiveswrited);不幸的是,结果还是一样