GLSL中的动态VBO读/写?

时间:2014-09-23 17:47:55

标签: opengl glsl vbo

现在它对我来说似乎我的交错式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);

2 个答案:

答案 0 :(得分:1)

你不能从Opengl的渲染管道改变VBO的内容,但是你可以根据时间使用技巧来更新它们,如果你使用的是Opengl 4.4,你可以使用ComputeShaders但它有点小在这里解释它有点复杂,好吧谷歌,祝你好运。

答案 1 :(得分:0)

  

如何在GLSL中读取和写入VBO?

你不能。 VBO严格来自普通渲染着色器。根本不可能进行修改(因为这会打开一个深不可测的深层蠕虫)但是使用转换反馈可以将着色器阶段的结果写入缓冲区。

或者您使用计算着色器。

  

问题大纲:我希望该轨道上的每个点都有自己的&#34;生命周期&#34;,逻辑:当行星通过每个连续点时?将生命周期更新为1.0并随着时间的推移而减少!

听起来像计算着色器的任务。但老实说,我不认为在GPU上处理这个会有很多好处。