Attaching a TBO to VBO

Hi all,
I need to attach a texture buffer object to a VBO to give a readonly view of the VBO. My vertex shader generates the new positions which are correctly stored in the vbo however the TBO contains the same init values. I setup the vbos/tbo pair as follows,


//init
glBindVertexArray(vaoID);
glBindBuffer( GL_ARRAY_BUFFER, vboID_Pos);
glBindBuffer( GL_TEXTURE_BUFFER, tboID);
glBufferData( GL_ARRAY_BUFFER, sizeof(position_mass_data), &(position_mass_data[0]), GL_DYNAMIC_DRAW);
glBufferData( GL_TEXTURE_BUFFER, sizeof(position_mass_data), &(position_mass_data[0]), GL_DYNAMIC_DRAW);
glBindTexture( GL_TEXTURE_BUFFER, texID);
glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F_ARB, tboID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,  4, GL_FLOAT, GL_FALSE, 0, 0);

//render
glBindVertexArray( vaoID);
glActiveTexture( GL_TEXTURE0);			
glBindTexture( GL_TEXTURE_BUFFER, texID);
   glDrawArrays(GL_POINTS, 0, MAX_MASSES);
glBindVertexArray( 0);

Is this the correct way to setup TBO with VBO such that the TBO shares the data with the VBO? Note that there are no OGL errors. I have used gDebugger to see the vbo contents and it lists the init data in the TBO where as the vbo data is correctly updated. Any ideas where I am wrong?

Regards,
Mobeen

I need to attach a texture buffer object to a VBO to give a readonly view of the VBO.

This statement shows a misunderstanding of the workings of OpenGL.

Buffer objects are buffer objects. You can use them for various things, but they are all essentially the same. There is no such thing as a TBO or a VBO; they’re both just different uses for a buffer object.

Therefore, to do what you want, you create a single buffer object, which you use for both vertex data (binding as a GL_ARRAY_BUFFER) and buffer texture data (binding as a GL_TEXTURE_BUFFER). So you have a single call to glBufferData to allocate the buffer.

Hi Alfonse,
Thanks for the reply. Ok is this what I should do.


glBindBuffer( GL_ARRAY_BUFFER, vboID_Pos[i]);
glBindBuffer( GL_TEXTURE_BUFFER, vboID_Pos[i]);
glBufferData( GL_ARRAY_BUFFER, sizeof(position_mass_data), &(position_mass_data[0]), GL_DYNAMIC_DRAW);
glBindTexture( GL_TEXTURE_BUFFER, texID[i]);
glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F_ARB, vboID_Pos[i]);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,  4, GL_FLOAT, GL_FALSE, 0, 0);

Actually its quite difficult for me to find good resources to learn more about these buffers. Could u suggest any useful resource to learn more about the buffers. I have already seen the wiki article.

Actually its quite difficult for me to find good resources to learn more about these buffers.

That’s because you’re overthinking the problem.

You have a buffer object. That buffer object can be used as a source for vertex data. That buffer object can be used as the source for buffer textures. Neither one interferes with the other in any way.

They’re just memory.

Once you understood this, you came up with the right solution: the code you posted. Well, except that binding the buffer to GL_TEXTURE_BUFFER was superfluous; binding a buffer to that location doesn’t have any particular effect. The linkage between texture object and buffer object is made by the glTexBuffer call. The extra code doesn’t hurt, but it’s not doing anything of value either.

Hi Alfonse,
Thanks for your input. The extra code I am putting in is for the vao. Actually, I have two vaos and I did not include the vao part, the init code is this


for(int j=0;j<2;j++) {
 glBindVertexArray(vaoID[j]);
 glBindBuffer( GL_ARRAY_BUFFER, vboID_Pos[j]);
 glBufferData( GL_ARRAY_BUFFER, sizeof(position_mass_data), &(position_mass_data[0]), GL_DYNAMIC_DRAW);
 
 glBindTexture( GL_TEXTURE_BUFFER, texID[j]);
 glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F_ARB, vboID_Pos[j]);
 glEnableVertexAttribArray(0);
 glVertexAttribPointer(0,  4, GL_FLOAT, GL_FALSE, 0, 0);
	
 glBindBuffer( GL_ARRAY_BUFFER, vboID_Vel[j]);
 glBufferData( GL_ARRAY_BUFFER, sizeof(velocity_data), &(velocity_data[0]), GL_DYNAMIC_DRAW);
 glEnableVertexAttribArray(1);
 glVertexAttribPointer(1,  4, GL_FLOAT, GL_FALSE, 0,0);
			
 glBindBuffer( GL_ARRAY_BUFFER, vboID_Con);
 glBufferData( GL_ARRAY_BUFFER, sizeof(connection_data), &(connection_data[0]), GL_STATIC_DRAW);
 glEnableVertexAttribArray(2);
 glVertexAttribIPointer(2,  4, GL_INT, 0,0);	
 		 
}

My render code is this


glBindVertexArray( vaoID[readID]);
glActiveTexture( GL_TEXTURE0);			 
glBindTexture( GL_TEXTURE_BUFFER, texID[readID]);
   glDrawArrays(GL_POINTS, 0, MAX_MASSES);
 
   int tmp = readID;
   readID=writeID;
   writeID = tmp;

glBindVertexArray( 0);

I have two vbos for position, attached to attribute 0 and vao[0]. I have two more vbos for velocity attached to attribute 1 and vao[1]. Both position vbos have tbos attached to them. Can I output to an attribute location from where I am reading? If not how do i read from vao[0] and write to vao[1] ?

Both position vbos have tbos attached to them.

Somehow, you seem to have misunderstood, so allow me to explain again.

There are no VBOs or TBOs. Stop calling them that. There are only buffer objects.

They are like pointers to memory. The only difference between one pointer and another is simply what happens to be stored at the pointer’s address. You can pass a pointer to any function that takes a pointer. That function may not actually work, because the pointer doesn’t point to data that the function understands.

You can pass a buffer object to the vertex attribute functions (gl*Pointer). You can pass a buffer object to the buffer texture binding function (glTexBuffer). These functions do not care that the buffer object was or currently is attached to something else.


 glBindBuffer( GL_ARRAY_BUFFER, vboID_Con);
 glBufferData( GL_ARRAY_BUFFER, sizeof(connection_data), &(connection_data[0]), GL_STATIC_DRAW);

This appears to be a copy-and-paste bug. This buffer object is the same in both VAOs. So you should not reallocate its memory; glBufferData is like calling malloc on a pointer. You also shouldn’t reupload data to it; glBufferSubData is like memcpy. It’s just a waste of time. You should create this object outside of the loop and then bind it as needed to the VAOs.

If not how do i read from vao[0] and write to vao[1] ?

VAOs are a completely different object type. As explained here, they are just containers for vertex format. Essentially, they contain the state set by glVertexAttribPointer and all other gl*Pointer functions, as well as the associated enables and disables.

VAOs have essentially nothing to do with this. They’re just a convenient way for you to set up vertex attributes. They store those gl*Pointer commands and essentially replicate them later.

Thanks Alfonse for the clarifications. Where do you get such detials from?

So its just buffer objects (pointers in memory) which are passed to gl*Pointer or any other func. accepting such a pointer. Whether the func. works depends on the data pointed to by the pointer. If the func. understands the data there, it will work. And since its a pointer it can be given to any other function so long as the function can understand the data being pointed by the pointer.

One more thing, from the discussion on allocation, it seems that the allocation of all of these pointers takes place in a global pool and vao contain states and buffer object pointers.

At this point, you real should read the specification. It will make things much clearer. But to reiterate what Alfonse and I have stated before:

A buffer object is thingy of memory that is “handled” by GL.
[ul][li] You allocate that memory with glBufferData[] You can set the values with glBufferSubData[] Through GL calls you can state that data is to be sourced from a buffer object (as attributes, as source for a texture, and also for uniforms [called uniform buffer objects and also called bindable uniforms].[*] There is more too: there is also transform feedback where one can have GL write the output to geometry or vertex shaders to a buffer object, but you are not doing that here.[/ul][/li]

A texture buffer object is not really a thingy at all. To be precise, you can set a texture object to source it’s data from a buffer object this is done by making the texture object a GL_TEXTURE_BUFFER (via the first time it is bound to bind it to GL_TEXTURE_BUFFER), and the source for the texture object is set by the call glTexBuffer. A simple way to view it is that “glTexBuffer allows one to set the pointer, the pointer is the name of a buffer object”.

Vertex Array objects are a container for state that holds the following and no more:
[ul][li] Format for each vertex attribute[] Source for each vertex attribute (i.e. buffer object and offset into the buffer object)[] Source for index data (i.e. buffer object only)[/ul][/li]The first 2 correspond to the parameters of glVertexPointer (and what buffer object is bound to GL_ARRAY_BUFFER when glVertexPointer is called) and the last correspond to what buffer object is bound to GL_ELEMENT_ARRAY_BUFFER.

The GL implementation decides where and how the memory for a buffer object is allocated… typically on PC’s that means VRAM on the video card, the storage hint you pass to glBufferData ideally is used by the GL implementation to decide where the buffer object memory is located (for example GL_STATIC_DRAW will almost always be VRAM).

Thanks kRogue that was awesome.