OK I am trying to follow the discussion of mass spring simulation on page 417 OpenGL superbible. The book says I need 2 TBOs, 2 VBOs and 2VAOs. So I do my setup as follows,
void createVBO()
{
//fill the vertices
int count = 0;
for(int i=0;i<MAX_MASSES;i++) {
vertices[i].position_mass[0]=vSpringMassVerts[i][0];
vertices[i].position_mass[1]=vSpringMassVerts[i][1];
vertices[i].position_mass[2]=vSpringMassVerts[i][2];
vertices[i].position_mass[3]=vSpringMassVerts[i][3];
vertices[i].velocity[0]=0;
vertices[i].velocity[1]=0;
vertices[i].velocity[2]=0;
vertices[i].velocity[3]=0;
vertices[i].connection[0]=connections[i][0];
vertices[i].connection[1]=connections[i][1];
vertices[i].connection[2]=connections[i][2];
vertices[i].connection[3]=connections[i][3];
}
// create buffer object
glGenVertexArrays(2, vaoID);
glGenBuffers( 2, vboID);
glBindVertexArray(vaoID[0]);
glBindBuffer( GL_ARRAY_BUFFER, vboID[0]);
glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), &(vertices[0]), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(MyVertex), (const GLvoid*) offsetof(MyVertex, position_mass));
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(MyVertex), (const GLvoid*) offsetof(MyVertex, velocity));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(MyVertex), (const GLvoid*) offsetof(MyVertex, connection));
glBindVertexArray(vaoID[1]);
glBindBuffer( GL_ARRAY_BUFFER, vboID[1]);
glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), &(vertices[0]), GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(MyVertex), (const GLvoid*) offsetof(MyVertex, position_mass));
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(MyVertex), (const GLvoid*) offsetof(MyVertex, velocity));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(MyVertex), (const GLvoid*) offsetof(MyVertex, connection));
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindBuffer( GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
gltCheckErrors();
}
void createTBO(size_t size) {
glGenTextures( 2, texID);
glGenBuffers( 2, tboID);
for(int i=0;i<2;i++) {
glBindVertexArray(vaoID[i]);
glBindBuffer( GL_TEXTURE_BUFFER, tboID[i]);
glBufferData( GL_TEXTURE_BUFFER, size, vSpringMassVerts, GL_STATIC_DRAW);
glActiveTexture(GL_TEXTURE0+i);
glBindTexture( GL_TEXTURE_BUFFER, texID[i]);
glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F_ARB, tboID[i]);
}
}
And as given in the sample codes of the book, I render my mass spring system using,
glUseProgram(massSpringShader);
glUniformMatrix4fv(mvpLocation, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
glUniform4fv(colorLocation,1, vRed);
glUniform1f(tLocation,0.01);
glUniform1f(kLocation, k);
glUniform1f(cLocation, c);
glUniform1f(rLengthLocation, l);
gltCheckErrors();
glBindVertexArray( vaoID[readID]);
glActiveTexture( GL_TEXTURE0+readID);
glBindTexture( GL_TEXTURE_BUFFER, texID[readID]);
glUniform1i( glGetUniformLocation( massSpringShader, "tex_position_mass"), readID);
glBindBuffer( GL_ARRAY_BUFFER, vboID[readID]);
glDrawArrays(GL_POINTS, 0, MAX_MASSES);
int tmp = readID;
readID=writeID;
writeID = tmp;
glBindBuffer( GL_ARRAY_BUFFER, 0);
glBindVertexArray( 0);
glUseProgram(0);
However, the output just gives me flickering nodes which donot move. Am I doing this correctly? As said in the book, the output would be written to the other TBO/VBO pair. One thing I am not sure is how do i assign the output of the vertex shader to a specific TBO/VBO? And here is the vertex shader (copied from the book.
#version 330
precision highp float;
#extension EXT_gpu_shader4 : require
in vec4 position_mass;
in vec4 velocity;
in vec4 connection;
uniform mat4 MVP;
uniform samplerBuffer tex_position_mass;
uniform float t, k, c, rest_length;
const vec3 gravity = vec3(0,0,0);
out Vertex {
vec4 position_mass;
vec4 velocity;
}vertex;
void main(void)
{
vec3 p = position_mass.xyz;
float m = position_mass.w;
vec3 u = velocity.xyz;
vec3 F;
vec3 v = u;
vec3 s = vec3(0);
if(connection[0] != -1) {
F = gravity + c*u;
for(int i=0;i<4;i++) {
if(connection[i]!=gl_VertexID) {
vec3 q = texelFetchBuffer(tex_position_mass, int(connection[i])).xyz;
vec3 d = q-p;
float x = length(d);
F += -k*(rest_length-x)*normalize(d);
}
}
vec3 a = F/m;
s = u*t +0.5*a*t*t;
v = u+a*t;
}
vertex.position_mass = vec4(p+s, m);
vertex.velocity = vec4(v,0);
gl_Position = MVP*vec4(p+s, 1.0);
Regards,
Mobeen