fp-tri.c revision 32001f49
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 "glut_wrap.h" 13 14#include "readtex.c" 15 16 17#define TEXTURE_FILE DEMOS_DATA_DIR "bw.rgb" 18 19unsigned show_fps = 0; 20unsigned int frame_cnt = 0; 21void alarmhandler(int); 22static const char *filename = NULL; 23 24static GLuint fragShader; 25static GLuint vertShader; 26static GLuint program; 27 28 29static 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 40void 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 56static 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 74static 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 96static 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 108static void setup_uniforms(void) 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 loci = glGetUniformLocationARB(program, "KernelSizeInt"); 133 if (loci >= 0) 134 glUniform1i(loci, 4); 135 } 136 { 137 GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f"); 138 GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f"); 139 GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f"); 140 GLfloat vecKer[] = 141 { 1.0, 0.0, 0.0, 0.25, 142 0.0, 1.0, 0.0, 0.25, 143 0.0, 0.0, 1.0, 0.25, 144 0.0, 0.0, 0.0, 0.25, 145 0.5, 0.0, 0.0, 0.35, 146 0.0, 0.5, 0.0, 0.35, 147 0.0, 0.0, 0.5, 0.35, 148 0.0, 0.0, 0.0, 0.35 149 }; 150 if (loc1f >= 0) 151 glUniform1fv(loc1f, 16, vecKer); 152 153 if (loc2f >= 0) 154 glUniform2fv(loc2f, 8, vecKer); 155 156 if (loc4f >= 0) 157 glUniform4fv(loc4f, 4, vecKer); 158 } 159 160 { 161 GLint tex1 = glGetUniformLocationARB(program, "tex1"); 162 GLint tex2 = glGetUniformLocationARB(program, "tex2"); 163 if (tex1 >= 0) 164 glUniform1i(tex1, 0); 165 if (tex2 >= 0) 166 glUniform1i(tex2, 1); 167 } 168} 169 170static void prepare_shaders(void) 171{ 172 static const char *fragShaderText = 173 "void main() {\n" 174 " gl_FragColor = gl_Color;\n" 175 "}\n"; 176 static const char *vertShaderText = 177 "void main() {\n" 178 " gl_FrontColor = gl_Color;\n" 179 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" 180 "}\n"; 181 fragShader = glCreateShader(GL_FRAGMENT_SHADER); 182 if (filename) 183 read_shader(fragShader, filename); 184 else 185 load_and_compile_shader(fragShader, fragShaderText); 186 187 188 vertShader = glCreateShader(GL_VERTEX_SHADER); 189 load_and_compile_shader(vertShader, vertShaderText); 190 191 program = glCreateProgram(); 192 glAttachShader(program, fragShader); 193 glAttachShader(program, vertShader); 194 glLinkProgram(program); 195 check_link(program); 196 glUseProgram(program); 197 198 setup_uniforms(); 199} 200 201#define LEVELS 8 202#define SIZE (1<<LEVELS) 203static int TexWidth = SIZE, TexHeight = SIZE; 204 205 206static void 207ResetTextureLevel( int i ) 208{ 209 GLubyte tex2d[SIZE*SIZE][4]; 210 211 { 212 GLint Width = TexWidth / (1 << i); 213 GLint Height = TexHeight / (1 << i); 214 GLint s, t; 215 216 for (s = 0; s < Width; s++) { 217 for (t = 0; t < Height; t++) { 218 tex2d[t*Width+s][0] = ((s / 16) % 2) ? 0 : 255; 219 tex2d[t*Width+s][1] = ((t / 16) % 2) ? 0 : 255; 220 tex2d[t*Width+s][2] = 128; 221 tex2d[t*Width+s][3] = 255; 222 } 223 } 224 225 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 226 227 glTexImage2D(GL_TEXTURE_2D, i, GL_RGB, Width, Height, 0, 228 GL_RGBA, GL_UNSIGNED_BYTE, tex2d); 229 } 230} 231 232 233static void 234ResetTexture( void ) 235{ 236 int i; 237 238 for (i = 0; i <= LEVELS; i++) 239 { 240 ResetTextureLevel(i); 241 } 242} 243 244static void Init( void ) 245{ 246 GLuint Texture; 247 248 /* Setup texture unit 0 */ 249 glGenTextures(1, &Texture); 250 glBindTexture(GL_TEXTURE_2D, Texture); 251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 253 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 254 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { 255 printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE); 256 exit(1); 257 } 258 259 /* Setup texture unit 1 */ 260 glGenTextures(1, &Texture); 261 glActiveTextureARB(GL_TEXTURE0_ARB + 1); 262 glBindTexture(GL_TEXTURE_2D, Texture); 263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 265 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 266 267 { 268 GLubyte data[32][32]; 269 int width = 32; 270 int height = 32; 271 int i; 272 int j; 273 274 for (i = 0; i < 32; i++) 275 for (j = 0; j < 32; j++) 276 { 277 /** 278 ** +-----------+ 279 ** | W | 280 ** | +-----+ | 281 ** | | | | 282 ** | | B | | 283 ** | | | | 284 ** | +-----+ | 285 ** | | 286 ** +-----------+ 287 **/ 288 int i2 = i - height / 2; 289 int j2 = j - width / 2; 290 int h8 = height / 8; 291 int w8 = width / 8; 292 if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) { 293 data[i][j] = 0x00; 294 } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) { 295 data[i][j] = 0x55; 296 } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) { 297 data[i][j] = 0xaa; 298 } else { 299 data[i][j] = 0xff; 300 } 301 } 302 303 glTexImage2D( GL_TEXTURE_2D, 0, 304 GL_ALPHA8, 305 32, 32, 0, 306 GL_ALPHA, GL_UNSIGNED_BYTE, data ); 307 } 308 309 /* Setup texture unit 2 */ 310 glGenTextures(1, &Texture); 311 glActiveTextureARB(GL_TEXTURE0_ARB + 2); 312 glBindTexture(GL_TEXTURE_2D, Texture); 313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 315 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 316 ResetTexture(); 317 318 glClearColor(.1, .3, .5, 0); 319} 320 321 322 323 324static void args(int argc, char *argv[]) 325{ 326 GLint i; 327 328 for (i = 1; i < argc; i++) { 329 if (strcmp(argv[i], "-fps") == 0) { 330 show_fps = 1; 331 } 332 else if (i == argc - 1) { 333 filename = argv[i]; 334 } 335 else { 336 usage(argv[0]); 337 exit(1); 338 } 339 } 340} 341 342 343 344 345 346static void Reshape(int width, int height) 347{ 348 349 glViewport(0, 0, (GLint)width, (GLint)height); 350 351 glMatrixMode(GL_PROJECTION); 352 glLoadIdentity(); 353 glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); 354 glMatrixMode(GL_MODELVIEW); 355} 356 357static void CleanUp(void) 358{ 359 glDeleteShader(fragShader); 360 glDeleteShader(vertShader); 361 glDeleteProgram(program); 362} 363 364static void Key(unsigned char key, int x, int y) 365{ 366 367 switch (key) { 368 case 27: 369 CleanUp(); 370 exit(1); 371 default: 372 break; 373 } 374 375 glutPostRedisplay(); 376} 377 378static void Display(void) 379{ 380 glClear(GL_COLOR_BUFFER_BIT); 381 382 glUseProgram(program); 383 glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 1.0, 1.0, 0.0, 0.0); 384 glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0.0, 0.0, 1.0, 1.0); 385 glBegin(GL_TRIANGLES); 386 387 glColor3f(0,0,1); 388 glTexCoord3f(1,1,0); 389 glVertex3f( 0.9, -0.9, -970.0); 390 391 glColor3f(1,0,0); 392 glTexCoord3f(1,-1,0); 393 glVertex3f( 0.9, 0.9, -30.0); 394 395 glColor3f(0,1,0); 396 glTexCoord3f(-1,0,0); 397 glVertex3f(-0.9, 0.0, -30.0); 398 glEnd(); 399 400 glFlush(); 401 if (show_fps) { 402 ++frame_cnt; 403 glutPostRedisplay(); 404 } 405} 406 407 408int main(int argc, char **argv) 409{ 410 glutInit(&argc, argv); 411 glutInitWindowPosition(0, 0); 412 glutInitWindowSize(250, 250); 413 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH); 414 args(argc, argv); 415 glutCreateWindow(filename ? filename : "fp-tri"); 416 glewInit(); 417 glutReshapeFunc(Reshape); 418 glutKeyboardFunc(Key); 419 glutDisplayFunc(Display); 420 prepare_shaders(); 421 Init(); 422#ifndef WIN32 423 if (show_fps) { 424 signal(SIGALRM, alarmhandler); 425 alarm(5); 426 } 427#endif 428 glutMainLoop(); 429 return 0; 430} 431