Merge branch '7.8' into master
[mesa.git] / progs / trivial / clear-fbo-scissor.c
1 /*
2 * Use scissor to clear the four quadrants of the FBO to different
3 * colors. Then draw a grey triangle in the middle.
4 */
5
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <string.h>
12 #include <GL/glew.h>
13 #include <GL/glut.h>
14 #include <GL/glu.h>
15
16
17 static int Width = 512, Height = 512;
18 static GLuint MyFB, MyRB;
19 static GLboolean UseTex = GL_FALSE;
20 static GLboolean UseCopyPix = GL_FALSE;
21
22
23 #define CheckError() \
24 do { \
25 GLenum err = glGetError(); \
26 if (err != GL_NO_ERROR) \
27 printf("Error: %s\n", gluErrorString(err)); \
28 assert(err == GL_NO_ERROR); \
29 } while (0)
30
31
32 static void
33 Init(void)
34 {
35 GLenum status;
36
37 fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
38 fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
39 fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
40 fflush(stderr);
41
42 if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
43 printf("GL_EXT_framebuffer_object not found!\n");
44 exit(0);
45 }
46
47 glGenFramebuffersEXT(1, &MyFB);
48 glGenRenderbuffersEXT(1, &MyRB);
49
50 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
51
52 if (UseTex) {
53 GLuint tex;
54 glGenTextures(1, &tex);
55 glBindTexture(GL_TEXTURE_2D, tex);
56 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0,
57 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
59 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
60 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
61 GL_COLOR_ATTACHMENT0_EXT,
62 GL_TEXTURE_2D, tex, 0);
63 }
64 else {
65 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRB);
66
67 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
68 GL_COLOR_ATTACHMENT0_EXT,
69 GL_RENDERBUFFER_EXT, MyRB);
70
71 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
72 }
73
74 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
75 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
76 fprintf(stderr, "Framebuffer object is incomplete (0x%x)!\n", status);
77 }
78
79 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
80 }
81
82
83 static void
84 Reshape(int width, int height)
85 {
86 glViewport(0, 0, width, height);
87 glMatrixMode(GL_PROJECTION);
88 glLoadIdentity();
89 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
90 glMatrixMode(GL_MODELVIEW);
91
92 Width = width;
93 Height = height;
94 if (!UseTex) {
95 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
96 }
97 }
98
99
100 static void
101 Key(unsigned char key, int x, int y)
102 {
103 if (key == 27) {
104 exit(0);
105 }
106 glutPostRedisplay();
107 }
108
109
110 static void
111 Draw(void)
112 {
113 GLboolean scissor = GL_TRUE;
114
115 /* draw to user framebuffer */
116 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
117 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
118 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
119
120 glViewport(0, 0, Width, Height);
121 CheckError();
122
123 if (scissor) {
124 glEnable(GL_SCISSOR_TEST);
125
126 /* lower-left = red */
127 glClearColor(1, 0, 0, 0);
128 glScissor(0, 0, Width / 2, Height / 2);
129 glClear(GL_COLOR_BUFFER_BIT);
130
131 /* lower-right = green */
132 glClearColor(0, 1, 0, 0);
133 glScissor(Width / 2, 0, Width - Width / 2, Height / 2);
134 glClear(GL_COLOR_BUFFER_BIT);
135
136 /* upper-left = blue */
137 glClearColor(0, 0, 1, 0);
138 glScissor(0, Height / 2, Width / 2, Height - Height / 2);
139 glClear(GL_COLOR_BUFFER_BIT);
140
141 /* upper-right = white */
142 glClearColor(1, 1, 1, 0);
143 glScissor(Width / 2, Height / 2, Width - Width / 2, Height - Height / 2);
144 glClear(GL_COLOR_BUFFER_BIT);
145
146 glDisable(GL_SCISSOR_TEST);
147 }
148 else {
149 glClearColor(0, 1, 0, 0);
150 glClear(GL_COLOR_BUFFER_BIT);
151 }
152
153 CheckError();
154
155 /* gray triangle in middle, pointing up */
156 glColor3f(0.5, 0.5, 0.5);
157 glBegin(GL_TRIANGLES);
158 glVertex2f(Width/4, Height/4);
159 glVertex2f(Width*3/4, Height/4);
160 glVertex2f(Width/2, Height*3/4);
161 glVertex2f(-0.5, -0.5);
162 glVertex2f(+0.5, -0.5);
163 glVertex2f( 0.0, 0.7);
164 glEnd();
165
166 CheckError();
167
168 /* copy fbo to window */
169 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, MyFB);
170 glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
171 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
172 glDrawBuffer(GL_BACK);
173
174 if (UseCopyPix) {
175 glWindowPos2i(0, 0);
176 glCopyPixels(0, 0, Width, Height, GL_COLOR);
177 }
178 else {
179 GLubyte *buffer = malloc(Width * Height * 4);
180
181 /* read from user framebuffer */
182 glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
183
184 /* draw to window */
185 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
186 glWindowPos2iARB(0, 0);
187 glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
188
189 free(buffer);
190 }
191
192 /* Bind normal framebuffer */
193 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
194
195 glutSwapBuffers();
196
197 CheckError();
198 }
199
200
201 int
202 main(int argc, char *argv[])
203 {
204 int i;
205
206 glutInit(&argc, argv);
207 glutInitWindowPosition(100, 0);
208 glutInitWindowSize(Width, Height);
209 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
210
211 for (i = 1; i < argc; i++) {
212 if (strcmp(argv[i], "-t") == 0)
213 UseTex = GL_TRUE;
214 else if (strcmp(argv[i], "-c") == 0)
215 UseCopyPix = GL_TRUE;
216 }
217
218 if (UseTex)
219 printf("Using render to texture\n");
220 else
221 printf("Using user-created render buffer\n");
222
223 if (!glutCreateWindow(argv[0])) {
224 exit(1);
225 }
226
227 glewInit();
228 Init();
229 glutReshapeFunc(Reshape);
230 glutKeyboardFunc(Key);
231 glutDisplayFunc(Draw);
232 glutMainLoop();
233 return 0;
234 }