132001f49Smrg/* Framebuffer object test */
232001f49Smrg
332001f49Smrg
432001f49Smrg#include <GL/glew.h>
532001f49Smrg#include "glut_wrap.h"
632001f49Smrg#include <assert.h>
732001f49Smrg#include <stdio.h>
832001f49Smrg#include <stdlib.h>
932001f49Smrg
1032001f49Smrg/* For debug */
1132001f49Smrg
1232001f49Smrg
1332001f49Smrgstatic int Win = 0;
1432001f49Smrgstatic int Width = 512, Height = 512;
1532001f49Smrg
1632001f49Smrgstatic GLenum TexTarget = GL_TEXTURE_2D;
1732001f49Smrgstatic int TexWidth = 512, TexHeight = 512;
1832001f49Smrg
1932001f49Smrgstatic GLuint MyFB;
2032001f49Smrgstatic GLuint TexObj;
2132001f49Smrgstatic GLboolean Anim = GL_FALSE;
2232001f49Smrgstatic GLfloat Rot = 0.0;
2332001f49Smrgstatic GLuint TextureLevel = 4;  /* which texture level to render to */
2432001f49Smrgstatic GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
2532001f49Smrg
2632001f49Smrg
2732001f49Smrgstatic void
2832001f49SmrgCheckError(int line)
2932001f49Smrg{
3032001f49Smrg   GLenum err = glGetError();
3132001f49Smrg   if (err) {
3232001f49Smrg      printf("GL Error 0x%x at line %d\n", (int) err, line);
3332001f49Smrg   }
3432001f49Smrg}
3532001f49Smrg
3632001f49Smrg
3732001f49Smrgstatic void
3832001f49SmrgIdle(void)
3932001f49Smrg{
4032001f49Smrg   Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
4132001f49Smrg   glutPostRedisplay();
4232001f49Smrg}
4332001f49Smrg
4432001f49Smrg
4532001f49Smrgstatic void
4632001f49SmrgRenderTexture(void)
4732001f49Smrg{
4832001f49Smrg   GLenum status;
4932001f49Smrg
5032001f49Smrg   glMatrixMode(GL_PROJECTION);
5132001f49Smrg   glLoadIdentity();
5232001f49Smrg   glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
5332001f49Smrg   glMatrixMode(GL_MODELVIEW);
5432001f49Smrg   glLoadIdentity();
5532001f49Smrg   glTranslatef(0.0, 0.0, -15.0);
5632001f49Smrg
5732001f49Smrg   if (1) {
5832001f49Smrg      /* draw to texture image */
5932001f49Smrg      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
6032001f49Smrg
6132001f49Smrg      status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
6232001f49Smrg      if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
6332001f49Smrg         printf("Framebuffer incomplete!!!\n");
6432001f49Smrg      }
6532001f49Smrg
6632001f49Smrg      glViewport(0, 0,
6732001f49Smrg                 TexWidth / (1 << TextureLevel),
6832001f49Smrg                 TexHeight / (1 << TextureLevel));
6932001f49Smrg      glClearColor(0.5, 0.5, 1.0, 0.0);
7032001f49Smrg      glClear(GL_COLOR_BUFFER_BIT);
7132001f49Smrg
7232001f49Smrg      CheckError(__LINE__);
7332001f49Smrg
7432001f49Smrg      glBegin(GL_POLYGON);
7532001f49Smrg      glColor3f(1, 0, 0);
7632001f49Smrg      glVertex2f(-1, -1);
7732001f49Smrg      glColor3f(0, 1, 0);
7832001f49Smrg      glVertex2f(1, -1);
7932001f49Smrg      glColor3f(0, 0, 1);
8032001f49Smrg      glVertex2f(0, 1);
8132001f49Smrg      glEnd();
8232001f49Smrg
8332001f49Smrg      /* Bind normal framebuffer */
8432001f49Smrg      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
8532001f49Smrg   }
8632001f49Smrg   else {
8732001f49Smrg   }
8832001f49Smrg
8932001f49Smrg   CheckError(__LINE__);
9032001f49Smrg}
9132001f49Smrg
9232001f49Smrg
9332001f49Smrg
9432001f49Smrgstatic void
9532001f49SmrgDisplay(void)
9632001f49Smrg{
9732001f49Smrg   float ar = (float) Width / (float) Height;
9832001f49Smrg
9932001f49Smrg   RenderTexture();
10032001f49Smrg
10132001f49Smrg   /* draw textured quad in the window */
10232001f49Smrg   glMatrixMode(GL_PROJECTION);
10332001f49Smrg   glLoadIdentity();
10432001f49Smrg   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
10532001f49Smrg   glMatrixMode(GL_MODELVIEW);
10632001f49Smrg   glLoadIdentity();
10732001f49Smrg   glTranslatef(0.0, 0.0, -7.0);
10832001f49Smrg
10932001f49Smrg   glViewport(0, 0, Width, Height);
11032001f49Smrg
11132001f49Smrg   glClearColor(0.25, 0.25, 0.25, 0);
11232001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
11332001f49Smrg
11432001f49Smrg   glPushMatrix();
11532001f49Smrg   glRotatef(Rot, 0, 1, 0);
11632001f49Smrg   glEnable(TexTarget);
11732001f49Smrg   glBindTexture(TexTarget, TexObj);
11832001f49Smrg
11932001f49Smrg   {
12032001f49Smrg      glBegin(GL_POLYGON);
12132001f49Smrg      glColor3f(0.25, 0.25, 0.25);
12232001f49Smrg      glTexCoord2f(0, 0);
12332001f49Smrg      glVertex2f(-1, -1);
12432001f49Smrg      glTexCoord2f(1, 0);
12532001f49Smrg      glVertex2f(1, -1);
12632001f49Smrg      glColor3f(1.0, 1.0, 1.0);
12732001f49Smrg      glTexCoord2f(1, 1);
12832001f49Smrg      glVertex2f(1, 1);
12932001f49Smrg      glTexCoord2f(0, 1);
13032001f49Smrg      glVertex2f(-1, 1);
13132001f49Smrg      glEnd();
13232001f49Smrg   }
13332001f49Smrg
13432001f49Smrg   glPopMatrix();
13532001f49Smrg   glDisable(TexTarget);
13632001f49Smrg
13732001f49Smrg   glutSwapBuffers();
13832001f49Smrg   CheckError(__LINE__);
13932001f49Smrg}
14032001f49Smrg
14132001f49Smrg
14232001f49Smrgstatic void
14332001f49SmrgReshape(int width, int height)
14432001f49Smrg{
14532001f49Smrg   glViewport(0, 0, width, height);
14632001f49Smrg   Width = width;
14732001f49Smrg   Height = height;
14832001f49Smrg}
14932001f49Smrg
15032001f49Smrg
15132001f49Smrgstatic void
15232001f49SmrgCleanUp(void)
15332001f49Smrg{
15432001f49Smrg   glDeleteFramebuffersEXT(1, &MyFB);
15532001f49Smrg
15632001f49Smrg   glDeleteTextures(1, &TexObj);
15732001f49Smrg
15832001f49Smrg   glutDestroyWindow(Win);
15932001f49Smrg
16032001f49Smrg   exit(0);
16132001f49Smrg}
16232001f49Smrg
16332001f49Smrg
16432001f49Smrgstatic void
16532001f49SmrgKey(unsigned char key, int x, int y)
16632001f49Smrg{
16732001f49Smrg   (void) x;
16832001f49Smrg   (void) y;
16932001f49Smrg   switch (key) {
17032001f49Smrg      case 'a':
17132001f49Smrg         Anim = !Anim;
17232001f49Smrg         if (Anim)
17332001f49Smrg            glutIdleFunc(Idle);
17432001f49Smrg         else
17532001f49Smrg            glutIdleFunc(NULL);
17632001f49Smrg         break;
17732001f49Smrg      case 's':
17832001f49Smrg         Rot += 2.0;
17932001f49Smrg         break;
18032001f49Smrg      case 27:
18132001f49Smrg         CleanUp();
18232001f49Smrg         break;
18332001f49Smrg   }
18432001f49Smrg   glutPostRedisplay();
18532001f49Smrg}
18632001f49Smrg
18732001f49Smrg
18832001f49Smrgstatic void
18932001f49SmrgInit(int argc, char *argv[])
19032001f49Smrg{
19132001f49Smrg   if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
19232001f49Smrg      printf("GL_EXT_framebuffer_object not found!\n");
19332001f49Smrg      exit(0);
19432001f49Smrg   }
19532001f49Smrg
19632001f49Smrg   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
19732001f49Smrg
19832001f49Smrg
19932001f49Smrg   /* Make texture object/image */
20032001f49Smrg   glGenTextures(1, &TexObj);
20132001f49Smrg   glBindTexture(TexTarget, TexObj);
20232001f49Smrg   glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
20332001f49Smrg   glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
20432001f49Smrg   glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
20532001f49Smrg   glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
20632001f49Smrg
20732001f49Smrg   glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
20832001f49Smrg                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
20932001f49Smrg   glTexImage2D(TexTarget, TextureLevel, TexIntFormat,
21032001f49Smrg                TexWidth / (1 << TextureLevel), TexHeight / (1 << TextureLevel), 0,
21132001f49Smrg                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
21232001f49Smrg
21332001f49Smrg
21432001f49Smrg   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
21532001f49Smrg
21632001f49Smrg
21732001f49Smrg
21832001f49Smrg
21932001f49Smrg   /* gen framebuffer id, delete it, do some assertions, just for testing */
22032001f49Smrg   glGenFramebuffersEXT(1, &MyFB);
22132001f49Smrg   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
22232001f49Smrg   assert(glIsFramebufferEXT(MyFB));
22332001f49Smrg
22432001f49Smrg
22532001f49Smrg   CheckError(__LINE__);
22632001f49Smrg
22732001f49Smrg   /* Render color to texture */
22832001f49Smrg   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
22932001f49Smrg                             TexTarget, TexObj, TextureLevel);
23032001f49Smrg
23132001f49Smrg
23232001f49Smrg
23332001f49Smrg   CheckError(__LINE__);
23432001f49Smrg
23532001f49Smrg   /* bind regular framebuffer */
23632001f49Smrg   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
23732001f49Smrg
23832001f49Smrg
23932001f49Smrg}
24032001f49Smrg
24132001f49Smrg
24232001f49Smrgint
24332001f49Smrgmain(int argc, char *argv[])
24432001f49Smrg{
24532001f49Smrg   glutInit(&argc, argv);
24632001f49Smrg   glutInitWindowPosition(0, 0);
24732001f49Smrg   glutInitWindowSize(Width, Height);
24832001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
24932001f49Smrg   Win = glutCreateWindow(argv[0]);
25032001f49Smrg   glewInit();
25132001f49Smrg   glutReshapeFunc(Reshape);
25232001f49Smrg   glutKeyboardFunc(Key);
25332001f49Smrg   glutDisplayFunc(Display);
25432001f49Smrg   if (Anim)
25532001f49Smrg      glutIdleFunc(Idle);
25632001f49Smrg   Init(argc, argv);
25732001f49Smrg   glutMainLoop();
25832001f49Smrg   return 0;
25932001f49Smrg}
260