I want to load a texture on one of my faces on a cube. All the other faces have a specific color that I put on them. The problem is that, when I try to apply the texture, it will not display it. Instead, the last texture used on the cube is being applied.
Here is a code sample :
Engine::Engine() : m_isMovingUp(false), m_isMovingDown(false), m_isMovingLeft(false), m_isMovingRight(false), m_context(24, 8, 4, 3, 3), m_angleX(0), m_angleZ(0), m_mov(3.0f, 3.0f, 3.0f)
{
//Window settings
m_win.create(sf::VideoMode(800, 600), "SFML Event and with some OpenGL graphics", sf::Style::Default, m_context);
m_win.setFramerateLimit(60);
//Opengl settings
glEnable(GL_TEXTURE_2D);
m_textureID = loadTexture("/Data/test.jpg");
}
void Engine::run()
{
bool running = true;
while (running)
{
processEvents();
update();
render();
}
}
void Engine::cube()
{
//glRotated(m_angleX, 1, 0, 0);
//glRotated(m_angleZ, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, m_textureID);
glBegin(GL_QUADS);
//face Rouge
//glColor3ub(255, 0, 0);
glTexCoord2d(0, 1); glVertex3d(1, 1, 1);
glTexCoord2d(0, 0); glVertex3d(1, 1, -1);
glTexCoord2d(1, 0); glVertex3d(-1, 1, -1);
glTexCoord2d(1, 1); glVertex3d(-1, 1, 1);
glEnd();
glBegin(GL_QUADS);
//face verte
glColor3ub(0, 255, 0);
glVertex3d(1, -1, 1);
glVertex3d(1, -1, -1);
glVertex3d(1, 1, -1);
glVertex3d(1, 1, 1);
//face bleu
glColor3ub(0, 0, 255);
glVertex3d(1, -1, 1);
glVertex3d(-1, -1, 1);
glVertex3d(-1, -1, -1);
glVertex3d(1, -1, -1);
//face jaune
glColor3ub(255, 255, 0);
glVertex3d(-1, 1, 1);
glVertex3d(-1, 1, -1);
glVertex3d(-1, -1, -1);
glVertex3d(-1, -1, 1);
//face cyan
glColor3ub(0, 255, 255);
glVertex3d(1, 1, -1);
glVertex3d(1, -1, -1);
glVertex3d(-1, -1, -1);
glVertex3d(-1, 1, -1);
//face magenta
glColor3ub(255, 0, 255);
glVertex3d(1, -1, 1);
glVertex3d(1, 1, 1);
glVertex3d(-1, 1, 1);
glVertex3d(-1, -1, 1);
glEnd();
glFlush();
}
GLuint Engine::loadTexture(string file)
{
GLuint textureID;
if (!m_image.loadFromFile(file))
EXIT_FAILURE;
glGenTextures(1, &textureID);
//glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, 4, m_image.getSize().x, m_image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.getPixelsPtr());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return textureID;
}
This is where I'm at after fixing as much as I could.
PS : CODE UPDATED & PICTURE ADDED
Picture of my cube
I see two mistakes in the pastebin code:
Line 27:
glBindTexture(GL_TEXTURE_2D, 0);
You can not change the bound texture in between glBegin and glEnd calls. You will have to split rendering of the textured and not textured faces to their own begin-end blocks.
Line 74:
glTexImage2D(GL_TEXTURE_2D, 0, 4, m_image.getSize().x, m_image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, &m_image.getPixelsPtr);
The last parameter should be m_image.getPixelsPtr() not &m_image.getPixelsPtr. You are taking address of the method and using it as image data. The method getPixelsPtr will give you pointer to the image data if you call it.
Also it seems that you are creating new texture and loading image into it on every frame. If it is just in this example that renders once, then it is ok. But in actual program it would have big impact on performance and the program would soon run out of memory.
There may be more problems, it can't be told without seeing the whole code. If you can, upload somewhere a minimal complete example.
Related
I want to dabble in some procedural textures in an OpenGL project, but nothing seems to work. All I need is to input the RGB and maybe A values into an empty texture, instead of loading it from a file. How do I do this, in actual, practical code?
Edit: There is no main code yet, because I have found nothing that works. The current best guess is this:
void GenerateTexture()
{
unsigned char image_data[16] = {0, 0, 150, 255, 125, 0, 0, 255, 0, 0, 150, 255, 125, 0, 0, 255};
glGenTextures(1, &tex_obj);
glBindTexture(GL_TEXTURE_2D, tex_obj);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
}
... implemented like this:
glBegin (GL_QUADS);
if (*irrelevant for question*){
glTexCoord2f(0.0,1.0);
glVertex3f (-0.45-cam.pos.val[0], 0.45-cam.pos.val[1], 0.45-cam.pos.val[2]);
glTexCoord2f(0.0,0.0);
glVertex3f (-0.45-cam.pos.val[0], -0.45-cam.pos.val[1], 0.45-cam.pos.val[2]);
glTexCoord2f(1.0,0.0);
glVertex3f (0.45-cam.pos.val[0], -0.45-cam.pos.val[1], 0.45-cam.pos.val[2]);
glTexCoord2f(1.0,1.0);
glVertex3f (0.45-cam.pos.val[0], 0.45-cam.pos.val[1], 0.45-cam.pos.val[2]);
}
glEnd ();
... but as soon as it is run with more than a 1x1 texture, it just goes clean white.
Create an array of data and load it into a texture image:
uint8_t image_data[4] = {255, 0, 0, 255}; // red
GLuint tex_obj;
glGenTextures(1, &tex_obj);
glBindTexture(GL_TEXTURE_2D, tex_obj);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
I am trying to make a stroke for chests in a minecraft game and I almost succeeded, but for some reason it is not drawn correctly.
ScreenShot
The screenshot shows how part of the line has disappeared. This happens when the line is on the chest. Maybe it's a texture mapping or something else. In this case, the stroke is drawn through the blocks normally.
ScreenShot2
Also, when the chest is in the dark, the outline becomes dark, although I turned off GL_LIGHTING
ScreenShot3
Here is a piece of code with which I draw the stroke
glPushAttrib(GL_ALL_ATTRIB_BITS);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glLineWidth(2);
glColor3ub(255, 255, 255);
glBegin(GL_LINES);
glVertex3f(1, 0, 0);
glVertex3f(1, -1, 0);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, -1, 0);
glVertex3f(0, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, -1, -1);
glVertex3f(1, -1, -1);
glVertex3f(1, 0, -1);
glVertex3f(1, -1, -1);
glVertex3f(0, -1, -1);
glVertex3f(0, -1, -1);
glVertex3f(0, -1, 0);
glVertex3f(0, -1, -1);
glVertex3f(0, 0, -1);
glVertex3f(0, 0, -1);
glVertex3f(1, 0, -1);
glVertex3f(0, 0, -1);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, -1);
glVertex3f(1, 0, 0);
glEnd();
glPopAttrib();
What can be wrong?
From your screenshots it seems that the order of rendering is the following:
terrain
outline
chest
Now since you have disabled GL_DEPTH_TEST in step 2, the fragments (pixels) that turned white (those on which the outline is drawn), won't get their depth information updated. That's because disabling GL_DEPTH_TEST not only disables depth testing, but also disables updating the depth information of fragments.
So when you finally draw the chest (with depth testing re-enabled), it will be drawn over all the fragments whose depth value indicates that they are behind it. That means, also over the fragments where the outline is drawn.
The black color of the outline on the third screenshot may be caused by your call to glBindTexture(GL_TEXTURE_2D, 0);. But that's just a hunch.
I'm currently trying to test out rendering to a framebuffer for various uses, but whenever I have an object(say a square) at a certain y-value, it appears "stretched", and then past a certain y-value or a certain x-value it seems to "thin out" and disappears. I have determined the x and y-values that it disappears at, but the coordinates seem to not have any rhyme or reason.
When I remove the framebuffer binding and render directly to the screen it draws the square perfectly fine, no matter the x or y-value.
Drawing a basic square(using immediate mode to remove possible errors) with a wide x-value looks like this:
Code here:
Window window("Framebuffer Testing", 1600, 900); //1600x900 right now
int fbowidth = 800, fboheight = 600;
mat4 ortho = mat4::orthographic(0, width, 0, height, -1.0f, 1.0f);
//trimmed out some code from shader creation that is bugless and unneccessary to include
Shader shader("basic"); shader.setUniform("pr_matrix", ortho);
Shader drawFromFBO("fbotest"); shader.setUniform("pr_matrix", ortho);
GLfloat screenVertices[] = {
0, 0, 0, 0, height, 0,
width, height, 0, width, 0, 0};
GLushort indices[] = {
0, 1, 2,
2, 3, 0 };
GLfloat texcoords[] = { //texcoords sent to the drawFromFBO shader
0, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 0 };
IndexBuffer ibo(indices, 6);
VertexArray vao;
vao.addBuffer(new Buffer(screenVertices, 4 * 3, 3), 0);
vao.addBuffer(new Buffer(texcoords, 2 * 6, 2), 1);
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbowidth, fboheight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "false" << std::endl;
glEnable(GL_TEXTURE_2D);
//the x-values mess up at ~783 thru 800 and the y-values at 0 thru ~313
while(!window.closed()) {
glClearColor(0.2f, 0.2f, 0.2f, 1.0f); //grey
window.clear(); //calls glclear for depth and color buffer
//bind framebuffer and shader
shader.enable(); //literally just calls glUseProgram(id) with the compiled shader id
glViewport(0, 0, fbowidth, fboheight);
glBindFramebuffer(GL_FRAMEBUFFER, fbo); //bind the fbo
glClearColor(1.0f, 0.0f, 1.0f, 1.0f); //set clear color to pink
glClear(GL_COLOR_BUFFER_BIT);
//render a red square to the framebuffer texture
glBegin(GL_QUADS); {
glColor3f(1.0f, 0.0f, 0.0f); //set the color to red
glVertex3f(700, 400, 0);
glVertex3f(700, 450, 0);
glVertex3f(750, 450, 0);
glVertex3f(750, 400, 0);
} glEnd();
shader.disable();
glBindFramebuffer(GL_FRAMEBUFFER, 0); //set framebuffer to the default
//render from framebuffer to screen
glViewport(0, 0, width, height);
drawFromFBO.enable();
glActiveTexture(GL_TEXTURE0);
drawFromFBO.setUniform1i("texfbo0", 0);
glBindTexture(GL_TEXTURE_2D, texture);
vao.bind();
ibo.bind();
glDrawElements(GL_TRIANGLES, ibo.getCount(), GL_UNSIGNED_SHORT, NULL);
ibo.unbind();
vao.unbind();
drawFromFBO.disable();
window.update();
}
If you want to see any thing extra, the file is located at my Github: here
I' experimenting in draw to texture with opengl.
I've found this simple and clear c code that do that (see in the end).
It draws a cube on a texture, and then a cube on the screen using the previous texture. The generated image is a cube with, in the textures, a lot of cube inside a cube inside a cube etc..: it seems a recursion loop.
But why? I was expecting only 2 cubes. And It seems an infinite recursion loop.. where is the actual recursion? and when does it stops?
/* ============================================================================
**
** Demonstration of rendering to texture
** Copyright (C) 2005 Julien Guertault
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** ========================================================================= */
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define SIZE 256
static unsigned char texture[3 * SIZE * SIZE];
static unsigned int texture_id;
static int window_width = 500;
static int window_height = 500;
/*
** Just a textured cube
*/
void Cube(void)
{
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, -1, 1);
glTexCoord2i(1, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 0); glVertex3f(-1, 1, -1);
glTexCoord2i(0, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 1); glVertex3f( 1, -1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, -1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, -1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, 1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, -1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, -1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, 1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, 1);
glEnd();
}
/*
** Function called to update rendering
*/
void DisplayFunc(void)
{
static float alpha = 20;
glLoadIdentity();
glTranslatef(0, 0, -10);
glRotatef(alpha, 1, 0, 0);
glRotatef(20 , 0, 1, 0);
/* Define a view-port adapted to the texture */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, 1, 5, 15);
glViewport(0, 0, SIZE, SIZE);
glMatrixMode(GL_MODELVIEW);
/* Render to buffer */
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Cube();
glFlush();
/* Copy buffer to texture */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, SIZE - 10, SIZE - 10);
/* Render to screen */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, window_width / (float) window_height, 5, 15);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Cube();
/* End */
glFlush();
glutSwapBuffers();
/* Update again and again */
alpha = alpha + 0.1;
glutPostRedisplay();
}
/*
** Function called when the window is created or resized
*/
void ReshapeFunc(int width, int height)
{
window_width = width;
window_height = height;
glutPostRedisplay();
}
/*
** Function called when a key is hit
*/
void KeyboardFunc(unsigned char key, int x, int y)
{
int foo;
foo = x + y; /* Has no effect: just to avoid a warning */
printf("%d",foo);
if ('q' == key || 'Q' == key || 27 == key)
exit(0);
}
int main(int argc, char **argv)
{
/* Creation of the window */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("Render to texture");
/* OpenGL settings */
glEnable(GL_DEPTH_TEST);
/* Texture setting */
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIZE, SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
/* Declaration of the callbacks */
glutDisplayFunc(&DisplayFunc);
glutReshapeFunc(&ReshapeFunc);
glutKeyboardFunc(&KeyboardFunc);
/* Loop */
glutMainLoop();
/* Never reached */
return 0;
}
/* ========================================================================= */
But why? I was expecting only 2 cubes. And It seems an infinite recursion loop.. where is the actual recursion? and when does it stops?
It's a feedback loop. Small experiment for you: Take a webcam connect it to your computer and let it show a live picture of the webcam. Now point the webcam on the screen so that it looks at the image it produced.
This is kind of what happens here: A cube with a texture is drawn. That picture is now copied to the texture. Then the cube is drawn again, but this time the texture already contains that cube so it's a cube with cubes on it. Also, for your pleasure the same cube is drawn to the screen, but that doesn't feed back.
If you want to have one nesting deep, you must disable texturing when drawing the cube that gets copied to the texture.
Update Code modification that doesn't recurse
void DisplayFunc(void)
{
First render without texture so we don't feed back. Also make the drawing color black, so this will result in a solid black cube on black background.
/* Render to buffer */
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D); /* <<<<<< */
glColor3f(0,0,0); /* <<<<<< */
Cube();
On a side note: For this there should really a frame buffer object be used, instead of relying on the back buffer to not be clobbered (overlapping windows may make it fail the pixel ownership test).
/* Copy buffer to texture */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, SIZE-10, SIZE-10);
/* Render to screen */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, window_width / (float) window_height, 5, 15);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Reenable texturing and switch color to white so that we can see the texture (or use GL_REPLACE texture mode).
glEnable(GL_TEXTURE_2D);
glColor3f(1,1,1);
Cube();
/* End */
glFlush();
glutSwapBuffers();
/* Update again and again */
alpha = alpha + 0.1;
glutPostRedisplay();
}
I've got a fairly complicated scene with many GL_POINTS that I need to render. The scene will be largely static, so I'd like to render it to a Framebuffer Object and then only update that FBO when my scene actually changes. I'd then like to render the FBO to the screen each frame.
I've found examples that render an FBO into a texture. I've found examples that render an FBO into a RenderBuffer (still not quite sure what that is). I'm not sure what the steps are to achieve this. Do I need to render to a texture and the draw the texture to the screen?
Can you please enumerate the steps (ideally even in pseudocode or actual code) to render my scene to an FBO and then draw that FBO to the screen.
draw() is sufficient for a placeholder for my own drawing functions.
I provide a minimal FBO example just for this
Basically the steps are: Create FBO with depth renderbuffer and color texture attachment. To render to FBO unbind the target texture, bind FBO, render to FBO. Unbind FBO, bind texture, render.
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
void init();
void display();
int const fbo_width = 512;
int const fbo_height = 512;
GLuint fb, color, depth;
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow("FBO test");
glutDisplayFunc(display);
glutIdleFunc(glutPostRedisplay);
glewInit();
init();
glutMainLoop();
return 0;
}
void CHECK_FRAMEBUFFER_STATUS()
{
GLenum status;
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
/* choose different formats */
break;
default:
/* programming error; will fail on all hardware */
fputs("Framebuffer Error\n", stderr);
exit(-1);
}
}
float const light_dir[]={1,1,1,0};
float const light_color[]={1,0.95,0.9,1};
void init()
{
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glGenRenderbuffers(1, &depth);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
fbo_width, fbo_height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
CHECK_FRAMEBUFFER_STATUS();
}
void prepare()
{
static float a=0, b=0, c=0;
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0,0, fbo_width, fbo_height);
glClearColor(1,1,1,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 1, 1, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
glTranslatef(0,0,-5);
glRotatef(a, 1, 0, 0);
glRotatef(b, 0, 1, 0);
glRotatef(c, 0, 0, 1);
glutSolidTeapot(0.75);
a=fmod(a+0.1, 360.);
b=fmod(b+0.5, 360.);
c=fmod(c+0.25, 360.);
}
void final()
{
static float a=0, b=0, c=0;
const int win_width = glutGet(GLUT_WINDOW_WIDTH);
const int win_height = glutGet(GLUT_WINDOW_HEIGHT);
const float aspect = (float)win_width/(float)win_height;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0, win_width, win_height);
glClearColor(1.,1.,1.,0.);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-5);
glRotatef(b, 0, 1, 0);
b=fmod(b+0.5, 360.);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, color);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_LIGHTING);
float cube[][5]=
{
{-1, -1, -1, 0, 0},
{ 1, -1, -1, 1, 0},
{ 1, 1, -1, 1, 1},
{-1, 1, -1, 0, 1},
{-1, -1, 1, -1, 0},
{ 1, -1, 1, 0, 0},
{ 1, 1, 1, 0, 1},
{-1, 1, 1, -1, 1},
};
unsigned int faces[]=
{
0, 1, 2, 3,
1, 5, 6, 2,
5, 4, 7, 6,
4, 0, 3, 7,
3, 2, 6, 7,
4, 5, 1, 0
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 5*sizeof(float), &cube[0][0]);
glTexCoordPointer(2, GL_FLOAT, 5*sizeof(float), &cube[0][3]);
glCullFace(GL_BACK);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces);
glCullFace(GL_FRONT);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void display()
{
prepare();
final();
glutSwapBuffers();
}
Here is alternative example which does not require textures:
// copy framebuffer
if(fboUsed)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT,
0, 0, screenWidth, screenHeight,
GL_COLOR_BUFFER_BIT,
GL_LINEAR);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
Replace variables in blit with your own.
Apperently frame buffer 0 is front buffer.
fboId is your frame buffer number.