You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL 3.x变换反馈GL_SEPARATE_ATTRIBS模式分离VBO配置问题

在macOS OpenGL 3.x中用变换反馈分离输出坐标和颜色到独立VBO

完全可以实现你的需求,你遇到的编译/链接错误是因为接口块的绑定配置和变换反馈的设置步骤有误,以下是正确的实现流程:

1. 修正着色器接口块写法

着色器中必须为输出接口块指定binding布局限定符,绑定值对应后续VBO的变换反馈缓冲绑定点。注意不要在变量名后加多余的点,示例顶点着色器:

#version 150 core // 对应macOS OpenGL 3.2 Core Profile
layout(location = 0) in vec3 coords_in;
layout(location = 1) in vec3 colors_in;

// 坐标输出块,绑定到变换反馈缓冲点0
layout(binding = 0) out BlockCoords {
    vec3 coords_out;
};
// 颜色输出块,绑定到变换反馈缓冲点1
layout(binding = 1) out BlockColors {
    vec3 colors_out;
};

void main() {
    // 示例:生成两倍顶点,复制并偏移原顶点
    if (gl_VertexID % 2 == 0) {
        coords_out = coords_in;
        colors_out = colors_in;
    } else {
        coords_out = coords_in + vec3(0.1, 0.1, 0.0);
        colors_out = colors_in * 0.8;
    }
}

2. 设置变换反馈模式与缓冲绑定

  • 必须使用GL_SEPARATE_ATTRIBS模式替代之前的GL_INTERLEAVED_ATTRIBS,因为要将数据输出到独立VBO。
  • 创建两个VBO并分配足够内存(至少为源顶点数的2倍对应数据大小),再绑定到对应的变换反馈缓冲点:
// 创建并初始化坐标VBO
GLuint coords_vbo;
glGenBuffers(1, &coords_vbo);
glBindBuffer(GL_ARRAY_BUFFER, coords_vbo);
glBufferData(GL_ARRAY_BUFFER, 2 * source_vert_count * sizeof(float)*3, nullptr, GL_STATIC_COPY);

// 创建并初始化颜色VBO
GLuint colors_vbo;
glGenBuffers(1, &colors_vbo);
glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
glBufferData(GL_ARRAY_BUFFER, 2 * source_vert_count * sizeof(float)*3, nullptr, GL_STATIC_COPY);

// 创建并绑定变换反馈对象(TFO)
GLuint tfo;
glGenTransformFeedbacks(1, &tfo);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo);

// 将VBO绑定到变换反馈缓冲绑定点,对应着色器中的binding值
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, coords_vbo);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, colors_vbo);

3. 配置变换反馈输出变量并链接程序

必须在程序链接前调用glTransformFeedbackVaryings,指定要捕获的输出变量,顺序要和缓冲绑定点对应:

// 指定变换反馈要捕获的输出变量
const GLchar* varyings[] = {"coords_out", "colors_out"};
glTransformFeedbackVaryings(program, 2, varyings, GL_SEPARATE_ATTRIBS);

// 链接程序并检查状态
glLinkProgram(program);
GLint link_ok;
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
    char log[1024];
    glGetProgramInfoLog(program, 1024, nullptr, log);
    fprintf(stderr, "Program link error: %s\n", log);
}

4. 执行变换反馈

执行时禁用光栅化(不需要生成片段,提升性能),然后启动变换反馈并绘制源顶点:

glEnable(GL_RASTERIZER_DISCARD);
glBeginTransformFeedback(GL_POINTS); // 根据你的源图元类型调整,比如GL_TRIANGLES
glDrawArrays(GL_POINTS, 0, source_vert_count);
glEndTransformFeedback();
glDisable(GL_RASTERIZER_DISCARD);

关键注意事项

  • macOS的OpenGL 3.2 Core Profile完全支持上述特性,确保你的上下文是Core Profile而非兼容模式。
  • 接口块的binding值必须和glBindBufferBase的第二个参数(缓冲绑定点)一一对应。
  • glTransformFeedbackVaryings必须在程序链接前调用,调用后需重新链接程序。

内容的提问来源于stack exchange,提问作者Graou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:51:18