2014-09-23 68 views
0

現在它似乎對我來說,我交錯的VBO是嚴格'只讀',但我想每幀更新它(最好從GLSL)。動態VBO在GLSL中讀/寫?

我有一顆行星在軌道上移動,下面的代碼是用於渲染軌道點。

問題提綱: 我要上軌道每個點都有自己的「一生」,邏輯:

    當行星經過每個連續點
  • ?將壽命更新到1.0並隨着時間減少!

這將用於創建每個移動物體的衰落軌道。現在我只是想找到方法來操縱vbo ...

如何讀取和寫入GLSL內和從VBO?任何人都可以發佈示例嗎?


更新:我修改上面的代碼轉換反饋工作(由用戶的Andon M.科爾曼建議),但我想我可能會做一些錯誤(我得到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); 
+1

我建議你閱讀[變換反饋](http://www.opengl。組織/維基/ Transform_Feedback)。從GLSL內部使用它沒有什麼特別的需要。 – 2014-09-23 20:32:22

+0

@ AndonM.Coleman - Ive無意中發現了變換反饋,還有: glMapBufferRange,glBufferSubData,double緩衝區和計算着色器,如user42813所示。它很難知道哪一個給了我最大的靈活性(每個軌道的數學運算,即距離,點積計算等等都是一樣的,但是我想稍後爲每個線段添加一個幾何着色器到實例四邊形 - 粗線)。 – mike 2014-09-23 21:10:26

+0

我很難確定哪種方法是最好的。我在某處添加了一個geom。着色器會影響變換反饋的捕獲(一旦有1個點,現在每個四角的角點都有4個點)。 glBufferSubData似乎沒事,但我無法找到如何「重新上傳」數據的例子,它似乎應該與glMapBufferRange一起使用?這仍然需要我在CPU上進行計算,然後上傳到設備... – mike 2014-09-23 21:29:37

回答

1

你不能改變你的VBO從的OpenGL渲染pipline的內容,但可以使用招數它們取決於時間,如果你還更新正在使用Opengl 4.4,你可以使用ComputeShaders,但在這裏解釋它有點複雜,因此谷歌爲它,祝你好運。

0

如何在GLSL內讀寫VBO?

你不行。 VBO嚴格從常規渲染着色器中只讀。修改是完全不可能的(因爲這會打開深不可測的深度蠕蟲),但使用變換反饋,着色器階段的結果可以寫入緩衝區。

或者您使用計算着色器。

問題提綱:我希望軌道上的每個點都有自己的「生命」邏輯:當行星經過每個連續點時?將壽命更新到1.0並隨着時間減少!

聽起來像計算着色器的任務。但說實話,我認爲在GPU上處理這個並沒有太大的收穫。

+0

那麼你建議在CPU上做更好,還是我正確地使用轉換反饋?如果你看到我修改我的帖子來使用它,但我得到'無效操作'glError - 我以前沒有使用過這種技術。另一方面,如果有可能在CPU上做我想做的所有事情,那會讓我的生活變得更輕鬆,但是當我擁有VBO時,我沒有看到這種可能性。 – mike 2014-09-24 01:31:05

+0

我在上面的代碼中做了什麼似乎是教科書。我認爲這個問題可能有索引緩衝區存在?也許改變反饋不起作用在這種情況下... – mike 2014-09-24 02:23:29