变换反馈仅适用于第一帧

时间:2013-10-17 03:28:06

标签: opengl transform-feedback

转换反馈适用于第一帧,但不适用于此之后。

这是基于“GLSL Cookbook”示例的粒子系统,虽然我将其转换为OpenGL 3.3。

我的程序设置:

我为每个属性设置了两组顶点数组缓冲区(2个用于位置,2个用于速度,2个用于startTime)。 2个VAO,第一个对应于第一个设置缓冲区,第二个VAO对应第二组缓冲区。 VAO将顶点属性设置为相应缓冲区。

有两个着色器程序,第一个执行变换反馈,第二个渲染。

在每个帧上,首先使用变换反馈着色器程序和VAO执行变换反馈,然后使用其他VAO渲染渲染着色器。在每个连续的帧上交换VAO。

如果我使用GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN的查询,我可以看到只有第一次写入所有基元时,之后写入的基元值为0。此外,我可以在视觉上看到第一个通过工作,看到点闪烁在屏幕上(点的起始位置和它们在第一帧中转换的位置之间的闪烁)。

我只在Mac OS X上看到这个问题(它在Linux和Windows上运行良好)。我知道Mac稍微落后于一些OpenGL功能,但是在这种情况下我找不到任何表明会出现问题的东西。

此外,我在渲染时检查了OpenGL错误,但没有。

在链接变换反馈着色器之前:

const char * outputNames[] = { "position", "velocity", "startTime" };
glTransformFeedbackVaryings(
    m_transformShader.programId(),
    3, 
    outputNames,
    GL_SEPARATE_ATTRIBS);

这是我正在使用的渲染功能代码:

// ************** Transform feedback pass

m_transformShader.bind();

glEnable(GL_RASTERIZER_DISCARD);

glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, positionBuffer[drawBuf]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, velocityBuffer[drawBuf]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, startTimeBuffer[drawBuf]);

m_vao[1-m_drawBuf].bind();

glBeginTransformFeedback(GL_POINTS);
glDrawArrays(GL_POINTS, 0, numParticles);
glEndTransformFeedback();

glDisable(GL_RASTERIZER_DISCARD);

// ************** Render pass

m_renderShader.bind();

glClear( GL_COLOR_BUFFER_BIT );
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture);
m_renderShader.setUniformValue("texSampler", 0);

m_vao[m_drawBuf].bind();
glDrawArrays(GL_POINTS, 0, numParticles);
m_vao[m_drawBuf].release();

m_renderShader.release();

m_drawBuf = 1 - m_drawBuf;

变换反馈着色器(m_transformShader)的顶点着色器:

#version 330

layout (location = 0) in vec3 vertexPosition;
layout (location = 1) in vec3 vertexVelocity;
layout (location = 2) in float vertexStartTime;
layout (location = 3) in vec3 vertexInitialVelocity;

out vec3 position;
out vec3 velocity;
out float startTime;

uniform float time;
uniform float H;

uniform vec3 accel;
uniform float lifespan;

void main()
{
    position = vertexPosition;
    velocity = vertexVelocity;
    startTime = vertexStartTime;

    if ( time >= startTime )
    {
        float age = time - startTime;
        if ( age > lifespan )
        {
            position = vec3(0.0);
            velocity = vertexInitialVelocity;
            startTime = time;
        }
        else
        {
            position += velocity * H;
            velocity += accel * H;
        }
    }
}

渲染顶点着色器:

#version 330

layout (location = 0) in vec3 vPosition;
layout (location = 2) in float vStartTime;

out float alpha;

uniform mat4 MVP;
uniform float time;
uniform float lifespan;

void main()
{
    gl_PointSize = 10.0;
    float age = time - vStartTime;
    alpha = 1.0 - age / lifespan;
    gl_Position = MVP * vec4(vPosition, 1.0);
}

我正在使用OpenGL 3.3上下文。

0 个答案:

没有答案