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_ */