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