Skip to main content
GameDev.net gamedev.net
🔒 Locked

FrameBuffer to Texture?

Started by kelmer Aug 10, 2007 at 6:00 AM 11 replies 2.5k views
Original Post
kelmer
kelmer
Is there any way to use the content of the framebuffer as a texture for an object? I want to project my application over a semispherical surface (something like a DOME screen) and I understand that overimposing the rendered scene into a big sphere with the proper parameters would be the simplest of the solutions (even if it's not the most efficient). Later on I plan on doing perspective correction mathematically, but as a workaround I would like to try this approach. Any suggestions?
coordz
coordz
You can either use glCopyTexImage2D() to copy the framebuffer into your texture or (better) set up a framebuffer object with your texture bound to it. Have a look here for an intro to that.
Ekast
Ekast
If you target newer graphics hardware which supports FBO´s, imho you should definitely use FBOs instead of using something like rendering to a pbuffer etc. I´ve just replaced some render to texture code using pBuffers by FBOs and the performance gain is pretty high.
Besides that it´s a lot easier to implement since you don´t have to care about all these decice context setups.

Another source for it might be the NVIDIA-Code Samples Site or this one. The latter one has several RTT samples.

Regards

Ralph
kelmer
kelmer
Thanks, that was really helpful :)
kelmer
kelmer
Hi again,

I tried glCopyTexImage2D() and it works okay except for the fact that I get too bad quality textures for my sphere; If I use textures bigger than 512x512 (in order to enhance quality) I get some weird results, the texture covering only 1/4 of the sphere (the rest is black or shows some artifacts).

Anyway, I'm trying the FBO samples that Evast pointed out, over at http://graphics.harvestsoft.net/index.php?page=opengl , but I get an "Error: EXT_framebuffer_object is not supported. " message. Maybe I should use a specific version of OpenGL (I'm using 2.1, which AFAIK is the latest one)?
VerMan
VerMan
Quote:
Error: EXT_framebuffer_object is not supported


That is because your graphic card does not support FBO (typical), so you must stick with pbuffers or switch to DX or use this wrapper class that renders to a texture using pbuffers (thanks to the GPGPU.org guys)
kelmer
kelmer
That wrapper seems to be the thing, but looks like my card doesn't even support it, as it needs the following extension: WGL_ARB_pbufferRenderTexture

:(

CodeMunkie
CodeMunkie
Post some code. If glCopyTexImage2D is producing an image where 1/4 is black then you probably just aren't setting up your viewport and/or projection matrix correctly when you do your offscreen rendering, or you are not creating a large enough texture or passing incorrect sizes to glCopyTexImage2D, etc.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
zedz
zedz
Quote:
Maybe I should use a specific version of OpenGL (I'm using 2.1, which AFAIK is the latest one)
your card should support FBO, what is it? do u have new drivers installed.

though glCopyTexSubImage2D(...) should be just as fast ( or perhaps faster ) + is perhaps simplier to use
kelmer
kelmer
My Graphics card is an Intel 82852/82855 GM/GME Graphics Controller, integrated with the chipset of my laptop.

These are the functions I use for rendering the scene into my texture:

void cargaTexturaGrande(){
/*this one prepares the texture variable in order to be copied from the framebuffer later. faketex is just an array the size of the texture (xSize, ySize) to create a the Texture with a blank data. */

glGenTextures(1,&bigtexture);
glBindTexture(GL_TEXTURE_2D,bigtexture);

glTexImage2D(GL_TEXTURE_2D,0 ,3 , xSize,
ySize, 0 , GL_RGB,
GL_UNSIGNED_BYTE, faketex);


glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);


delete[] faketex;
}

void daleTextura(){ //this one

glViewport(0,0,xSize,ySize); //we change the viewport into the new one

SistemaSolar(); //this is the function that sets the image to be rendered to texture;


//save data to texture using glCopyTexImage2D
glBindTexture(GL_TEXTURE_2D,bigtexture);

glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
0,0, xSize, ySize, 0);

//restore viewport
glViewport(0,0,W_WIDTH,W_HEIGHT);
}

I call cargaTexturaGrande from the main() function and daleTextura from my Idle function, in order for the texture to change along with my rendering.

If I set W_WIDTH to a size different from xSize & ySize I get strange results, like that I mentioned about the texture only covering 1/4 of the sphere.


for reference, here's the SistemaSolar function, which just creates some planets around a Sun. Sorry for the Scomments in Spanish:
void SistemaSolar(){
//draw a misc scene
/****/
//Color del fondo
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Limpia los buffer de color y profundidad


//Se activa la matriz del modelador
//glMatrixMode(GL_MODELVIEW);
glViewport(0,0,xSize,ySize);
//Activamos la matriz de proyección para mover la cámara
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f,1.0,1.0,6000.0);

glTranslatef(0,0,-900);
//glTranslatef(0,10,posz);
//glRotatef(fAnguloCamara, 0.0, 1.0, 0.0);

//Se activa la matriz del modelador
glMatrixMode(GL_MODELVIEW);

//Inicializamos la matriz del modelo a la identidad
glLoadIdentity();
//glRotatef(rotacamaraz,0,0,1);
//glRotatef(rotacamarax,1,0,0);
//glRotatef(rotacamaray,0,1,0);
glPushMatrix();
creaSol(textura, rotacion);
glPopMatrix();
//glEnable(GL_LIGHTING);
//glEnable(GL_LIGHT0);

glPushMatrix(); //Hago un push a la matriz para recordar su posicion despues
creaTierra(orbitas, texturatierra, texturaluna, fAnguloTierra, rotacion);
glPopMatrix();

glPushMatrix(); //Hago un push a la matriz para recordar su posicion despues
creaMercurio(orbitas, texturam, fAnguloMercurio, rotacion);
glPopMatrix();

glPushMatrix(); //Hago un push a la matriz para recordar su posicion despues
creaVenus(orbitas, texturav, fAnguloVenus, rotacion);
glPopMatrix();

glPushMatrix();
creaCometa(x, z, fAnguloTierra, texturacometa);
glPopMatrix();

glPushMatrix();
creaSaturno(orbitas, texturasaturno, fAnguloSaturno, rotacion);
glPopMatrix();

//glutSwapBuffers(); // Intercambia los dos buffers gráficos disponibles
glFlush();// Vacia todos los Buffers

}
zedz
zedz
intel youre prolly out of luck then
had a look here couldnt see the chipset so dont know if its good
http://en.wikipedia.org/wiki/Intel_graphics_media_accelerator

just use glCopyTexSubImage2D
perhaps post a screenshot of what u have + why its not good enuf
kelmer
kelmer
Sure:

Image Hosted by ImageShack.us
This is the scene using a 512x512 texture. As you can see, the quality I get is quite poor.

Image Hosted by ImageShack.us
This is the result using a 1024 x 1024
V-man
V-man
Quote:
Original post by zedz
Quote:
Maybe I should use a specific version of OpenGL (I'm using 2.1, which AFAIK is the latest one)
your card should support FBO, what is it? do u have new drivers installed.

though glCopyTexSubImage2D(...) should be just as fast ( or perhaps faster ) + is perhaps simplier to use


Intel doesn't support 2.1

Use glGetString(GL_VERSION)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.