1/* Framebuffer object test */
2
3
4#include <GL/glew.h>
5#include "glut_wrap.h"
6#include <assert.h>
7#include <stdio.h>
8#include <stdlib.h>
9
10/* For debug */
11
12
13static int Win = 0;
14static int Width = 512, Height = 512;
15
16static GLenum TexTarget = GL_TEXTURE_2D;
17static int TexWidth = 512, TexHeight = 512;
18
19static GLuint MyFB;
20static GLuint TexObj;
21static GLboolean Anim = GL_FALSE;
22static GLfloat Rot = 0.0;
23static GLuint TextureLevel = 4;  /* which texture level to render to */
24static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
25
26
27static void
28CheckError(int line)
29{
30   GLenum err = glGetError();
31   if (err) {
32      printf("GL Error 0x%x at line %d\n", (int) err, line);
33   }
34}
35
36
37static void
38Idle(void)
39{
40   Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
41   glutPostRedisplay();
42}
43
44
45static void
46RenderTexture(void)
47{
48   GLenum status;
49
50   glMatrixMode(GL_PROJECTION);
51   glLoadIdentity();
52   glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
53   glMatrixMode(GL_MODELVIEW);
54   glLoadIdentity();
55   glTranslatef(0.0, 0.0, -15.0);
56
57   if (1) {
58      /* draw to texture image */
59      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
60
61      status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
62      if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
63         printf("Framebuffer incomplete!!!\n");
64      }
65
66      glViewport(0, 0,
67                 TexWidth / (1 << TextureLevel),
68                 TexHeight / (1 << TextureLevel));
69      glClearColor(0.5, 0.5, 1.0, 0.0);
70      glClear(GL_COLOR_BUFFER_BIT);
71
72      CheckError(__LINE__);
73
74      glBegin(GL_POLYGON);
75      glColor3f(1, 0, 0);
76      glVertex2f(-1, -1);
77      glColor3f(0, 1, 0);
78      glVertex2f(1, -1);
79      glColor3f(0, 0, 1);
80      glVertex2f(0, 1);
81      glEnd();
82
83      /* Bind normal framebuffer */
84      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
85   }
86   else {
87   }
88
89   CheckError(__LINE__);
90}
91
92
93
94static void
95Display(void)
96{
97   float ar = (float) Width / (float) Height;
98
99   RenderTexture();
100
101   /* draw textured quad in the window */
102   glMatrixMode(GL_PROJECTION);
103   glLoadIdentity();
104   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
105   glMatrixMode(GL_MODELVIEW);
106   glLoadIdentity();
107   glTranslatef(0.0, 0.0, -7.0);
108
109   glViewport(0, 0, Width, Height);
110
111   glClearColor(0.25, 0.25, 0.25, 0);
112   glClear(GL_COLOR_BUFFER_BIT);
113
114   glPushMatrix();
115   glRotatef(Rot, 0, 1, 0);
116   glEnable(TexTarget);
117   glBindTexture(TexTarget, TexObj);
118
119   {
120      glBegin(GL_POLYGON);
121      glColor3f(0.25, 0.25, 0.25);
122      glTexCoord2f(0, 0);
123      glVertex2f(-1, -1);
124      glTexCoord2f(1, 0);
125      glVertex2f(1, -1);
126      glColor3f(1.0, 1.0, 1.0);
127      glTexCoord2f(1, 1);
128      glVertex2f(1, 1);
129      glTexCoord2f(0, 1);
130      glVertex2f(-1, 1);
131      glEnd();
132   }
133
134   glPopMatrix();
135   glDisable(TexTarget);
136
137   glutSwapBuffers();
138   CheckError(__LINE__);
139}
140
141
142static void
143Reshape(int width, int height)
144{
145   glViewport(0, 0, width, height);
146   Width = width;
147   Height = height;
148}
149
150
151static void
152CleanUp(void)
153{
154   glDeleteFramebuffersEXT(1, &MyFB);
155
156   glDeleteTextures(1, &TexObj);
157
158   glutDestroyWindow(Win);
159
160   exit(0);
161}
162
163
164static void
165Key(unsigned char key, int x, int y)
166{
167   (void) x;
168   (void) y;
169   switch (key) {
170      case 'a':
171         Anim = !Anim;
172         if (Anim)
173            glutIdleFunc(Idle);
174         else
175            glutIdleFunc(NULL);
176         break;
177      case 's':
178         Rot += 2.0;
179         break;
180      case 27:
181         CleanUp();
182         break;
183   }
184   glutPostRedisplay();
185}
186
187
188static void
189Init(int argc, char *argv[])
190{
191   if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
192      printf("GL_EXT_framebuffer_object not found!\n");
193      exit(0);
194   }
195
196   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
197
198
199   /* Make texture object/image */
200   glGenTextures(1, &TexObj);
201   glBindTexture(TexTarget, TexObj);
202   glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
203   glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
204   glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
205   glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
206
207   glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
208                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
209   glTexImage2D(TexTarget, TextureLevel, TexIntFormat,
210                TexWidth / (1 << TextureLevel), TexHeight / (1 << TextureLevel), 0,
211                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
212
213
214   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
215
216
217
218
219   /* gen framebuffer id, delete it, do some assertions, just for testing */
220   glGenFramebuffersEXT(1, &MyFB);
221   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
222   assert(glIsFramebufferEXT(MyFB));
223
224
225   CheckError(__LINE__);
226
227   /* Render color to texture */
228   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
229                             TexTarget, TexObj, TextureLevel);
230
231
232
233   CheckError(__LINE__);
234
235   /* bind regular framebuffer */
236   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
237
238
239}
240
241
242int
243main(int argc, char *argv[])
244{
245   glutInit(&argc, argv);
246   glutInitWindowPosition(0, 0);
247   glutInitWindowSize(Width, Height);
248   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
249   Win = glutCreateWindow(argv[0]);
250   glewInit();
251   glutReshapeFunc(Reshape);
252   glutKeyboardFunc(Key);
253   glutDisplayFunc(Display);
254   if (Anim)
255      glutIdleFunc(Idle);
256   Init(argc, argv);
257   glutMainLoop();
258   return 0;
259}
260