【发布时间】:2014-09-23 17:47:54
【问题描述】:
现在在我看来似乎我的交错式 VBO 严格来说是“只读的”,但我想每帧都更新它(最好从 GLSL 更新)。
我有一个在轨道上移动的行星,下面的代码用于渲染轨道点。
问题大纲: 我希望该轨道上的每个点都有自己的“生命周期”,逻辑:
- 行星何时经过每个连续点?将生命周期更新为 1.0 并随着时间的推移而减少!
这将用于创建每个移动物体的衰落轨道路径。现在我只是在寻找操纵 vbo 的方法......
如何在 GLSL 中读写 VBO?任何人都可以发布示例吗?
更新:我修改了上面的代码以使用转换反馈(由用户 Andon M. Coleman 建议),但我认为我可能做错了什么(我得到 glError):
设置:
// Initialize and upload to graphics card
glGenVertexArrays(1, &_vaoID);
glGenBuffers(1, &_vBufferID);
glGenBuffers(1, &_iBufferID);
glGenBuffers(1, &_tboID);
// First VAO setup
glBindVertexArray(_vaoID);
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
glBufferData(GL_ARRAY_BUFFER, _vsize * sizeof(Vertex), _varray, GL_DYNAMIC_DRAW);
// TRANSFORM FEEDBACK
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _tboID); // Specify buffer
// Allocate space without specifying data
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
_vsize*sizeof(Vertex), NULL, GL_DYNAMIC_COPY);
// Tell OGL which object to store the results of transform feedback
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _vBufferID); //correct?
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE,
sizeof(Vertex), reinterpret_cast<const GLvoid*>(offsetof(Vertex, location)));
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
sizeof(Vertex), reinterpret_cast<const GLvoid*>(offsetof(Vertex, velocity)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _isize * sizeof(int), _iarray, GL_STREAM_DRAW);
渲染方法():
//disable fragment, so that we do a first run with feedback
glEnable(GL_RASTERIZER_DISCARD);
glBindVertexArray(_vaoID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _tboID);
glBeginTransformFeedback(_mode);
glDrawElements(_mode, _isize, GL_UNSIGNED_INT, 0);
glEndTransformFeedback();
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
glBindVertexArray(0);
glDisable(GL_RASTERIZER_DISCARD);
// then i attempt to do the actual draw
glBindVertexArray(_vaoID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
glDrawElements(_mode, _isize, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
并且 - 在链接之前:
const GLchar* feedbackVaryings[] = { "point_position" };
glTransformFeedbackVaryings(_ephemerisProgram->getProgramID(), 1, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
【问题讨论】:
-
我建议您阅读transform feedback。您无需在 GLSL 中执行任何特殊操作即可使用它。
-
@AndonM.Coleman - 我偶然发现了变换反馈以及:glMapBufferRange、glBufferSubData、双缓冲区和计算着色器,如下面的 user42813 建议的那样。很难知道哪一个给了我最大的灵活性(每个轨道的数学,即距离,点积计算等将是相同的,但我想稍后为每个线段的实例四边形添加一个几何着色器 - 拥有粗线。)
-
我很难确定哪种方法最好。我在某处读到添加了一个geom。着色器影响变换反馈的捕获(曾经有 1 个点,现在四边形的每个角有 4 个点)。 glBufferSubData 似乎没问题,但我找不到如何“重新上传”数据的示例,而且它似乎应该与 glMapBufferRange 结合使用?这仍然需要我在 CPU 上进行计算,然后上传到设备...