Sign in to follow this  
A_SN

updating framebuffer using FBOs

Recommended Posts

I currently display a buffer on screen using a mere call of glDrawPixels(). It's great but it's very slow. The buffer is a uint32 array of very arbitrary dimensions. I tried replacing the glDrawPixels (width, height, GL_BGRA, GL_UNSIGNED_BYTE, fb); call using PBOs, unfortunately despite all the Googling and reading of threads on the topic of PBOs in this forum, I still couldn't come up with something that works, I'm stuck with the following code that only gives me a blue square :
Outside of the loop :

	// Texture mapping
	uint32_t bufferID, textureID;

	glEnable (GL_TEXTURE_2D);
	//glGenBuffers(1, &bufferID);	// causes a crash
	glGenTextures(1, &textureID);
	glBindTexture (GL_TEXTURE_RECTANGLE_ARB, textureID);
	glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); 

	glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, fb);
	//glBufferData (GL_PIXEL_UNPACK_BUFFER_ARB, width*height*sizeof(uint32_t), NULL, GL_STREAM_DRAW); // causes a crash too
	//fb = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);   
	//memcpy (fb, fData, (4 * iTexW * iTexH * sizeof(float)));
	//glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); 
	
	//glBufferData (GL_ARRAY_BUFFER, width*height*sizeof(uint32_t), fb, GL_DYNAMIC_DRAW);
	//glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, fb);

....
Inside the main running loop :

	glBindTexture (GL_TEXTURE_RECTANGLE_ARB, textureID);
	glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, fb);
	glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, fb);
	glBegin (GL_QUADS);
	glTexCoord2f (0.0, 0.0);	glVertex3f (0.0, 0.0, 0.0);
	glTexCoord2f (1.0, 0.0);	glVertex3f (100.0, 0.0, 0.0);
	glTexCoord2f (1.0, 1.0);	glVertex3f (100.0, 100.0, 0.0);
	glTexCoord2f (0.0, 1.0);	glVertex3f (0.0, 100.0, 0.0);
	glEnd ();
	glFinish(); 
Can anyone tell me what I'm doing wrong please? [Edited by - A_SN on May 31, 2009 3:49:19 AM]

Share this post


Link to post
Share on other sites

glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, fb);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, fb);




These almost certainly shouldn't be in your main drawing loop, not only will these constantly destroy and recreate the data in your texture, you're then overwriting it with the glTexSubImage2D call.

Also, in your generation code, where are you populating the fb buffer? What data are you putting into it?

Edit: Please rename the title of the thread, most people won't look at a thread called 'Untitled'

Share this post


Link to post
Share on other sites
Quote:
Original post by AndyEsser
*** Source Snippet Removed ***

These almost certainly shouldn't be in your main drawing loop, not only will these constantly destroy and recreate the data in your texture, you're then overwriting it with the glTexSubImage2D call.

Also, in your generation code, where are you populating the fb buffer? What data are you putting into it?

Edit: Please rename the title of the thread, most people won't look at a thread called 'Untitled'


Oops yeah sorry, hadn't seen I had forgotten to put a title (this must be the only board I've seen that'll let you get away without a title).

Anyways, I need to update it constantly because fb is a framebuffer and needs to be displayed to a window, it's not a regular static texture. The fact remains that all I see is a blue square though :-( any ideas?

Share this post


Link to post
Share on other sites
Quote:
Original post by bubu LV
You have in topic title word FBO - Framebuffer Object. But in your code there is nothing regarding FBOs. You are just uploading some bytes to texture, and displaying this texture.

What exactly are you trying to do?


Yeah I'm not sure what FBOs are, I read about it but I'm not sure I got how it works, but I was told it'd be much faster that using glDrawPixels.

What I'm trying to do is to display a framebuffer pointed to by pointer fb on a window, this means updating it tens of times a second. Sorry, I'm quite new to OpenGL actually...

Share this post


Link to post
Share on other sites
FBO are usually used when you want to render scene to texture, and later use this texture for some postprocessing or just displaying as image in your scene.

Quote:
Original post by A_SN
What I'm trying to do is to display a framebuffer pointed to by pointer fb on a window, this means updating it tens of times a second.

Are you simply trying to render pixels from memory? Then PBO is way to go for best performance. But in simplest case just create one texture, and use glTexSubImage2D to upload each frame data.

Share this post


Link to post
Share on other sites
Quote:
Original post by bubu LV
FBO are usually used when you want to render scene to texture, and later use this texture for some postprocessing or just displaying as image in your scene.

Quote:
Original post by A_SN
What I'm trying to do is to display a framebuffer pointed to by pointer fb on a window, this means updating it tens of times a second.

Are you simply trying to render pixels from memory? Then PBO is way to go for best performance. But in simplest case just create one texture, and use glTexSubImage2D to upload each frame data.


Oh yeah, oops, I said FBO in the title, I guess I meant PBO.

The problem with PBOs is, as you could see in my code, that's precisely what I tried to do, the glTexSubImage2D thing. But it doesn't work, all I get is a blue square. So what's wrong with my code?

Share this post


Link to post
Share on other sites
For PBO your code is incomplete - you are missing PBO object binding. Check the examples here:
http://www.songho.ca/opengl/gl_pbo.html
and
http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt (Streaming textures using pixel buffer objects)

As for your blue color - are you correctly filling data in memory pointed by fb variable?
And there is no need to call glTexImage2D in main running loop. Allocate texture memory only at startup.

Share this post


Link to post
Share on other sites
Quote:
Original post by A_SN
I'm not sure what FBOs are


The idea (behind FBO; dunno about PBO) is that you enable a FBO to be rendered to, and attach a texture to it (and a depth buffer, it seems), so that the FBO will fill the texture itself when you draw stuff. You don't need to be copying those pixels to texture every frame. After the FBO is done with it, you should be able to bind that texture and render something with it.

Here is a tutorial (first link on Google).

Share this post


Link to post
Share on other sites
Quote:
Original post by bubu LV
For PBO your code is incomplete - you are missing PBO object binding. Check the examples here:
http://www.songho.ca/opengl/gl_pbo.html
and
http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt (Streaming textures using pixel buffer objects)


That's hardly helpful, my code still crashes at either glGenBuffers or glGenBuffersARB...

Quote:
As for your blue color - are you correctly filling data in memory pointed by fb variable?

Yes, that's why glDrawPixels works. All I'm trying to do is replace that single glDrawPixels call...

Quote:
Original post by lightbringer
Here is a tutorial (first link on Google).

Thanks but it also crashes as soon as it gets to glGenFramebuffersEXT()...

By the way in case that helps with my crashes here's what I run prior to these calls :


glfwInit();
glfwOpenWindow (width, height, 8, 8, 8, 8, 24, 0, GLFW_WINDOW));

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glOrtho(0, width, 0, height, -1, 1);
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
float scale = 1.f;
glScalef(scale, -scale, scale);
glTranslatef(0, -height/scale, 0);

glPixelZoom (scale, -scale);
glRasterPos2i (0, 0);
glEnable(GL_TEXTURE_2D);

Share this post


Link to post
Share on other sites
Are you loading entry points for extension functions yourself? Or are you using GLEE or GLEW? Check with debugger if crashing functions (glGenBuffers, glGenBuffersARB, glGenFramebuffersEXT) are not NULL.

Share this post


Link to post
Share on other sites
Quote:
Original post by bubu LV
Are you loading entry points for extension functions yourself? Or are you using GLEE or GLEW? Check with debugger if crashing functions (glGenBuffers, glGenBuffersARB, glGenFramebuffersEXT) are not NULL.


They are indeed NULL. It's strange that the compiler/linker wouldn't warn me about not finding them though. I'm using GLFW, although I have GLEW ready to be used, what do I have to do to get access to those?

Share this post


Link to post
Share on other sites
Not finding them is something different than them being NULL. Compiler and linker finds function declarations and compiles/links just fine. It doesn't know what will be their values at runtime.

And GLFW has nothing to do with extensions, it is used only for opening window.

To load extension entry points you can use platform specific API (on Windows - wglGetProcAddress) or GLEW (http://glew.sourceforge.net/basic.html) or GLEE (http://elf-stone.com/glee.php).

Share this post


Link to post
Share on other sites
Quote:
Original post by bubu LV
Not finding them is something different than them being NULL. Compiler and linker finds function declarations and compiles/links just fine. It doesn't know what will be their values at runtime.

And GLFW has nothing to do with extensions, it is used only for opening window.

To load extension entry points you can use platform specific API (on Windows - wglGetProcAddress) or GLEW (http://glew.sourceforge.net/basic.html) or GLEE (http://elf-stone.com/glee.php).


OK, thanks, I got it working now. Here's my code, I'm still not sure what it does in full details, if you can see anything wrong/inefficient, I'd be thankful :).

Initalisation:

unsigned int pBuffer;

glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGenBuffers(1, &pBuffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pBuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pBuffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width*height*sizeof(uint32_t), NULL, GL_STREAM_DRAW);
void *pboMemory = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);


In the loop:

memcpy(pboMemory, fb, width*height*sizeof(uint32_t));
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pBuffer);

glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
glEnd();
glDisable(GL_TEXTURE_2D);

Share this post


Link to post
Share on other sites
If you are using only one PBO, then no need to call glBindBuffer all the time. Just call it once - right after glGenBuffers.
Also you are calling glUnmapBuffer in the loop, but not glMapBuffer? You shuld call them both:
void* ptr = glMapBuffer();
memcpy(ptr, source, size);
glUnmapBuffer();
glTexSubImage(..)


Also check OpenGL errors by calling glGetError() after each OpenGL function call.

Share this post


Link to post
Share on other sites
Quote:
Original post by bubu LV
If you are using only one PBO, then no need to call glBindBuffer all the time. Just call it once - right after glGenBuffers.
Also you are calling glUnmapBuffer in the loop, but not glMapBuffer? You shuld call them both:
void* ptr = glMapBuffer();
memcpy(ptr, source, size);
glUnmapBuffer();
glTexSubImage(..)


Also check OpenGL errors by calling glGetError() after each OpenGL function call.


Oh yeah oops, the mapping, didn't even notice that my buffer stopped updating.

[Edited by - A_SN on June 1, 2009 7:24:40 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this