sdrblurtest
changeset 0:26513fdda566
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 17 Oct 2013 08:19:56 +0300 |
parents | |
children | e8fc0c9754c9 |
files | .hgignore Makefile RUN sdr/blur.glsl sdr/hblur.glsl sdr/vblur.glsl sdr/vert.glsl src/main.cc src/rtarg.cc src/rtarg.h src/sdr.c src/sdr.h |
diffstat | 12 files changed, 1004 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Thu Oct 17 08:19:56 2013 +0300 1.3 @@ -0,0 +1,4 @@ 1.4 +\.o$ 1.5 +\.d$ 1.6 +\.swp$ 1.7 +^sdrconvol$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Thu Oct 17 08:19:56 2013 +0300 2.3 @@ -0,0 +1,23 @@ 2.4 +src = $(wildcard src/*.cc) 2.5 +csrc = $(wildcard src/*.c) 2.6 +obj = $(src:.cc=.o) $(csrc:.c=.o) 2.7 +bin = sdrconvol 2.8 + 2.9 +CC = clang 2.10 +CXX = clang++ 2.11 +CFLAGS = -pedantic -Wall -g 2.12 +CXXFLAGS = -pedantic -Wall -g 2.13 +LDFLAGS = $(libgl) 2.14 + 2.15 +ifeq ($(shell uname -s), Darwin) 2.16 + libgl = -framework OpenGL -framework GLUT -lGLEW 2.17 +else 2.18 + libgl = -lGL -lGLU -lglut -lGLEW 2.19 +endif 2.20 + 2.21 +$(bin): $(obj) 2.22 + $(CXX) -o $@ $(obj) $(LDFLAGS) 2.23 + 2.24 +.PHONY: clean 2.25 +clean: 2.26 + rm -f $(obj) $(bin)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/RUN Thu Oct 17 08:19:56 2013 +0300 3.3 @@ -0,0 +1,3 @@ 3.4 +#!/bin/sh 3.5 + 3.6 +__GL_SYNC_TO_VBLANK=0 vblank_mode=0 frapix ./sdrconvol $*
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/sdr/blur.glsl Thu Oct 17 08:19:56 2013 +0300 4.3 @@ -0,0 +1,25 @@ 4.4 +uniform sampler2D tex; 4.5 +uniform vec2 size, texsize; 4.6 + 4.7 +#define KSZ 31 4.8 +#define HALF_KSZ 15 4.9 +#define SCALE float(KSZ * KSZ) 4.10 + 4.11 +void main() 4.12 +{ 4.13 + float pixw = 1.0 / texsize.x; 4.14 + float pixh = 1.0 / texsize.y; 4.15 + 4.16 + vec3 texel = vec3(0.0, 0.0, 0.0); 4.17 + for(int i=0; i<KSZ; i++) { 4.18 + for(int j=0; j<KSZ; j++) { 4.19 + float x = float(j - HALF_KSZ) * pixw; 4.20 + float y = float(i - HALF_KSZ) * pixh; 4.21 + vec2 uv = gl_TexCoord[0].st + vec2(x, y); 4.22 + texel += texture2D(tex, uv).rgb; 4.23 + } 4.24 + } 4.25 + 4.26 + gl_FragColor.rgb = texel / SCALE; 4.27 + gl_FragColor.a = 1.0; 4.28 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/sdr/hblur.glsl Thu Oct 17 08:19:56 2013 +0300 5.3 @@ -0,0 +1,21 @@ 5.4 +uniform sampler2D tex; 5.5 +uniform vec2 size, texsize; 5.6 + 5.7 +#define KSZ 31 5.8 +#define HALF_KSZ 15 5.9 +#define SCALE float(KSZ) 5.10 + 5.11 +void main() 5.12 +{ 5.13 + float pixw = 1.0 / texsize.x; 5.14 + 5.15 + vec3 texel = vec3(0.0, 0.0, 0.0); 5.16 + for(int i=0; i<KSZ; i++) { 5.17 + float x = float(i - HALF_KSZ) * pixw; 5.18 + vec2 uv = gl_TexCoord[0].st + vec2(x, 0.0); 5.19 + texel += texture2D(tex, uv).rgb; 5.20 + } 5.21 + 5.22 + gl_FragColor.rgb = texel / SCALE; 5.23 + gl_FragColor.a = 1.0; 5.24 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/sdr/vblur.glsl Thu Oct 17 08:19:56 2013 +0300 6.3 @@ -0,0 +1,21 @@ 6.4 +uniform sampler2D tex; 6.5 +uniform vec2 size, texsize; 6.6 + 6.7 +#define KSZ 31 6.8 +#define HALF_KSZ 15 6.9 +#define SCALE float(KSZ) 6.10 + 6.11 +void main() 6.12 +{ 6.13 + float pixh = 1.0 / texsize.y; 6.14 + 6.15 + vec3 texel = vec3(0.0, 0.0, 0.0); 6.16 + for(int i=0; i<KSZ; i++) { 6.17 + float y = float(i - HALF_KSZ) * pixh; 6.18 + vec2 uv = gl_TexCoord[0].st + vec2(0.0, y); 6.19 + texel += texture2D(tex, uv).rgb; 6.20 + } 6.21 + 6.22 + gl_FragColor.rgb = texel / SCALE; 6.23 + gl_FragColor.a = 1.0; 6.24 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/sdr/vert.glsl Thu Oct 17 08:19:56 2013 +0300 7.3 @@ -0,0 +1,5 @@ 7.4 +void main() 7.5 +{ 7.6 + gl_Position = ftransform(); 7.7 + gl_TexCoord[0] = gl_MultiTexCoord0; 7.8 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/main.cc Thu Oct 17 08:19:56 2013 +0300 8.3 @@ -0,0 +1,241 @@ 8.4 +#include <stdio.h> 8.5 +#include <stdlib.h> 8.6 +#include <math.h> 8.7 +#include <assert.h> 8.8 + 8.9 +#include <GL/glew.h> 8.10 +#ifndef __APPLE__ 8.11 +#include <GL/glut.h> 8.12 +#else 8.13 +#include <GLUT/glut.h> 8.14 +#endif 8.15 +#include "rtarg.h" 8.16 +#include "sdr.h" 8.17 + 8.18 +enum { 8.19 + BLUR_REG, 8.20 + BLUR_SEP, 8.21 + 8.22 + NUM_BLUR_TYPES 8.23 +}; 8.24 + 8.25 +static bool init(); 8.26 +static void cleanup(); 8.27 +static void disp(); 8.28 +static void print_string(const char *str); 8.29 +static void idle(); 8.30 +static void reshape(int x, int y); 8.31 +static void keyb(unsigned char key, int x, int y); 8.32 +static void mouse(int bn, int st, int x, int y); 8.33 +static void motion(int x, int y); 8.34 + 8.35 +static int win_width, win_height; 8.36 +static float cam_theta, cam_phi, cam_dist = 8; 8.37 + 8.38 +static RenderTarget *rtarg, *tmp_rtarg; 8.39 +static unsigned int sdrblur, sdr_hblur, sdr_vblur; 8.40 + 8.41 +static int blur_type = BLUR_REG; 8.42 + 8.43 + 8.44 +int main(int argc, char **argv) 8.45 +{ 8.46 + glutInitWindowSize(1280, 800); 8.47 + glutInit(&argc, argv); 8.48 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 8.49 + glutCreateWindow("convolution"); 8.50 + 8.51 + glutDisplayFunc(disp); 8.52 + glutIdleFunc(idle); 8.53 + glutReshapeFunc(reshape); 8.54 + glutKeyboardFunc(keyb); 8.55 + glutMouseFunc(mouse); 8.56 + glutMotionFunc(motion); 8.57 + 8.58 + if(!init()) { 8.59 + return 1; 8.60 + } 8.61 + atexit(cleanup); 8.62 + 8.63 + glutMainLoop(); 8.64 + return 0; 8.65 +} 8.66 + 8.67 +static bool init() 8.68 +{ 8.69 + glewInit(); 8.70 + 8.71 + glClearColor(0.1, 0.1, 0.1, 1); 8.72 + 8.73 + glEnable(GL_DEPTH_TEST); 8.74 + glEnable(GL_CULL_FACE); 8.75 + glEnable(GL_LIGHTING); 8.76 + glEnable(GL_LIGHT0); 8.77 + 8.78 + rtarg = new RenderTarget; 8.79 + tmp_rtarg = new RenderTarget; 8.80 + 8.81 + if(!(sdrblur = create_program_load("sdr/vert.glsl", "sdr/blur.glsl"))) { 8.82 + return false; 8.83 + } 8.84 + if(!(sdr_hblur = create_program_load("sdr/vert.glsl", "sdr/hblur.glsl"))) { 8.85 + return false; 8.86 + } 8.87 + if(!(sdr_vblur = create_program_load("sdr/vert.glsl", "sdr/vblur.glsl"))) { 8.88 + return false; 8.89 + } 8.90 + 8.91 + return true; 8.92 +} 8.93 + 8.94 +static void cleanup() 8.95 +{ 8.96 + delete rtarg; 8.97 + delete tmp_rtarg; 8.98 +} 8.99 + 8.100 +static void disp() 8.101 +{ 8.102 + glMatrixMode(GL_MODELVIEW); 8.103 + glLoadIdentity(); 8.104 + glTranslatef(0, 0, -cam_dist); 8.105 + glRotatef(cam_phi, 1, 0, 0); 8.106 + glRotatef(cam_theta, 0, 1, 0); 8.107 + 8.108 + bind_render_target(rtarg); 8.109 + 8.110 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 8.111 + 8.112 + glFrontFace(GL_CW); 8.113 + glutSolidTeapot(1.0); 8.114 + glFrontFace(GL_CCW); 8.115 + 8.116 + if(blur_type == BLUR_SEP) { 8.117 + // render with horizontal blur into tmp_rtarg 8.118 + bind_render_target(tmp_rtarg); 8.119 + 8.120 + set_uniform_float2(sdr_hblur, "size", rtarg->xsz, rtarg->ysz); 8.121 + set_uniform_float2(sdr_hblur, "texsize", rtarg->tex_xsz, rtarg->tex_ysz); 8.122 + bind_program(sdr_hblur); 8.123 + 8.124 + rtarg->display(); 8.125 + 8.126 + // render with vertical blur into the regular framebuffer 8.127 + bind_render_target(0); 8.128 + 8.129 + set_uniform_float2(sdr_vblur, "size", tmp_rtarg->xsz, tmp_rtarg->ysz); 8.130 + set_uniform_float2(sdr_vblur, "texsize", tmp_rtarg->tex_xsz, tmp_rtarg->tex_ysz); 8.131 + bind_program(sdr_vblur); 8.132 + 8.133 + tmp_rtarg->display(); 8.134 + 8.135 + } else { 8.136 + // render with the full blur into the regular framebuffer 8.137 + bind_render_target(0); 8.138 + 8.139 + // display the rendered image 8.140 + set_uniform_float2(sdrblur, "size", rtarg->xsz, rtarg->ysz); 8.141 + set_uniform_float2(sdrblur, "texsize", rtarg->tex_xsz, rtarg->tex_ysz); 8.142 + bind_program(sdrblur); 8.143 + 8.144 + rtarg->display(); 8.145 + } 8.146 + bind_program(0); 8.147 + 8.148 + print_string(blur_type == BLUR_REG ? "Regular blur" : "Seperable blur"); 8.149 + 8.150 + glutSwapBuffers(); 8.151 + assert(glGetError() == GL_NO_ERROR); 8.152 +} 8.153 + 8.154 +static void print_string(const char *str) 8.155 +{ 8.156 + glPushAttrib(GL_ENABLE_BIT); 8.157 + 8.158 + glMatrixMode(GL_MODELVIEW); 8.159 + glPushMatrix(); 8.160 + glLoadIdentity(); 8.161 + glMatrixMode(GL_PROJECTION); 8.162 + glPushMatrix(); 8.163 + glLoadIdentity(); 8.164 + glOrtho(0, win_width, 0, win_height, -1, 1); 8.165 + 8.166 + glDisable(GL_LIGHTING); 8.167 + glDisable(GL_DEPTH_TEST); 8.168 + 8.169 + glRasterPos2f(1, 1); 8.170 + glColor3f(1, 1, 0); 8.171 + while(*str) { 8.172 + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *str++); 8.173 + } 8.174 + 8.175 + glPopMatrix(); 8.176 + glMatrixMode(GL_MODELVIEW); 8.177 + glPopMatrix(); 8.178 + 8.179 + glPopAttrib(); 8.180 +} 8.181 + 8.182 +static void idle() 8.183 +{ 8.184 + glutPostRedisplay(); 8.185 +} 8.186 + 8.187 +static void reshape(int x, int y) 8.188 +{ 8.189 + win_width = x; 8.190 + win_height = y; 8.191 + 8.192 + glViewport(0, 0, x, y); 8.193 + 8.194 + glMatrixMode(GL_PROJECTION); 8.195 + glLoadIdentity(); 8.196 + gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); 8.197 + 8.198 + rtarg->reshape(x, y); 8.199 + tmp_rtarg->reshape(x, y); 8.200 +} 8.201 + 8.202 +static void keyb(unsigned char key, int x, int y) 8.203 +{ 8.204 + switch(key) { 8.205 + case 27: 8.206 + exit(0); 8.207 + 8.208 + case ' ': 8.209 + blur_type = (blur_type + 1) % NUM_BLUR_TYPES; 8.210 + break; 8.211 + } 8.212 +} 8.213 + 8.214 + 8.215 +static bool bnstate[32]; 8.216 +static int prev_x, prev_y; 8.217 + 8.218 +static void mouse(int bn, int st, int x, int y) 8.219 +{ 8.220 + prev_x = x; 8.221 + prev_y = y; 8.222 + bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN; 8.223 +} 8.224 + 8.225 +static void motion(int x, int y) 8.226 +{ 8.227 + int dx = x - prev_x; 8.228 + int dy = y - prev_y; 8.229 + prev_x = x; 8.230 + prev_y = y; 8.231 + 8.232 + if(bnstate[0]) { 8.233 + cam_theta += dx * 0.5; 8.234 + cam_phi += dy * 0.5; 8.235 + 8.236 + if(cam_phi < -90) cam_phi = -90; 8.237 + if(cam_phi > 90) cam_phi = 90; 8.238 + } 8.239 + if(bnstate[2]) { 8.240 + cam_dist -= dy * 0.1; 8.241 + 8.242 + if(cam_dist < 0) cam_dist = 0; 8.243 + } 8.244 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/rtarg.cc Thu Oct 17 08:19:56 2013 +0300 9.3 @@ -0,0 +1,136 @@ 9.4 +#include <GL/glew.h> 9.5 +#include "rtarg.h" 9.6 + 9.7 +RenderTarget::RenderTarget() 9.8 +{ 9.9 + fbo = tex = zbuf = 0; 9.10 +} 9.11 + 9.12 +RenderTarget::~RenderTarget() 9.13 +{ 9.14 + destroy(); 9.15 +} 9.16 + 9.17 +bool RenderTarget::create(int xsz, int ysz) 9.18 +{ 9.19 + destroy(); 9.20 + 9.21 + glGenFramebuffers(1, &fbo); 9.22 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 9.23 + 9.24 + this->xsz = xsz; 9.25 + this->ysz = ysz; 9.26 + tex_xsz = next_pow2(xsz); 9.27 + tex_ysz = next_pow2(ysz); 9.28 + 9.29 + glGenTextures(1, &tex); 9.30 + glBindTexture(GL_TEXTURE_2D, tex); 9.31 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 9.32 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 9.33 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 9.34 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 9.35 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 9.36 + 9.37 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); 9.38 + 9.39 + glGenRenderbuffers(1, &zbuf); 9.40 + glBindRenderbuffer(GL_RENDERBUFFER, zbuf); 9.41 + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 9.42 + 9.43 + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); 9.44 + 9.45 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 9.46 + return true; 9.47 +} 9.48 + 9.49 +void RenderTarget::destroy() 9.50 +{ 9.51 + if(fbo) { 9.52 + glDeleteFramebuffers(1, &fbo); 9.53 + } 9.54 + if(tex) { 9.55 + glDeleteTextures(1, &tex); 9.56 + } 9.57 + if(zbuf) { 9.58 + glDeleteRenderbuffers(1, &zbuf); 9.59 + } 9.60 +} 9.61 + 9.62 +void RenderTarget::reshape(int new_xsz, int new_ysz) 9.63 +{ 9.64 + if(!fbo) { 9.65 + create(new_xsz, new_ysz); 9.66 + return; 9.67 + } 9.68 + 9.69 + xsz = new_xsz; 9.70 + ysz = new_ysz; 9.71 + 9.72 + int new_txsz = next_pow2(new_xsz); 9.73 + int new_tysz = next_pow2(new_ysz); 9.74 + 9.75 + if(tex_xsz >= new_txsz && tex_ysz >= new_tysz) { 9.76 + return; 9.77 + } 9.78 + 9.79 + tex_xsz = new_txsz; 9.80 + tex_ysz = new_tysz; 9.81 + 9.82 + glBindTexture(GL_TEXTURE_2D, tex); 9.83 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 9.84 + 9.85 + glBindRenderbuffer(GL_RENDERBUFFER, zbuf); 9.86 + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 9.87 +} 9.88 + 9.89 +void RenderTarget::display() const 9.90 +{ 9.91 + glMatrixMode(GL_MODELVIEW); 9.92 + glPushMatrix(); 9.93 + glLoadIdentity(); 9.94 + glMatrixMode(GL_PROJECTION); 9.95 + glPushMatrix(); 9.96 + glLoadIdentity(); 9.97 + 9.98 + glPushAttrib(GL_ENABLE_BIT); 9.99 + glDisable(GL_DEPTH_TEST); 9.100 + glDisable(GL_LIGHTING); 9.101 + glEnable(GL_TEXTURE_2D); 9.102 + glBindTexture(GL_TEXTURE_2D, tex); 9.103 + 9.104 + float max_u = (float)xsz / (float)tex_xsz; 9.105 + float max_v = (float)ysz / (float)tex_ysz; 9.106 + 9.107 + glBegin(GL_QUADS); 9.108 + glColor3f(1, 1, 1); 9.109 + glTexCoord2f(0, 0); 9.110 + glVertex2f(-1, -1); 9.111 + glTexCoord2f(max_u, 0); 9.112 + glVertex2f(1, -1); 9.113 + glTexCoord2f(max_u, max_v); 9.114 + glVertex2f(1, 1); 9.115 + glTexCoord2f(0, max_v); 9.116 + glVertex2f(-1, 1); 9.117 + glEnd(); 9.118 + 9.119 + glPopAttrib(); 9.120 + glPopMatrix(); 9.121 + glMatrixMode(GL_MODELVIEW); 9.122 + glPopMatrix(); 9.123 +} 9.124 + 9.125 +void bind_render_target(const RenderTarget *rtarg) 9.126 +{ 9.127 + glBindFramebuffer(GL_FRAMEBUFFER, rtarg ? rtarg->fbo : 0); 9.128 +} 9.129 + 9.130 +int next_pow2(int x) 9.131 +{ 9.132 + x--; 9.133 + x = (x >> 1) | x; 9.134 + x = (x >> 2) | x; 9.135 + x = (x >> 4) | x; 9.136 + x = (x >> 8) | x; 9.137 + x = (x >> 16) | x; 9.138 + return x + 1; 9.139 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/rtarg.h Thu Oct 17 08:19:56 2013 +0300 10.3 @@ -0,0 +1,22 @@ 10.4 +#ifndef RTARG_H_ 10.5 +#define RTARG_H_ 10.6 + 10.7 +class RenderTarget { 10.8 +public: 10.9 + int xsz, ysz, tex_xsz, tex_ysz; 10.10 + unsigned int fbo, tex, zbuf; 10.11 + 10.12 + RenderTarget(); 10.13 + ~RenderTarget(); 10.14 + 10.15 + bool create(int xsz, int ysz); 10.16 + void destroy(); 10.17 + void reshape(int xsz, int ysz); 10.18 + 10.19 + void display() const; 10.20 +}; 10.21 + 10.22 +void bind_render_target(const RenderTarget *rtarg); 10.23 +int next_pow2(int x); 10.24 + 10.25 +#endif // RTARG_H_
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/sdr.c Thu Oct 17 08:19:56 2013 +0300 11.3 @@ -0,0 +1,427 @@ 11.4 +/* 11.5 +Printblobs - halftoning display hack 11.6 +Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org> 11.7 + 11.8 +This program is free software: you can redistribute it and/or modify 11.9 +it under the terms of the GNU General Public License as published by 11.10 +the Free Software Foundation, either version 3 of the License, or 11.11 +(at your option) any later version. 11.12 + 11.13 +This program is distributed in the hope that it will be useful, 11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.16 +GNU General Public License for more details. 11.17 + 11.18 +You should have received a copy of the GNU General Public License 11.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 11.20 +*/ 11.21 +#include <stdio.h> 11.22 +#include <stdlib.h> 11.23 +#include <string.h> 11.24 +#include <errno.h> 11.25 +#include <stdarg.h> 11.26 +#include <assert.h> 11.27 +#include <GL/glew.h> 11.28 + 11.29 +#if defined(unix) || defined(__unix__) 11.30 +#include <unistd.h> 11.31 +#include <sys/stat.h> 11.32 +#endif /* unix */ 11.33 + 11.34 +#include "sdr.h" 11.35 + 11.36 +static const char *sdrtypestr(unsigned int sdrtype); 11.37 + 11.38 +unsigned int create_vertex_shader(const char *src) 11.39 +{ 11.40 + return create_shader(src, GL_VERTEX_SHADER); 11.41 +} 11.42 + 11.43 +unsigned int create_pixel_shader(const char *src) 11.44 +{ 11.45 + return create_shader(src, GL_FRAGMENT_SHADER); 11.46 +} 11.47 + 11.48 +unsigned int create_tessctl_shader(const char *src) 11.49 +{ 11.50 + return create_shader(src, GL_TESS_CONTROL_SHADER); 11.51 +} 11.52 + 11.53 +unsigned int create_tesseval_shader(const char *src) 11.54 +{ 11.55 + return create_shader(src, GL_TESS_EVALUATION_SHADER); 11.56 +} 11.57 + 11.58 +unsigned int create_geometry_shader(const char *src) 11.59 +{ 11.60 + return create_shader(src, GL_GEOMETRY_SHADER); 11.61 +} 11.62 + 11.63 +unsigned int create_shader(const char *src, unsigned int sdr_type) 11.64 +{ 11.65 + unsigned int sdr; 11.66 + int success, info_len; 11.67 + char *info_str = 0; 11.68 + GLenum err; 11.69 + 11.70 + sdr = glCreateShader(sdr_type); 11.71 + assert(glGetError() == GL_NO_ERROR); 11.72 + glShaderSource(sdr, 1, &src, 0); 11.73 + err = glGetError(); 11.74 + assert(err == GL_NO_ERROR); 11.75 + glCompileShader(sdr); 11.76 + assert(glGetError() == GL_NO_ERROR); 11.77 + 11.78 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 11.79 + assert(glGetError() == GL_NO_ERROR); 11.80 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 11.81 + assert(glGetError() == GL_NO_ERROR); 11.82 + 11.83 + if(info_len) { 11.84 + if((info_str = malloc(info_len + 1))) { 11.85 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 11.86 + assert(glGetError() == GL_NO_ERROR); 11.87 + } 11.88 + } 11.89 + 11.90 + if(success) { 11.91 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 11.92 + } else { 11.93 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 11.94 + glDeleteShader(sdr); 11.95 + sdr = 0; 11.96 + } 11.97 + 11.98 + free(info_str); 11.99 + return sdr; 11.100 +} 11.101 + 11.102 +void free_shader(unsigned int sdr) 11.103 +{ 11.104 + glDeleteShader(sdr); 11.105 +} 11.106 + 11.107 +unsigned int load_vertex_shader(const char *fname) 11.108 +{ 11.109 + return load_shader(fname, GL_VERTEX_SHADER); 11.110 +} 11.111 + 11.112 +unsigned int load_pixel_shader(const char *fname) 11.113 +{ 11.114 + return load_shader(fname, GL_FRAGMENT_SHADER); 11.115 +} 11.116 + 11.117 +unsigned int load_tessctl_shader(const char *fname) 11.118 +{ 11.119 + return load_shader(fname, GL_TESS_CONTROL_SHADER); 11.120 +} 11.121 + 11.122 +unsigned int load_tesseval_shader(const char *fname) 11.123 +{ 11.124 + return load_shader(fname, GL_TESS_EVALUATION_SHADER); 11.125 +} 11.126 + 11.127 +unsigned int load_geometry_shader(const char *fname) 11.128 +{ 11.129 + return load_shader(fname, GL_GEOMETRY_SHADER); 11.130 +} 11.131 + 11.132 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 11.133 +{ 11.134 +#if defined(unix) || defined(__unix__) 11.135 + struct stat st; 11.136 +#endif 11.137 + unsigned int sdr; 11.138 + size_t filesize; 11.139 + FILE *fp; 11.140 + char *src; 11.141 + 11.142 + if(!(fp = fopen(fname, "r"))) { 11.143 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 11.144 + return 0; 11.145 + } 11.146 + 11.147 +#if defined(unix) || defined(__unix__) 11.148 + fstat(fileno(fp), &st); 11.149 + filesize = st.st_size; 11.150 +#else 11.151 + fseek(fp, 0, SEEK_END); 11.152 + filesize = ftell(fp); 11.153 + fseek(fp, 0, SEEK_SET); 11.154 +#endif /* unix */ 11.155 + 11.156 + if(!(src = malloc(filesize + 1))) { 11.157 + fclose(fp); 11.158 + return 0; 11.159 + } 11.160 + fread(src, 1, filesize, fp); 11.161 + src[filesize] = 0; 11.162 + fclose(fp); 11.163 + 11.164 + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); 11.165 + sdr = create_shader(src, sdr_type); 11.166 + 11.167 + free(src); 11.168 + return sdr; 11.169 +} 11.170 + 11.171 + 11.172 +unsigned int get_vertex_shader(const char *fname) 11.173 +{ 11.174 + return get_shader(fname, GL_VERTEX_SHADER); 11.175 +} 11.176 + 11.177 +unsigned int get_pixel_shader(const char *fname) 11.178 +{ 11.179 + return get_shader(fname, GL_FRAGMENT_SHADER); 11.180 +} 11.181 + 11.182 +unsigned int get_tessctl_shader(const char *fname) 11.183 +{ 11.184 + return get_shader(fname, GL_TESS_CONTROL_SHADER); 11.185 +} 11.186 + 11.187 +unsigned int get_tesseval_shader(const char *fname) 11.188 +{ 11.189 + return get_shader(fname, GL_TESS_EVALUATION_SHADER); 11.190 +} 11.191 + 11.192 +unsigned int get_geometry_shader(const char *fname) 11.193 +{ 11.194 + return get_shader(fname, GL_GEOMETRY_SHADER); 11.195 +} 11.196 + 11.197 +unsigned int get_shader(const char *fname, unsigned int sdr_type) 11.198 +{ 11.199 + unsigned int sdr; 11.200 + if(!(sdr = load_shader(fname, sdr_type))) { 11.201 + return 0; 11.202 + } 11.203 + return sdr; 11.204 +} 11.205 + 11.206 + 11.207 +/* ---- gpu programs ---- */ 11.208 + 11.209 +unsigned int create_program(void) 11.210 +{ 11.211 + unsigned int prog = glCreateProgram(); 11.212 + assert(glGetError() == GL_NO_ERROR); 11.213 + return prog; 11.214 +} 11.215 + 11.216 +unsigned int create_program_link(unsigned int sdr0, ...) 11.217 +{ 11.218 + unsigned int prog, sdr; 11.219 + va_list ap; 11.220 + 11.221 + if(!(prog = create_program())) { 11.222 + return 0; 11.223 + } 11.224 + 11.225 + attach_shader(prog, sdr0); 11.226 + if(glGetError()) { 11.227 + return 0; 11.228 + } 11.229 + 11.230 + va_start(ap, sdr0); 11.231 + while((sdr = va_arg(ap, unsigned int))) { 11.232 + attach_shader(prog, sdr); 11.233 + if(glGetError()) { 11.234 + return 0; 11.235 + } 11.236 + } 11.237 + va_end(ap); 11.238 + 11.239 + if(link_program(prog) == -1) { 11.240 + free_program(prog); 11.241 + return 0; 11.242 + } 11.243 + return prog; 11.244 +} 11.245 + 11.246 +unsigned int create_program_load(const char *vfile, const char *pfile) 11.247 +{ 11.248 + unsigned int vs = 0, ps = 0; 11.249 + 11.250 + if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) { 11.251 + return 0; 11.252 + } 11.253 + if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) { 11.254 + return 0; 11.255 + } 11.256 + return create_program_link(vs, ps, 0); 11.257 +} 11.258 + 11.259 +void free_program(unsigned int sdr) 11.260 +{ 11.261 + glDeleteProgram(sdr); 11.262 +} 11.263 + 11.264 +void attach_shader(unsigned int prog, unsigned int sdr) 11.265 +{ 11.266 + glAttachShader(prog, sdr); 11.267 + assert(glGetError() == GL_NO_ERROR); 11.268 +} 11.269 + 11.270 +int link_program(unsigned int prog) 11.271 +{ 11.272 + int linked, info_len, retval = 0; 11.273 + char *info_str = 0; 11.274 + 11.275 + glLinkProgram(prog); 11.276 + assert(glGetError() == GL_NO_ERROR); 11.277 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 11.278 + assert(glGetError() == GL_NO_ERROR); 11.279 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 11.280 + assert(glGetError() == GL_NO_ERROR); 11.281 + 11.282 + if(info_len) { 11.283 + if((info_str = malloc(info_len + 1))) { 11.284 + glGetProgramInfoLog(prog, info_len, 0, info_str); 11.285 + assert(glGetError() == GL_NO_ERROR); 11.286 + } 11.287 + } 11.288 + 11.289 + if(linked) { 11.290 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 11.291 + } else { 11.292 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 11.293 + retval = -1; 11.294 + } 11.295 + 11.296 + free(info_str); 11.297 + return retval; 11.298 +} 11.299 + 11.300 +int bind_program(unsigned int prog) 11.301 +{ 11.302 + GLenum err; 11.303 + 11.304 + glUseProgram(prog); 11.305 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 11.306 + /* maybe the program is not linked, try linking first */ 11.307 + if(err == GL_INVALID_OPERATION) { 11.308 + if(link_program(prog) == -1) { 11.309 + return -1; 11.310 + } 11.311 + glUseProgram(prog); 11.312 + return glGetError() == GL_NO_ERROR ? 0 : -1; 11.313 + } 11.314 + return -1; 11.315 + } 11.316 + return 0; 11.317 +} 11.318 + 11.319 +/* ugly but I'm not going to write the same bloody code over and over */ 11.320 +#define BEGIN_UNIFORM_CODE \ 11.321 + int loc, curr_prog; \ 11.322 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 11.323 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ 11.324 + return -1; \ 11.325 + } \ 11.326 + if((loc = glGetUniformLocation(prog, name)) != -1) 11.327 + 11.328 +#define END_UNIFORM_CODE \ 11.329 + if((unsigned int)curr_prog != prog) { \ 11.330 + bind_program(curr_prog); \ 11.331 + } \ 11.332 + return loc == -1 ? -1 : 0 11.333 + 11.334 +int set_uniform_int(unsigned int prog, const char *name, int val) 11.335 +{ 11.336 + BEGIN_UNIFORM_CODE { 11.337 + glUniform1i(loc, val); 11.338 + } 11.339 + END_UNIFORM_CODE; 11.340 +} 11.341 + 11.342 +int set_uniform_float(unsigned int prog, const char *name, float val) 11.343 +{ 11.344 + BEGIN_UNIFORM_CODE { 11.345 + glUniform1f(loc, val); 11.346 + } 11.347 + END_UNIFORM_CODE; 11.348 +} 11.349 + 11.350 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) 11.351 +{ 11.352 + BEGIN_UNIFORM_CODE { 11.353 + glUniform2f(loc, x, y); 11.354 + } 11.355 + END_UNIFORM_CODE; 11.356 +} 11.357 + 11.358 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 11.359 +{ 11.360 + BEGIN_UNIFORM_CODE { 11.361 + glUniform3f(loc, x, y, z); 11.362 + } 11.363 + END_UNIFORM_CODE; 11.364 +} 11.365 + 11.366 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 11.367 +{ 11.368 + BEGIN_UNIFORM_CODE { 11.369 + glUniform4f(loc, x, y, z, w); 11.370 + } 11.371 + END_UNIFORM_CODE; 11.372 +} 11.373 + 11.374 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 11.375 +{ 11.376 + BEGIN_UNIFORM_CODE { 11.377 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 11.378 + } 11.379 + END_UNIFORM_CODE; 11.380 +} 11.381 + 11.382 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 11.383 +{ 11.384 + BEGIN_UNIFORM_CODE { 11.385 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 11.386 + } 11.387 + END_UNIFORM_CODE; 11.388 +} 11.389 + 11.390 +int get_attrib_loc(unsigned int prog, const char *name) 11.391 +{ 11.392 + int loc, curr_prog; 11.393 + 11.394 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 11.395 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 11.396 + return -1; 11.397 + } 11.398 + 11.399 + loc = glGetAttribLocation(prog, (char*)name); 11.400 + 11.401 + if((unsigned int)curr_prog != prog) { 11.402 + bind_program(curr_prog); 11.403 + } 11.404 + return loc; 11.405 +} 11.406 + 11.407 +void set_attrib_float3(int attr_loc, float x, float y, float z) 11.408 +{ 11.409 + glVertexAttrib3f(attr_loc, x, y, z); 11.410 +} 11.411 + 11.412 +static const char *sdrtypestr(unsigned int sdrtype) 11.413 +{ 11.414 + switch(sdrtype) { 11.415 + case GL_VERTEX_SHADER: 11.416 + return "vertex"; 11.417 + case GL_FRAGMENT_SHADER: 11.418 + return "pixel"; 11.419 + case GL_TESS_CONTROL_SHADER: 11.420 + return "tessellation control"; 11.421 + case GL_TESS_EVALUATION_SHADER: 11.422 + return "tessellation evaluation"; 11.423 + case GL_GEOMETRY_SHADER: 11.424 + return "geometry"; 11.425 + 11.426 + default: 11.427 + break; 11.428 + } 11.429 + return "<unknown>"; 11.430 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/sdr.h Thu Oct 17 08:19:56 2013 +0300 12.3 @@ -0,0 +1,76 @@ 12.4 +/* 12.5 +Printblobs - halftoning display hack 12.6 +Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org> 12.7 + 12.8 +This program is free software: you can redistribute it and/or modify 12.9 +it under the terms of the GNU General Public License as published by 12.10 +the Free Software Foundation, either version 3 of the License, or 12.11 +(at your option) any later version. 12.12 + 12.13 +This program is distributed in the hope that it will be useful, 12.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 12.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.16 +GNU General Public License for more details. 12.17 + 12.18 +You should have received a copy of the GNU General Public License 12.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 12.20 +*/ 12.21 +#ifndef SDR_H_ 12.22 +#define SDR_H_ 12.23 + 12.24 +#ifdef __cplusplus 12.25 +extern "C" { 12.26 +#endif /* __cplusplus */ 12.27 + 12.28 +/* ---- shaders ---- */ 12.29 +unsigned int create_vertex_shader(const char *src); 12.30 +unsigned int create_pixel_shader(const char *src); 12.31 +unsigned int create_tessctl_shader(const char *src); 12.32 +unsigned int create_tesseval_shader(const char *src); 12.33 +unsigned int create_geometry_shader(const char *src); 12.34 +unsigned int create_shader(const char *src, unsigned int sdr_type); 12.35 +void free_shader(unsigned int sdr); 12.36 + 12.37 +unsigned int load_vertex_shader(const char *fname); 12.38 +unsigned int load_pixel_shader(const char *fname); 12.39 +unsigned int load_tessctl_shader(const char *fname); 12.40 +unsigned int load_tesseval_shader(const char *fname); 12.41 +unsigned int load_geometry_shader(const char *fname); 12.42 +unsigned int load_shader(const char *src, unsigned int sdr_type); 12.43 + 12.44 +unsigned int get_vertex_shader(const char *fname); 12.45 +unsigned int get_pixel_shader(const char *fname); 12.46 +unsigned int get_tessctl_shader(const char *fname); 12.47 +unsigned int get_tesseval_shader(const char *fname); 12.48 +unsigned int get_geometry_shader(const char *fname); 12.49 +unsigned int get_shader(const char *fname, unsigned int sdr_type); 12.50 + 12.51 +int add_shader(const char *fname, unsigned int sdr); 12.52 +int remove_shader(const char *fname); 12.53 + 12.54 +/* ---- gpu programs ---- */ 12.55 +unsigned int create_program(void); 12.56 +unsigned int create_program_link(unsigned int sdr0, ...); 12.57 +unsigned int create_program_load(const char *vfile, const char *pfile); 12.58 +void free_program(unsigned int sdr); 12.59 + 12.60 +void attach_shader(unsigned int prog, unsigned int sdr); 12.61 +int link_program(unsigned int prog); 12.62 +int bind_program(unsigned int prog); 12.63 + 12.64 +int set_uniform_int(unsigned int prog, const char *name, int val); 12.65 +int set_uniform_float(unsigned int prog, const char *name, float val); 12.66 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); 12.67 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 12.68 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 12.69 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); 12.70 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); 12.71 + 12.72 +int get_attrib_loc(unsigned int prog, const char *name); 12.73 +void set_attrib_float3(int attr_loc, float x, float y, float z); 12.74 + 12.75 +#ifdef __cplusplus 12.76 +} 12.77 +#endif /* __cplusplus */ 12.78 + 12.79 +#endif /* SDR_H_ */