diff options
Diffstat (limited to 'progs/glsl/convolutions.c')
-rw-r--r-- | progs/glsl/convolutions.c | 470 |
1 files changed, 0 insertions, 470 deletions
diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c deleted file mode 100644 index fdfaf568a2..0000000000 --- a/progs/glsl/convolutions.c +++ /dev/null @@ -1,470 +0,0 @@ -/** - * Convolution with GLSL. - * Note: uses GL_ARB_shader_objects, GL_ARB_vertex_shader, GL_ARB_fragment_shader, - * not the OpenGL 2.0 shader API. - * Author: Zack Rusin - */ - -#include <GL/glew.h> - -#define GL_GLEXT_PROTOTYPES -#include "readtex.h" - -#include <GL/glut.h> -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <math.h> - -enum Filter { - GAUSSIAN_BLUR, - SHARPEN, - MEAN_REMOVAL, - EMBOSS, - EDGE_DETECT, - NO_FILTER, - LAST -}; -#define QUIT LAST - -struct BoundingBox { - float minx, miny, minz; - float maxx, maxy, maxz; -}; -struct Texture { - GLuint id; - GLfloat x; - GLfloat y; - GLint width; - GLint height; - GLenum format; -}; - -static const char *textureLocation = "../images/girl2.rgb"; - -static GLfloat viewRotx = 0.0, viewRoty = 0.0, viewRotz = 0.0; -static struct BoundingBox box; -static struct Texture texture; -static GLuint program; -static GLint menuId; -static enum Filter filter = GAUSSIAN_BLUR; - - -static void checkError(int line) -{ - GLenum err = glGetError(); - if (err) { - printf("GL Error %s (0x%x) at line %d\n", - gluErrorString(err), (int) err, line); - } -} - -static void loadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader(shader); - - glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog(shader, 1000, &len, log); - fprintf(stderr, "Problem compiling shader: %s\n", log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - -static void readShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "Unable to open shader file %s\n", filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("Read %d bytes from shader file %s\n", n, filename); - if (n > 0) { - buffer[n] = 0; - loadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -checkLink(GLuint prog) -{ - GLint stat; - glGetProgramiv(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - -static void fillConvolution(GLint *k, - GLfloat *scale, - GLfloat *color) -{ - switch(filter) { - case GAUSSIAN_BLUR: - k[0] = 1; k[1] = 2; k[2] = 1; - k[3] = 2; k[4] = 4; k[5] = 2; - k[6] = 1; k[7] = 2; k[8] = 1; - - *scale = 1./16.; - break; - case SHARPEN: - k[0] = 0; k[1] = -2; k[2] = 0; - k[3] = -2; k[4] = 11; k[5] = -2; - k[6] = 0; k[7] = -2; k[8] = 0; - - *scale = 1./3.; - break; - case MEAN_REMOVAL: - k[0] = -1; k[1] = -1; k[2] = -1; - k[3] = -1; k[4] = 9; k[5] = -1; - k[6] = -1; k[7] = -1; k[8] = -1; - - *scale = 1./1.; - break; - case EMBOSS: - k[0] = -1; k[1] = 0; k[2] = -1; - k[3] = 0; k[4] = 4; k[5] = 0; - k[6] = -1; k[7] = 0; k[8] = -1; - - *scale = 1./1.; - color[0] = 0.5; - color[1] = 0.5; - color[2] = 0.5; - color[3] = 0.5; - break; - case EDGE_DETECT: - k[0] = 1; k[1] = 1; k[2] = 1; - k[3] = 0; k[4] = 0; k[5] = 0; - k[6] = -1; k[7] = -1; k[8] = -1; - - *scale = 1.; - color[0] = 0.5; - color[1] = 0.5; - color[2] = 0.5; - color[3] = 0.5; - break; - case NO_FILTER: - k[0] = 0; k[1] = 0; k[2] = 0; - k[3] = 0; k[4] = 1; k[5] = 0; - k[6] = 0; k[7] = 0; k[8] = 0; - - *scale = 1.; - break; - default: - assert(!"Unhandled switch value"); - } -} - -static void setupConvolution() -{ - GLint *kernel = (GLint*)malloc(sizeof(GLint) * 9); - GLfloat scale = 0.0; - GLfloat *vecKer = (GLfloat*)malloc(sizeof(GLfloat) * 9 * 4); - GLuint loc; - GLuint i; - GLfloat baseColor[4]; - baseColor[0] = 0; - baseColor[1] = 0; - baseColor[2] = 0; - baseColor[3] = 0; - - fillConvolution(kernel, &scale, baseColor); - /*vector of 4*/ - for (i = 0; i < 9; ++i) { - vecKer[i*4 + 0] = kernel[i]; - vecKer[i*4 + 1] = kernel[i]; - vecKer[i*4 + 2] = kernel[i]; - vecKer[i*4 + 3] = kernel[i]; - } - - loc = glGetUniformLocationARB(program, "KernelValue"); - glUniform4fv(loc, 9, vecKer); - loc = glGetUniformLocationARB(program, "ScaleFactor"); - glUniform4f(loc, scale, scale, scale, scale); - loc = glGetUniformLocationARB(program, "BaseColor"); - glUniform4f(loc, baseColor[0], baseColor[1], - baseColor[2], baseColor[3]); - - free(vecKer); - free(kernel); -} - -static void createProgram(const char *vertProgFile, - const char *fragProgFile) -{ - GLuint fragShader = 0, vertShader = 0; - - program = glCreateProgram(); - if (vertProgFile) { - vertShader = glCreateShader(GL_VERTEX_SHADER); - readShader(vertShader, vertProgFile); - glAttachShader(program, vertShader); - } - - if (fragProgFile) { - fragShader = glCreateShader(GL_FRAGMENT_SHADER); - readShader(fragShader, fragProgFile); - glAttachShader(program, fragShader); - } - - glLinkProgram(program); - checkLink(program); - - glUseProgram(program); - - /* - assert(glIsProgram(program)); - assert(glIsShader(fragShader)); - assert(glIsShader(vertShader)); - */ - - checkError(__LINE__); - {/*texture*/ - GLuint texLoc = glGetUniformLocationARB(program, "srcTex"); - glUniform1iARB(texLoc, 0); - } - {/*setup offsets */ - float offsets[] = { 1.0 / texture.width, 1.0 / texture.height, - 0.0 , 1.0 / texture.height, - -1.0 / texture.width, 1.0 / texture.height, - 1.0 / texture.width, 0.0, - 0.0 , 0.0, - -1.0 / texture.width, 0.0, - 1.0 / texture.width, -1.0 / texture.height, - 0.0 , -1.0 / texture.height, - -1.0 / texture.width, -1.0 / texture.height }; - GLuint offsetLoc = glGetUniformLocationARB(program, "Offset"); - glUniform2fv(offsetLoc, 9, offsets); - } - setupConvolution(); - - checkError(__LINE__); -} - - -static void readTexture(const char *filename) -{ - GLubyte *data; - - texture.x = 0; - texture.y = 0; - - glGenTextures(1, &texture.id); - glBindTexture(GL_TEXTURE_2D, texture.id); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - data = LoadRGBImage(filename, &texture.width, &texture.height, - &texture.format); - if (!data) { - printf("Error: couldn't load texture image '%s'\n", filename); - exit(1); - } - printf("Texture %s (%d x %d)\n", - filename, texture.width, texture.height); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, - texture.width, texture.height, 0, texture.format, - GL_UNSIGNED_BYTE, data); -} - -static void menuSelected(int entry) -{ - switch (entry) { - case QUIT: - exit(0); - break; - default: - filter = (enum Filter)entry; - } - setupConvolution(); - - glutPostRedisplay(); -} - -static void menuInit() -{ - menuId = glutCreateMenu(menuSelected); - - glutAddMenuEntry("Gaussian blur", GAUSSIAN_BLUR); - glutAddMenuEntry("Sharpen", SHARPEN); - glutAddMenuEntry("Mean removal", MEAN_REMOVAL); - glutAddMenuEntry("Emboss", EMBOSS); - glutAddMenuEntry("Edge detect", EDGE_DETECT); - glutAddMenuEntry("None", NO_FILTER); - - glutAddMenuEntry("Quit", QUIT); - - glutAttachMenu(GLUT_RIGHT_BUTTON); -} - -static void init() -{ - if (!glutExtensionSupported("GL_ARB_shader_objects") || - !glutExtensionSupported("GL_ARB_vertex_shader") || - !glutExtensionSupported("GL_ARB_fragment_shader")) { - fprintf(stderr, "Sorry, this program requires GL_ARB_shader_objects, GL_ARB_vertex_shader, and GL_ARB_fragment_shader\n"); - exit(1); - } - - fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); - fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); - fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); - - menuInit(); - readTexture(textureLocation); - createProgram("convolution.vert", "convolution.frag"); - - glEnable(GL_TEXTURE_2D); - glClearColor(1.0, 1.0, 1.0, 1.0); - /*glShadeModel(GL_SMOOTH);*/ - glShadeModel(GL_FLAT); -} - -static void reshape(int width, int height) -{ - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - box.minx = 0; - box.maxx = width; - box.miny = 0; - box.maxy = height; - box.minz = 0; - box.maxz = 1; - glOrtho(box.minx, box.maxx, box.miny, box.maxy, -999999, 999999); - glMatrixMode(GL_MODELVIEW); -} - -static void keyPress(unsigned char key, int x, int y) -{ - switch(key) { - case 27: - exit(0); - default: - break; - } - glutPostRedisplay(); -} - -static void -special(int k, int x, int y) -{ - switch (k) { - case GLUT_KEY_UP: - viewRotx += 2.0; - break; - case GLUT_KEY_DOWN: - viewRotx -= 2.0; - break; - case GLUT_KEY_LEFT: - viewRoty += 2.0; - break; - case GLUT_KEY_RIGHT: - viewRoty -= 2.0; - break; - default: - return; - } - glutPostRedisplay(); -} - - -static void draw() -{ - GLfloat center[2]; - GLfloat anchor[2]; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glLoadIdentity(); - glPushMatrix(); - - center[0] = box.maxx/2; - center[1] = box.maxy/2; - anchor[0] = center[0] - texture.width/2; - anchor[1] = center[1] - texture.height/2; - - glTranslatef(center[0], center[1], 0); - glRotatef(viewRotx, 1.0, 0.0, 0.0); - glRotatef(viewRoty, 0.0, 1.0, 0.0); - glRotatef(viewRotz, 0.0, 0.0, 1.0); - glTranslatef(-center[0], -center[1], 0); - - glTranslatef(anchor[0], anchor[1], 0); - glBegin(GL_TRIANGLE_STRIP); - { - glColor3f(1., 0., 0.); - glTexCoord2f(0, 0); - glVertex3f(0, 0, 0); - - glColor3f(0., 1., 0.); - glTexCoord2f(0, 1.0); - glVertex3f(0, texture.height, 0); - - glColor3f(1., 0., 0.); - glTexCoord2f(1.0, 0); - glVertex3f(texture.width, 0, 0); - - glColor3f(0., 1., 0.); - glTexCoord2f(1, 1); - glVertex3f(texture.width, texture.height, 0); - } - glEnd(); - - glPopMatrix(); - - glutSwapBuffers(); -} - -int main(int argc, char **argv) -{ - glutInit(&argc, argv); - - glutInitWindowSize(400, 400); - glutInitDisplayMode(GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE); - - if (!glutCreateWindow("Image Convolutions")) { - fprintf(stderr, "Couldn't create window!\n"); - exit(1); - } - - glewInit(); - init(); - - glutReshapeFunc(reshape); - glutKeyboardFunc(keyPress); - glutSpecialFunc(special); - glutDisplayFunc(draw); - - - glutMainLoop(); - return 0; -} |