132001f49Smrg
232001f49Smrg#include <stdio.h>
332001f49Smrg#include <string.h>
432001f49Smrg#include <stdlib.h>
532001f49Smrg
632001f49Smrg#ifndef WIN32
732001f49Smrg#include <unistd.h>
832001f49Smrg#include <signal.h>
932001f49Smrg#endif
1032001f49Smrg
1132001f49Smrg#include <GL/glew.h>
1232001f49Smrg#include "glut_wrap.h"
1332001f49Smrg
1432001f49Smrg#include "readtex.c"
1532001f49Smrg
1632001f49Smrg
1732001f49Smrg#define TEXTURE_FILE DEMOS_DATA_DIR "bw.rgb"
1832001f49Smrg
1932001f49Smrgunsigned show_fps = 0;
2032001f49Smrgunsigned int frame_cnt = 0;
2132001f49Smrgvoid alarmhandler(int);
2232001f49Smrgstatic const char *filename = NULL;
2332001f49Smrg
2432001f49Smrgstatic GLuint fragShader;
2532001f49Smrgstatic GLuint vertShader;
2632001f49Smrgstatic GLuint program;
2732001f49Smrg
2832001f49Smrg
2932001f49Smrgstatic void usage(char *name)
3032001f49Smrg{
3132001f49Smrg   fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
3232001f49Smrg#ifndef WIN32
3332001f49Smrg   fprintf(stderr, "\n" );
3432001f49Smrg   fprintf(stderr, "options:\n");
3532001f49Smrg   fprintf(stderr, "    -fps  show frames per second\n");
3632001f49Smrg#endif
3732001f49Smrg}
3832001f49Smrg
3932001f49Smrg#ifndef WIN32
4032001f49Smrgvoid alarmhandler (int sig)
4132001f49Smrg{
4232001f49Smrg   if (sig == SIGALRM) {
4332001f49Smrg      printf("%d frames in 5.0 seconds = %.3f FPS\n", frame_cnt,
4432001f49Smrg             frame_cnt / 5.0);
4532001f49Smrg
4632001f49Smrg      frame_cnt = 0;
4732001f49Smrg   }
4832001f49Smrg   signal(SIGALRM, alarmhandler);
4932001f49Smrg   alarm(5);
5032001f49Smrg}
5132001f49Smrg#endif
5232001f49Smrg
5332001f49Smrg
5432001f49Smrg
5532001f49Smrg
5632001f49Smrgstatic void load_and_compile_shader(GLuint shader, const char *text)
5732001f49Smrg{
5832001f49Smrg   GLint stat;
5932001f49Smrg
6032001f49Smrg   glShaderSource(shader, 1, (const GLchar **) &text, NULL);
6132001f49Smrg
6232001f49Smrg   glCompileShader(shader);
6332001f49Smrg
6432001f49Smrg   glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
6532001f49Smrg   if (!stat) {
6632001f49Smrg      GLchar log[1000];
6732001f49Smrg      GLsizei len;
6832001f49Smrg      glGetShaderInfoLog(shader, 1000, &len, log);
6932001f49Smrg      fprintf(stderr, "fp-tri: problem compiling shader:\n%s\n", log);
7032001f49Smrg      exit(1);
7132001f49Smrg   }
7232001f49Smrg}
7332001f49Smrg
7432001f49Smrgstatic void read_shader(GLuint shader, const char *filename)
7532001f49Smrg{
7632001f49Smrg   const int max = 100*1000;
7732001f49Smrg   int n;
7832001f49Smrg   char *buffer = (char*) malloc(max);
7932001f49Smrg   FILE *f = fopen(filename, "r");
8032001f49Smrg   if (!f) {
8132001f49Smrg      fprintf(stderr, "fp-tri: Unable to open shader file %s\n", filename);
8232001f49Smrg      exit(1);
8332001f49Smrg   }
8432001f49Smrg
8532001f49Smrg   n = fread(buffer, 1, max, f);
8632001f49Smrg   printf("fp-tri: read %d bytes from shader file %s\n", n, filename);
8732001f49Smrg   if (n > 0) {
8832001f49Smrg      buffer[n] = 0;
8932001f49Smrg      load_and_compile_shader(shader, buffer);
9032001f49Smrg   }
9132001f49Smrg
9232001f49Smrg   fclose(f);
9332001f49Smrg   free(buffer);
9432001f49Smrg}
9532001f49Smrg
9632001f49Smrgstatic void check_link(GLuint prog)
9732001f49Smrg{
9832001f49Smrg   GLint stat;
9932001f49Smrg   glGetProgramiv(prog, GL_LINK_STATUS, &stat);
10032001f49Smrg   if (!stat) {
10132001f49Smrg      GLchar log[1000];
10232001f49Smrg      GLsizei len;
10332001f49Smrg      glGetProgramInfoLog(prog, 1000, &len, log);
10432001f49Smrg      fprintf(stderr, "Linker error:\n%s\n", log);
10532001f49Smrg   }
10632001f49Smrg}
10732001f49Smrg
10832001f49Smrgstatic void setup_uniforms(void)
10932001f49Smrg{
11032001f49Smrg   {
11132001f49Smrg      GLint loc1f = glGetUniformLocationARB(program, "Offset1f");
11232001f49Smrg      GLint loc2f = glGetUniformLocationARB(program, "Offset2f");
11332001f49Smrg      GLint loc4f = glGetUniformLocationARB(program, "Offset4f");
11432001f49Smrg      GLfloat vecKer[] =
11532001f49Smrg         { 1.0, 0.0, 0.0,  1.0,
11632001f49Smrg           0.0, 1.0, 0.0,  1.0,
11732001f49Smrg           1.0, 0.0, 0.0,  1.0,
11832001f49Smrg           0.0, 0.0, 0.0,  1.0
11932001f49Smrg         };
12032001f49Smrg      if (loc1f >= 0)
12132001f49Smrg         glUniform1fv(loc1f, 16, vecKer);
12232001f49Smrg
12332001f49Smrg      if (loc2f >= 0)
12432001f49Smrg         glUniform2fv(loc2f, 8, vecKer);
12532001f49Smrg
12632001f49Smrg      if (loc4f >= 0)
12732001f49Smrg         glUniform4fv(loc4f, 4, vecKer);
12832001f49Smrg
12932001f49Smrg   }
13032001f49Smrg
13132001f49Smrg   {
13232001f49Smrg      GLint loci = glGetUniformLocationARB(program, "KernelSizeInt");
13332001f49Smrg      if (loci >= 0)
13432001f49Smrg         glUniform1i(loci, 4);
13532001f49Smrg   }
13632001f49Smrg   {
13732001f49Smrg      GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
13832001f49Smrg      GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
13932001f49Smrg      GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
14032001f49Smrg      GLfloat vecKer[] =
14132001f49Smrg         { 1.0, 0.0, 0.0,  0.25,
14232001f49Smrg           0.0, 1.0, 0.0,  0.25,
14332001f49Smrg           0.0, 0.0, 1.0,  0.25,
14432001f49Smrg           0.0, 0.0, 0.0,  0.25,
14532001f49Smrg           0.5, 0.0, 0.0,  0.35,
14632001f49Smrg           0.0, 0.5, 0.0,  0.35,
14732001f49Smrg           0.0, 0.0, 0.5,  0.35,
14832001f49Smrg           0.0, 0.0, 0.0,  0.35
14932001f49Smrg         };
15032001f49Smrg      if (loc1f >= 0)
15132001f49Smrg         glUniform1fv(loc1f, 16, vecKer);
15232001f49Smrg
15332001f49Smrg      if (loc2f >= 0)
15432001f49Smrg         glUniform2fv(loc2f, 8, vecKer);
15532001f49Smrg
15632001f49Smrg      if (loc4f >= 0)
15732001f49Smrg         glUniform4fv(loc4f, 4, vecKer);
15832001f49Smrg   }
15932001f49Smrg
16032001f49Smrg   {
16132001f49Smrg      GLint tex1 = glGetUniformLocationARB(program, "tex1");
16232001f49Smrg      GLint tex2 = glGetUniformLocationARB(program, "tex2");
16332001f49Smrg      if (tex1 >= 0)
16432001f49Smrg         glUniform1i(tex1, 0);
16532001f49Smrg      if (tex2 >= 0)
16632001f49Smrg         glUniform1i(tex2, 1);
16732001f49Smrg   }
16832001f49Smrg}
16932001f49Smrg
17032001f49Smrgstatic void prepare_shaders(void)
17132001f49Smrg{
17232001f49Smrg   static const char *fragShaderText =
17332001f49Smrg      "void main() {\n"
17432001f49Smrg      "    gl_FragColor = gl_Color;\n"
17532001f49Smrg      "}\n";
17632001f49Smrg   static const char *vertShaderText =
17732001f49Smrg      "void main() {\n"
17832001f49Smrg      "   gl_FrontColor = gl_Color;\n"
17932001f49Smrg      "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
18032001f49Smrg      "}\n";
18132001f49Smrg   fragShader = glCreateShader(GL_FRAGMENT_SHADER);
18232001f49Smrg   if (filename)
18332001f49Smrg      read_shader(fragShader, filename);
18432001f49Smrg   else
18532001f49Smrg      load_and_compile_shader(fragShader, fragShaderText);
18632001f49Smrg
18732001f49Smrg
18832001f49Smrg   vertShader = glCreateShader(GL_VERTEX_SHADER);
18932001f49Smrg   load_and_compile_shader(vertShader, vertShaderText);
19032001f49Smrg
19132001f49Smrg   program = glCreateProgram();
19232001f49Smrg   glAttachShader(program, fragShader);
19332001f49Smrg   glAttachShader(program, vertShader);
19432001f49Smrg   glLinkProgram(program);
19532001f49Smrg   check_link(program);
19632001f49Smrg   glUseProgram(program);
19732001f49Smrg
19832001f49Smrg   setup_uniforms();
19932001f49Smrg}
20032001f49Smrg
20132001f49Smrg#define LEVELS 8
20232001f49Smrg#define SIZE (1<<LEVELS)
20332001f49Smrgstatic int TexWidth = SIZE, TexHeight = SIZE;
20432001f49Smrg
20532001f49Smrg
20632001f49Smrgstatic void
20732001f49SmrgResetTextureLevel( int i )
20832001f49Smrg{
20932001f49Smrg   GLubyte tex2d[SIZE*SIZE][4];
21032001f49Smrg
21132001f49Smrg   {
21232001f49Smrg      GLint Width = TexWidth / (1 << i);
21332001f49Smrg      GLint Height = TexHeight / (1 << i);
21432001f49Smrg      GLint s, t;
21532001f49Smrg
21632001f49Smrg      for (s = 0; s < Width; s++) {
21732001f49Smrg         for (t = 0; t < Height; t++) {
21832001f49Smrg            tex2d[t*Width+s][0] = ((s / 16) % 2) ? 0 : 255;
21932001f49Smrg            tex2d[t*Width+s][1] = ((t / 16) % 2) ? 0 : 255;
22032001f49Smrg            tex2d[t*Width+s][2] = 128;
22132001f49Smrg            tex2d[t*Width+s][3] = 255;
22232001f49Smrg         }
22332001f49Smrg      }
22432001f49Smrg
22532001f49Smrg      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
22632001f49Smrg
22732001f49Smrg      glTexImage2D(GL_TEXTURE_2D, i, GL_RGB, Width, Height, 0,
22832001f49Smrg                   GL_RGBA, GL_UNSIGNED_BYTE, tex2d);
22932001f49Smrg   }
23032001f49Smrg}
23132001f49Smrg
23232001f49Smrg
23332001f49Smrgstatic void
23432001f49SmrgResetTexture( void )
23532001f49Smrg{
23632001f49Smrg   int i;
23732001f49Smrg
23832001f49Smrg   for (i = 0; i <= LEVELS; i++)
23932001f49Smrg   {
24032001f49Smrg      ResetTextureLevel(i);
24132001f49Smrg   }
24232001f49Smrg}
24332001f49Smrg
24432001f49Smrgstatic void Init( void )
24532001f49Smrg{
24632001f49Smrg   GLuint Texture;
24732001f49Smrg
24832001f49Smrg   /* Setup texture unit 0 */
24932001f49Smrg   glGenTextures(1, &Texture);
25032001f49Smrg   glBindTexture(GL_TEXTURE_2D, Texture);
25132001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
25232001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
25332001f49Smrg   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
25432001f49Smrg   if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
25532001f49Smrg      printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
25632001f49Smrg      exit(1);
25732001f49Smrg   }
25832001f49Smrg
25932001f49Smrg   /* Setup texture unit 1 */
26032001f49Smrg   glGenTextures(1, &Texture);
26132001f49Smrg   glActiveTextureARB(GL_TEXTURE0_ARB + 1);
26232001f49Smrg   glBindTexture(GL_TEXTURE_2D, Texture);
26332001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
26432001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
26532001f49Smrg   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
26632001f49Smrg
26732001f49Smrg   {
26832001f49Smrg      GLubyte data[32][32];
26932001f49Smrg      int width = 32;
27032001f49Smrg      int height = 32;
27132001f49Smrg      int i;
27232001f49Smrg      int j;
27332001f49Smrg
27432001f49Smrg      for (i = 0; i < 32; i++)
27532001f49Smrg         for (j = 0; j < 32; j++)
27632001f49Smrg	 {
27732001f49Smrg	    /**
27832001f49Smrg	     ** +-----------+
27932001f49Smrg	     ** |     W     |
28032001f49Smrg	     ** |  +-----+  |
28132001f49Smrg	     ** |  |     |  |
28232001f49Smrg	     ** |  |  B  |  |
28332001f49Smrg	     ** |  |     |  |
28432001f49Smrg	     ** |  +-----+  |
28532001f49Smrg	     ** |           |
28632001f49Smrg	     ** +-----------+
28732001f49Smrg	     **/
28832001f49Smrg	    int i2 = i - height / 2;
28932001f49Smrg	    int j2 = j - width / 2;
29032001f49Smrg	    int h8 = height / 8;
29132001f49Smrg	    int w8 = width / 8;
29232001f49Smrg	    if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) {
29332001f49Smrg	       data[i][j] = 0x00;
29432001f49Smrg	    } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) {
29532001f49Smrg	       data[i][j] = 0x55;
29632001f49Smrg	    } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) {
29732001f49Smrg	       data[i][j] = 0xaa;
29832001f49Smrg	    } else {
29932001f49Smrg	       data[i][j] = 0xff;
30032001f49Smrg	    }
30132001f49Smrg	 }
30232001f49Smrg
30332001f49Smrg      glTexImage2D( GL_TEXTURE_2D, 0,
30432001f49Smrg                    GL_ALPHA8,
30532001f49Smrg                    32, 32, 0,
30632001f49Smrg                    GL_ALPHA, GL_UNSIGNED_BYTE, data );
30732001f49Smrg   }
30832001f49Smrg
30932001f49Smrg   /* Setup texture unit 2 */
31032001f49Smrg   glGenTextures(1, &Texture);
31132001f49Smrg   glActiveTextureARB(GL_TEXTURE0_ARB + 2);
31232001f49Smrg   glBindTexture(GL_TEXTURE_2D, Texture);
31332001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
31432001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
31532001f49Smrg   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
31632001f49Smrg   ResetTexture();
31732001f49Smrg
31832001f49Smrg   glClearColor(.1, .3, .5, 0);
31932001f49Smrg}
32032001f49Smrg
32132001f49Smrg
32232001f49Smrg
32332001f49Smrg
32432001f49Smrgstatic void args(int argc, char *argv[])
32532001f49Smrg{
32632001f49Smrg   GLint i;
32732001f49Smrg
32832001f49Smrg   for (i = 1; i < argc; i++) {
32932001f49Smrg      if (strcmp(argv[i], "-fps") == 0) {
33032001f49Smrg         show_fps = 1;
33132001f49Smrg      }
33232001f49Smrg      else if (i == argc - 1) {
33332001f49Smrg	 filename = argv[i];
33432001f49Smrg      }
33532001f49Smrg      else {
33632001f49Smrg	 usage(argv[0]);
33732001f49Smrg	 exit(1);
33832001f49Smrg      }
33932001f49Smrg   }
34032001f49Smrg}
34132001f49Smrg
34232001f49Smrg
34332001f49Smrg
34432001f49Smrg
34532001f49Smrg
34632001f49Smrgstatic void Reshape(int width, int height)
34732001f49Smrg{
34832001f49Smrg
34932001f49Smrg    glViewport(0, 0, (GLint)width, (GLint)height);
35032001f49Smrg
35132001f49Smrg    glMatrixMode(GL_PROJECTION);
35232001f49Smrg    glLoadIdentity();
35332001f49Smrg    glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
35432001f49Smrg    glMatrixMode(GL_MODELVIEW);
35532001f49Smrg}
35632001f49Smrg
35732001f49Smrgstatic void CleanUp(void)
35832001f49Smrg{
35932001f49Smrg   glDeleteShader(fragShader);
36032001f49Smrg   glDeleteShader(vertShader);
36132001f49Smrg   glDeleteProgram(program);
36232001f49Smrg}
36332001f49Smrg
36432001f49Smrgstatic void Key(unsigned char key, int x, int y)
36532001f49Smrg{
36632001f49Smrg
36732001f49Smrg   switch (key) {
36832001f49Smrg   case 27:
36932001f49Smrg      CleanUp();
37032001f49Smrg      exit(1);
37132001f49Smrg   default:
37232001f49Smrg      break;
37332001f49Smrg   }
37432001f49Smrg
37532001f49Smrg   glutPostRedisplay();
37632001f49Smrg}
37732001f49Smrg
37832001f49Smrgstatic void Display(void)
37932001f49Smrg{
38032001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
38132001f49Smrg
38232001f49Smrg   glUseProgram(program);
38332001f49Smrg   glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 1.0, 1.0, 0.0, 0.0);
38432001f49Smrg   glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0.0, 0.0, 1.0, 1.0);
38532001f49Smrg   glBegin(GL_TRIANGLES);
38632001f49Smrg
38732001f49Smrg   glColor3f(0,0,1);
38832001f49Smrg   glTexCoord3f(1,1,0);
38932001f49Smrg   glVertex3f( 0.9, -0.9, -970.0);
39032001f49Smrg
39132001f49Smrg   glColor3f(1,0,0);
39232001f49Smrg   glTexCoord3f(1,-1,0);
39332001f49Smrg   glVertex3f( 0.9,  0.9, -30.0);
39432001f49Smrg
39532001f49Smrg   glColor3f(0,1,0);
39632001f49Smrg   glTexCoord3f(-1,0,0);
39732001f49Smrg   glVertex3f(-0.9,  0.0, -30.0);
39832001f49Smrg   glEnd();
39932001f49Smrg
40032001f49Smrg   glFlush();
40132001f49Smrg   if (show_fps) {
40232001f49Smrg      ++frame_cnt;
40332001f49Smrg      glutPostRedisplay();
40432001f49Smrg   }
40532001f49Smrg}
40632001f49Smrg
40732001f49Smrg
40832001f49Smrgint main(int argc, char **argv)
40932001f49Smrg{
41032001f49Smrg   glutInit(&argc, argv);
41132001f49Smrg   glutInitWindowPosition(0, 0);
41232001f49Smrg   glutInitWindowSize(250, 250);
41332001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
41432001f49Smrg   args(argc, argv);
41532001f49Smrg   glutCreateWindow(filename ? filename : "fp-tri");
41632001f49Smrg   glewInit();
41732001f49Smrg   glutReshapeFunc(Reshape);
41832001f49Smrg   glutKeyboardFunc(Key);
41932001f49Smrg   glutDisplayFunc(Display);
42032001f49Smrg   prepare_shaders();
42132001f49Smrg   Init();
42232001f49Smrg#ifndef WIN32
42332001f49Smrg   if (show_fps) {
42432001f49Smrg      signal(SIGALRM, alarmhandler);
42532001f49Smrg      alarm(5);
42632001f49Smrg   }
42732001f49Smrg#endif
42832001f49Smrg   glutMainLoop();
42932001f49Smrg   return 0;
43032001f49Smrg}
431