st/mesa: fix glCopyPixels bugs/crashes when src region need clipping
[mesa.git] / progs / fpglsl / fp-tri.c
1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 #ifndef WIN32
7 #include <unistd.h>
8 #include <signal.h>
9 #endif
10
11 #include <GL/glew.h>
12 #include <GL/glut.h>
13
14 #include "readtex.c"
15
16
17 #define TEXTURE_FILE "../images/bw.rgb"
18
19 unsigned show_fps = 0;
20 unsigned int frame_cnt = 0;
21 void alarmhandler(int);
22 static const char *filename = NULL;
23
24 static GLuint fragShader;
25 static GLuint vertShader;
26 static GLuint program;
27
28
29 static void usage(char *name)
30 {
31 fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
32 #ifndef WIN32
33 fprintf(stderr, "\n" );
34 fprintf(stderr, "options:\n");
35 fprintf(stderr, " -fps show frames per second\n");
36 #endif
37 }
38
39 #ifndef WIN32
40 void alarmhandler (int sig)
41 {
42 if (sig == SIGALRM) {
43 printf("%d frames in 5.0 seconds = %.3f FPS\n", frame_cnt,
44 frame_cnt / 5.0);
45
46 frame_cnt = 0;
47 }
48 signal(SIGALRM, alarmhandler);
49 alarm(5);
50 }
51 #endif
52
53
54
55
56 static void load_and_compile_shader(GLuint shader, const char *text)
57 {
58 GLint stat;
59
60 glShaderSource(shader, 1, (const GLchar **) &text, NULL);
61
62 glCompileShader(shader);
63
64 glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
65 if (!stat) {
66 GLchar log[1000];
67 GLsizei len;
68 glGetShaderInfoLog(shader, 1000, &len, log);
69 fprintf(stderr, "fp-tri: problem compiling shader:\n%s\n", log);
70 exit(1);
71 }
72 }
73
74 static void read_shader(GLuint shader, const char *filename)
75 {
76 const int max = 100*1000;
77 int n;
78 char *buffer = (char*) malloc(max);
79 FILE *f = fopen(filename, "r");
80 if (!f) {
81 fprintf(stderr, "fp-tri: Unable to open shader file %s\n", filename);
82 exit(1);
83 }
84
85 n = fread(buffer, 1, max, f);
86 printf("fp-tri: read %d bytes from shader file %s\n", n, filename);
87 if (n > 0) {
88 buffer[n] = 0;
89 load_and_compile_shader(shader, buffer);
90 }
91
92 fclose(f);
93 free(buffer);
94 }
95
96 static void check_link(GLuint prog)
97 {
98 GLint stat;
99 glGetProgramiv(prog, GL_LINK_STATUS, &stat);
100 if (!stat) {
101 GLchar log[1000];
102 GLsizei len;
103 glGetProgramInfoLog(prog, 1000, &len, log);
104 fprintf(stderr, "Linker error:\n%s\n", log);
105 }
106 }
107
108 static void setup_uniforms()
109 {
110 {
111 GLint loc1f = glGetUniformLocationARB(program, "Offset1f");
112 GLint loc2f = glGetUniformLocationARB(program, "Offset2f");
113 GLint loc4f = glGetUniformLocationARB(program, "Offset4f");
114 GLfloat vecKer[] =
115 { 1.0, 0.0, 0.0, 1.0,
116 0.0, 1.0, 0.0, 1.0,
117 1.0, 0.0, 0.0, 1.0,
118 0.0, 0.0, 0.0, 1.0
119 };
120 if (loc1f >= 0)
121 glUniform1fv(loc1f, 16, vecKer);
122
123 if (loc2f >= 0)
124 glUniform2fv(loc2f, 8, vecKer);
125
126 if (loc4f >= 0)
127 glUniform4fv(loc4f, 4, vecKer);
128
129 }
130
131 {
132 GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
133 GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
134 GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
135 GLfloat vecKer[] =
136 { 1.0, 0.0, 0.0, 0.25,
137 0.0, 1.0, 0.0, 0.25,
138 0.0, 0.0, 1.0, 0.25,
139 0.0, 0.0, 0.0, 0.25,
140 0.5, 0.0, 0.0, 0.35,
141 0.0, 0.5, 0.0, 0.35,
142 0.0, 0.0, 0.5, 0.35,
143 0.0, 0.0, 0.0, 0.35
144 };
145 if (loc1f >= 0)
146 glUniform1fv(loc1f, 16, vecKer);
147
148 if (loc2f >= 0)
149 glUniform2fv(loc2f, 8, vecKer);
150
151 if (loc4f >= 0)
152 glUniform4fv(loc4f, 4, vecKer);
153 }
154 }
155
156 static void prepare_shaders()
157 {
158 static const char *fragShaderText =
159 "void main() {\n"
160 " gl_FragColor = gl_Color;\n"
161 "}\n";
162 static const char *vertShaderText =
163 "void main() {\n"
164 " gl_FrontColor = gl_Color;\n"
165 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
166 "}\n";
167 fragShader = glCreateShader(GL_FRAGMENT_SHADER);
168 if (filename)
169 read_shader(fragShader, filename);
170 else
171 load_and_compile_shader(fragShader, fragShaderText);
172
173
174 vertShader = glCreateShader(GL_VERTEX_SHADER);
175 load_and_compile_shader(vertShader, vertShaderText);
176
177 program = glCreateProgram();
178 glAttachShader(program, fragShader);
179 glAttachShader(program, vertShader);
180 glLinkProgram(program);
181 check_link(program);
182 glUseProgram(program);
183
184 setup_uniforms();
185 }
186
187 #define LEVELS 8
188 #define SIZE (1<<LEVELS)
189 static int TexWidth = SIZE, TexHeight = SIZE;
190
191
192 static void
193 ResetTextureLevel( int i )
194 {
195 GLubyte tex2d[SIZE*SIZE][4];
196
197 {
198 GLint Width = TexWidth / (1 << i);
199 GLint Height = TexHeight / (1 << i);
200 GLint s, t;
201
202 for (s = 0; s < Width; s++) {
203 for (t = 0; t < Height; t++) {
204 tex2d[t*Width+s][0] = ((s / 16) % 2) ? 0 : 255;
205 tex2d[t*Width+s][1] = ((t / 16) % 2) ? 0 : 255;
206 tex2d[t*Width+s][2] = 128;
207 tex2d[t*Width+s][3] = 255;
208 }
209 }
210
211 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
212
213 glTexImage2D(GL_TEXTURE_2D, i, GL_RGB, Width, Height, 0,
214 GL_RGBA, GL_UNSIGNED_BYTE, tex2d);
215 }
216 }
217
218
219 static void
220 ResetTexture( void )
221 {
222 int i;
223
224 for (i = 0; i <= LEVELS; i++)
225 {
226 ResetTextureLevel(i);
227 }
228 }
229
230 static void Init( void )
231 {
232 GLuint Texture;
233
234 /* Load texture */
235 glGenTextures(1, &Texture);
236 glBindTexture(GL_TEXTURE_2D, Texture);
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
239 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
240 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
241 printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
242 exit(1);
243 }
244
245
246 glGenTextures(1, &Texture);
247 glActiveTextureARB(GL_TEXTURE0_ARB + 1);
248 glBindTexture(GL_TEXTURE_2D, Texture);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
251 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
252
253 {
254 GLubyte data[32][32];
255 int width = 32;
256 int height = 32;
257 int i;
258 int j;
259
260 for (i = 0; i < 32; i++)
261 for (j = 0; j < 32; j++)
262 {
263 /**
264 ** +-----------+
265 ** | W |
266 ** | +-----+ |
267 ** | | | |
268 ** | | B | |
269 ** | | | |
270 ** | +-----+ |
271 ** | |
272 ** +-----------+
273 **/
274 int i2 = i - height / 2;
275 int j2 = j - width / 2;
276 int h8 = height / 8;
277 int w8 = width / 8;
278 if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) {
279 data[i][j] = 0x00;
280 } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) {
281 data[i][j] = 0x55;
282 } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) {
283 data[i][j] = 0xaa;
284 } else {
285 data[i][j] = 0xff;
286 }
287 }
288
289 glTexImage2D( GL_TEXTURE_2D, 0,
290 GL_ALPHA8,
291 32, 32, 0,
292 GL_ALPHA, GL_UNSIGNED_BYTE, data );
293 }
294
295 glGenTextures(1, &Texture);
296 glActiveTextureARB(GL_TEXTURE0_ARB + 2);
297 glBindTexture(GL_TEXTURE_2D, Texture);
298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
300 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
301 ResetTexture();
302
303 glClearColor(.1, .3, .5, 0);
304 }
305
306
307
308
309 static void args(int argc, char *argv[])
310 {
311 GLint i;
312
313 for (i = 1; i < argc; i++) {
314 if (strcmp(argv[i], "-fps") == 0) {
315 show_fps = 1;
316 }
317 else if (i == argc - 1) {
318 filename = argv[i];
319 }
320 else {
321 usage(argv[0]);
322 exit(1);
323 }
324 }
325 }
326
327
328
329
330
331 static void Reshape(int width, int height)
332 {
333
334 glViewport(0, 0, (GLint)width, (GLint)height);
335
336 glMatrixMode(GL_PROJECTION);
337 glLoadIdentity();
338 glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
339 glMatrixMode(GL_MODELVIEW);
340 }
341
342 static void CleanUp(void)
343 {
344 glDeleteShader(fragShader);
345 glDeleteShader(vertShader);
346 glDeleteProgram(program);
347 }
348
349 static void Key(unsigned char key, int x, int y)
350 {
351
352 switch (key) {
353 case 27:
354 CleanUp();
355 exit(1);
356 default:
357 break;
358 }
359
360 glutPostRedisplay();
361 }
362
363 static void Display(void)
364 {
365 glClear(GL_COLOR_BUFFER_BIT);
366
367 glUseProgram(program);
368 glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 1.0, 1.0, 0.0, 0.0);
369 glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0.0, 0.0, 1.0, 1.0);
370 glBegin(GL_TRIANGLES);
371
372 glColor3f(0,0,1);
373 glTexCoord3f(1,1,0);
374 glVertex3f( 0.9, -0.9, -30.0);
375
376 glColor3f(1,0,0);
377 glTexCoord3f(1,-1,0);
378 glVertex3f( 0.9, 0.9, -30.0);
379
380 glColor3f(0,1,0);
381 glTexCoord3f(-1,0,0);
382 glVertex3f(-0.9, 0.0, -30.0);
383 glEnd();
384
385 glFlush();
386 if (show_fps) {
387 ++frame_cnt;
388 glutPostRedisplay();
389 }
390 }
391
392
393 int main(int argc, char **argv)
394 {
395 glutInit(&argc, argv);
396 glutInitWindowPosition(0, 0);
397 glutInitWindowSize(250, 250);
398 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
399 args(argc, argv);
400 glutCreateWindow(filename ? filename : "fp-tri");
401 glewInit();
402 glutReshapeFunc(Reshape);
403 glutKeyboardFunc(Key);
404 glutDisplayFunc(Display);
405 prepare_shaders();
406 Init();
407 #ifndef WIN32
408 if (show_fps) {
409 signal(SIGALRM, alarmhandler);
410 alarm(5);
411 }
412 #endif
413 glutMainLoop();
414 return 0;
415 }