PPO

I am hoping to speed up my transfers of live video to the OpenGL video card we are using. Currently I transfer with glTexSubImage2D and am thinking of using PPO’s. I have a sample, and have some questions about it:

In my sample, it constructs a “temp buffer” with this call:

 glGenBuffersARB(1, &pboID); 
 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboID); 
 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, bytes, NULL, GL_STREAM_DRAW_ARB); 
 CHECK_GL(); 

Should this happen every frame, or only once during startup?

Also with this call:

glDeleteBuffersARB(1, &pboID);

should this happen every frame, or only once at shutdown?

Currently I transfer with glTexSubImage2D and am thinking of using PPO’s.
I think you mean PBO: Pixel Buffer Object.

Should this happen every frame, or only once during startup?
Just during startup. This allocates the buffer object and allocates memory for the buffer itself. Unless you need to resize the buffer, you should only do this once.

Same with the deletion.

You should take a look at the performance sample of PBOs at nvidias homepage. I have the same situation where i upload video in real time to textures but I have found out that its very HW dependant and VERY image format dependant. When it comes to Nvidia HW you almost get worse performance if you are using standard RGB or RGBA images. ATI hw improves in general and a lot on osx so the conclusion is that i have a performance matrix with image format, hw and operating system as a lut to see if the pbos are good or not. phew…

Thanks for the ideas guys. I have modified my code so that it is setting things up once, and then using them. It is very fast on the transfer. Unfortunately all I get is an olive green texture. Do you see anything obvious I am doing wrong?

Setup code

 
				bytes = width * height * 3;

				glGenBuffersARB(1, &m_extension_buffer_id); 
				glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_extension_buffer_id); 
				glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, bytes, NULL, GL_STREAM_DRAW_ARB);
 

Texture binding code:

 
	int bytes = 0;
	void * data = NULL;
	if (m_extension_buffer_allocated) 
	{
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, m_video_texture_index_id );
		glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_extension_buffer_id);

		bytes = width * height * 3;

		data = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); 
		if (data != NULL)
		{
			memcpy(data, input_buffer, bytes); 
			glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); 
			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, 0);			
			

		}
		glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
		
	

 

Cleanup code:

  
	if (m_extension_buffer_allocated == true)
	{
		glDeleteBuffersARB(1, &m_extension_buffer_id); 
	}