#include <GL/glew.h>
#include <GL/glut.h>
#include <stdio.h>
int window ;
int width = 600;
int height = 600;
float eye[] = { 0.0, -1.0, 10.0 };
float lookat[] = { 0.0, 100.0, 0.0 };
float up[] = { 0.0, 0.0, 1.0 };
enum swizzle { X=0, Y=1, Z=2 };
float fov = 60.0;
struct FBO
{
GLuint id; // FBO Handle
GLuint colorID; // Color Attachment Handle
GLuint depthID; // Depth Attachment Handle
GLenum depth_format; // GL_DEPTH_COMPONENT24, ...
FBO() : id(0), colorID(0), depthID(0) {}
} ;
FBO fbo24 ;
FBO fbo32 ;
float near_clip = 0.001 ;
float far_clip = 1000.0 ;
void initFBO( FBO &fbo )
{
if( fbo.id != 0 )
{
glDeleteRenderbuffers( 1, &fbo.colorID );
glDeleteRenderbuffers( 1, &fbo.depthID );
glDeleteFramebuffers( 1, &fbo.id );
fbo.colorID = fbo.depthID = fbo.id = 0;
}
glGenFramebuffers( 1, &fbo.id );
glBindFramebuffer( GL_FRAMEBUFFER, fbo.id );
glGenRenderbuffers( 1, &fbo.colorID );
glBindRenderbuffer( GL_RENDERBUFFER, fbo.colorID );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB, width, height );
glGenRenderbuffers( 1, &fbo.depthID );
glBindRenderbuffer( GL_RENDERBUFFER, fbo.depthID );
glRenderbufferStorage( GL_RENDERBUFFER, fbo.depth_format, width, height );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fbo.colorID );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, fbo.depthID );
}
void init()
{
#define GLEW_STATIC 1
glewInit() ;
fbo24.depth_format = GL_DEPTH_COMPONENT24 ;
fbo32.depth_format = GL_DEPTH_COMPONENT16 ;
initFBO( fbo24 );
initFBO( fbo32 );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glClearColor( 0.5, 0.5, 1.0, 0.0 ) ;
glEnable( GL_DEPTH_TEST );
}
void reshape( int w, int h )
{
if( w != width || h != height )
{
width = w ;
height = h;
glViewport( 0, 0, width, height ) ;
initFBO( fbo24 );
initFBO( fbo32 );
}
glMatrixMode( GL_PROJECTION ) ;
glLoadIdentity() ;
gluPerspective( fov, (float)w/h, near_clip, far_clip ) ;
glMatrixMode( GL_MODELVIEW ) ;
glLoadIdentity() ;
gluLookAt( eye[X], eye[Y], eye[Z],
lookat[X], lookat[Y], lookat[Z],
up[X], up[Y], up[Z] ) ;
}
void drawTest()
{
glColor3f( 1.0, 1.0, 1.0 );
glBegin( GL_QUADS );
glVertex3f( -20.0, 0.0, 0.0 );
glVertex3f( 20.0, 0.0, 0.0 );
glVertex3f( 20.0, 1000.0, 0.0 );
glVertex3f( -20.0, 1000.0, 0.0 );
glEnd();
glColor3f( 0.0, 0.0, 0.0 );
glBegin( GL_QUADS );
glVertex3f( -20.0, 0.0, 0.1 );
glVertex3f( 20.0, 0.0, 0.1 );
glVertex3f( 20.0, 1000.0, 0.1 );
glVertex3f( -20.0, 1000.0, 0.1 );
glEnd();
}
void draw()
{
glBindFramebuffer( GL_FRAMEBUFFER, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glBindFramebuffer( GL_FRAMEBUFFER, fbo24.id );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
drawTest();
glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo24.id );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
glBlitFramebuffer( 0, 0, width, height,
0, 0, width/2, height,
GL_COLOR_BUFFER_BIT, GL_NEAREST );
glBindFramebuffer( GL_FRAMEBUFFER, fbo32.id ) ;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
drawTest();
glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo32.id );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
glBlitFramebuffer( 0, 0, width, height,
width/2, 0, width, height,
GL_COLOR_BUFFER_BIT, GL_NEAREST );
glutSwapBuffers();
glutPostRedisplay() ;
}
void key( unsigned char key, int x, int y )
{
static float units = 1.0;
switch( key )
{
case 'q' :
glutDestroyWindow( window ) ;
exit( 0 ) ;
break ;
case 'n' :
near_clip += 0.001*units ;
reshape( width, height );
printf( "Near Clip = %f\n", near_clip );
break ;
case 'N' :
near_clip -= 0.001*units ;
reshape( width, height );
printf( "Near Clip = %f\n", near_clip );
break ;
case 'f' :
far_clip += 10.0*units ;
reshape( width, height );
printf( "Far Clip = %f\n", far_clip );
break ;
case 'F' :
far_clip -= 10.0*units ;
reshape( width, height );
printf( "Far Clip = %f\n", far_clip );
break ;
case 'u' :
units *= 10.0;
break;
case 'U' :
units /= 10.0;
break;
}
reshape( width, height ) ;
}
int main(int argc, char** argv)
{
glutInit( &argc, argv ) ;
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH ) ;
glutInitWindowSize( width, height ) ;
glutInitWindowPosition( 200, 200 ) ;
window = glutCreateWindow( "Depth Test" ) ;
init() ;
glutDisplayFunc( draw ) ;
glutReshapeFunc( reshape ) ;
glutKeyboardFunc( key ) ;
glutMainLoop() ;
return 0;
}