# HG changeset patch # User John Tsiombikas # Date 1381987196 -10800 # Node ID 26513fdda566a103f798d9203e7d74a42a2eb9bb initial commit diff -r 000000000000 -r 26513fdda566 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,4 @@ +\.o$ +\.d$ +\.swp$ +^sdrconvol$ diff -r 000000000000 -r 26513fdda566 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,23 @@ +src = $(wildcard src/*.cc) +csrc = $(wildcard src/*.c) +obj = $(src:.cc=.o) $(csrc:.c=.o) +bin = sdrconvol + +CC = clang +CXX = clang++ +CFLAGS = -pedantic -Wall -g +CXXFLAGS = -pedantic -Wall -g +LDFLAGS = $(libgl) + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT -lGLEW +else + libgl = -lGL -lGLU -lglut -lGLEW +endif + +$(bin): $(obj) + $(CXX) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r 26513fdda566 RUN --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RUN Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,3 @@ +#!/bin/sh + +__GL_SYNC_TO_VBLANK=0 vblank_mode=0 frapix ./sdrconvol $* diff -r 000000000000 -r 26513fdda566 sdr/blur.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/blur.glsl Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,25 @@ +uniform sampler2D tex; +uniform vec2 size, texsize; + +#define KSZ 31 +#define HALF_KSZ 15 +#define SCALE float(KSZ * KSZ) + +void main() +{ + float pixw = 1.0 / texsize.x; + float pixh = 1.0 / texsize.y; + + vec3 texel = vec3(0.0, 0.0, 0.0); + for(int i=0; i +#include +#include +#include + +#include +#ifndef __APPLE__ +#include +#else +#include +#endif +#include "rtarg.h" +#include "sdr.h" + +enum { + BLUR_REG, + BLUR_SEP, + + NUM_BLUR_TYPES +}; + +static bool init(); +static void cleanup(); +static void disp(); +static void print_string(const char *str); +static void idle(); +static void reshape(int x, int y); +static void keyb(unsigned char key, int x, int y); +static void mouse(int bn, int st, int x, int y); +static void motion(int x, int y); + +static int win_width, win_height; +static float cam_theta, cam_phi, cam_dist = 8; + +static RenderTarget *rtarg, *tmp_rtarg; +static unsigned int sdrblur, sdr_hblur, sdr_vblur; + +static int blur_type = BLUR_REG; + + +int main(int argc, char **argv) +{ + glutInitWindowSize(1280, 800); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow("convolution"); + + glutDisplayFunc(disp); + glutIdleFunc(idle); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + if(!init()) { + return 1; + } + atexit(cleanup); + + glutMainLoop(); + return 0; +} + +static bool init() +{ + glewInit(); + + glClearColor(0.1, 0.1, 0.1, 1); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + rtarg = new RenderTarget; + tmp_rtarg = new RenderTarget; + + if(!(sdrblur = create_program_load("sdr/vert.glsl", "sdr/blur.glsl"))) { + return false; + } + if(!(sdr_hblur = create_program_load("sdr/vert.glsl", "sdr/hblur.glsl"))) { + return false; + } + if(!(sdr_vblur = create_program_load("sdr/vert.glsl", "sdr/vblur.glsl"))) { + return false; + } + + return true; +} + +static void cleanup() +{ + delete rtarg; + delete tmp_rtarg; +} + +static void disp() +{ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); + + bind_render_target(rtarg); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glFrontFace(GL_CW); + glutSolidTeapot(1.0); + glFrontFace(GL_CCW); + + if(blur_type == BLUR_SEP) { + // render with horizontal blur into tmp_rtarg + bind_render_target(tmp_rtarg); + + set_uniform_float2(sdr_hblur, "size", rtarg->xsz, rtarg->ysz); + set_uniform_float2(sdr_hblur, "texsize", rtarg->tex_xsz, rtarg->tex_ysz); + bind_program(sdr_hblur); + + rtarg->display(); + + // render with vertical blur into the regular framebuffer + bind_render_target(0); + + set_uniform_float2(sdr_vblur, "size", tmp_rtarg->xsz, tmp_rtarg->ysz); + set_uniform_float2(sdr_vblur, "texsize", tmp_rtarg->tex_xsz, tmp_rtarg->tex_ysz); + bind_program(sdr_vblur); + + tmp_rtarg->display(); + + } else { + // render with the full blur into the regular framebuffer + bind_render_target(0); + + // display the rendered image + set_uniform_float2(sdrblur, "size", rtarg->xsz, rtarg->ysz); + set_uniform_float2(sdrblur, "texsize", rtarg->tex_xsz, rtarg->tex_ysz); + bind_program(sdrblur); + + rtarg->display(); + } + bind_program(0); + + print_string(blur_type == BLUR_REG ? "Regular blur" : "Seperable blur"); + + glutSwapBuffers(); + assert(glGetError() == GL_NO_ERROR); +} + +static void print_string(const char *str) +{ + glPushAttrib(GL_ENABLE_BIT); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, win_width, 0, win_height, -1, 1); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glRasterPos2f(1, 1); + glColor3f(1, 1, 0); + while(*str) { + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *str++); + } + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); +} + +static void idle() +{ + glutPostRedisplay(); +} + +static void reshape(int x, int y) +{ + win_width = x; + win_height = y; + + glViewport(0, 0, x, y); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); + + rtarg->reshape(x, y); + tmp_rtarg->reshape(x, y); +} + +static void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + + case ' ': + blur_type = (blur_type + 1) % NUM_BLUR_TYPES; + break; + } +} + + +static bool bnstate[32]; +static int prev_x, prev_y; + +static void mouse(int bn, int st, int x, int y) +{ + prev_x = x; + prev_y = y; + bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN; +} + +static void motion(int x, int y) +{ + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(bnstate[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; + } + if(bnstate[2]) { + cam_dist -= dy * 0.1; + + if(cam_dist < 0) cam_dist = 0; + } +} diff -r 000000000000 -r 26513fdda566 src/rtarg.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rtarg.cc Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,136 @@ +#include +#include "rtarg.h" + +RenderTarget::RenderTarget() +{ + fbo = tex = zbuf = 0; +} + +RenderTarget::~RenderTarget() +{ + destroy(); +} + +bool RenderTarget::create(int xsz, int ysz) +{ + destroy(); + + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + this->xsz = xsz; + this->ysz = ysz; + tex_xsz = next_pow2(xsz); + tex_ysz = next_pow2(ysz); + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + + glGenRenderbuffers(1, &zbuf); + glBindRenderbuffer(GL_RENDERBUFFER, zbuf); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return true; +} + +void RenderTarget::destroy() +{ + if(fbo) { + glDeleteFramebuffers(1, &fbo); + } + if(tex) { + glDeleteTextures(1, &tex); + } + if(zbuf) { + glDeleteRenderbuffers(1, &zbuf); + } +} + +void RenderTarget::reshape(int new_xsz, int new_ysz) +{ + if(!fbo) { + create(new_xsz, new_ysz); + return; + } + + xsz = new_xsz; + ysz = new_ysz; + + int new_txsz = next_pow2(new_xsz); + int new_tysz = next_pow2(new_ysz); + + if(tex_xsz >= new_txsz && tex_ysz >= new_tysz) { + return; + } + + tex_xsz = new_txsz; + tex_ysz = new_tysz; + + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + glBindRenderbuffer(GL_RENDERBUFFER, zbuf); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); +} + +void RenderTarget::display() const +{ + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + + float max_u = (float)xsz / (float)tex_xsz; + float max_v = (float)ysz / (float)tex_ysz; + + glBegin(GL_QUADS); + glColor3f(1, 1, 1); + glTexCoord2f(0, 0); + glVertex2f(-1, -1); + glTexCoord2f(max_u, 0); + glVertex2f(1, -1); + glTexCoord2f(max_u, max_v); + glVertex2f(1, 1); + glTexCoord2f(0, max_v); + glVertex2f(-1, 1); + glEnd(); + + glPopAttrib(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + +void bind_render_target(const RenderTarget *rtarg) +{ + glBindFramebuffer(GL_FRAMEBUFFER, rtarg ? rtarg->fbo : 0); +} + +int next_pow2(int x) +{ + x--; + x = (x >> 1) | x; + x = (x >> 2) | x; + x = (x >> 4) | x; + x = (x >> 8) | x; + x = (x >> 16) | x; + return x + 1; +} diff -r 000000000000 -r 26513fdda566 src/rtarg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rtarg.h Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,22 @@ +#ifndef RTARG_H_ +#define RTARG_H_ + +class RenderTarget { +public: + int xsz, ysz, tex_xsz, tex_ysz; + unsigned int fbo, tex, zbuf; + + RenderTarget(); + ~RenderTarget(); + + bool create(int xsz, int ysz); + void destroy(); + void reshape(int xsz, int ysz); + + void display() const; +}; + +void bind_render_target(const RenderTarget *rtarg); +int next_pow2(int x); + +#endif // RTARG_H_ diff -r 000000000000 -r 26513fdda566 src/sdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdr.c Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,427 @@ +/* +Printblobs - halftoning display hack +Copyright (C) 2013 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include +#include +#include +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) +#include +#include +#endif /* unix */ + +#include "sdr.h" + +static const char *sdrtypestr(unsigned int sdrtype); + +unsigned int create_vertex_shader(const char *src) +{ + return create_shader(src, GL_VERTEX_SHADER); +} + +unsigned int create_pixel_shader(const char *src) +{ + return create_shader(src, GL_FRAGMENT_SHADER); +} + +unsigned int create_tessctl_shader(const char *src) +{ + return create_shader(src, GL_TESS_CONTROL_SHADER); +} + +unsigned int create_tesseval_shader(const char *src) +{ + return create_shader(src, GL_TESS_EVALUATION_SHADER); +} + +unsigned int create_geometry_shader(const char *src) +{ + return create_shader(src, GL_GEOMETRY_SHADER); +} + +unsigned int create_shader(const char *src, unsigned int sdr_type) +{ + unsigned int sdr; + int success, info_len; + char *info_str = 0; + GLenum err; + + sdr = glCreateShader(sdr_type); + assert(glGetError() == GL_NO_ERROR); + glShaderSource(sdr, 1, &src, 0); + err = glGetError(); + assert(err == GL_NO_ERROR); + glCompileShader(sdr); + assert(glGetError() == GL_NO_ERROR); + + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); + assert(glGetError() == GL_NO_ERROR); + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); + assert(glGetError() == GL_NO_ERROR); + + if(info_len) { + if((info_str = malloc(info_len + 1))) { + glGetShaderInfoLog(sdr, info_len, 0, info_str); + assert(glGetError() == GL_NO_ERROR); + } + } + + if(success) { + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); + } else { + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); + glDeleteShader(sdr); + sdr = 0; + } + + free(info_str); + return sdr; +} + +void free_shader(unsigned int sdr) +{ + glDeleteShader(sdr); +} + +unsigned int load_vertex_shader(const char *fname) +{ + return load_shader(fname, GL_VERTEX_SHADER); +} + +unsigned int load_pixel_shader(const char *fname) +{ + return load_shader(fname, GL_FRAGMENT_SHADER); +} + +unsigned int load_tessctl_shader(const char *fname) +{ + return load_shader(fname, GL_TESS_CONTROL_SHADER); +} + +unsigned int load_tesseval_shader(const char *fname) +{ + return load_shader(fname, GL_TESS_EVALUATION_SHADER); +} + +unsigned int load_geometry_shader(const char *fname) +{ + return load_shader(fname, GL_GEOMETRY_SHADER); +} + +unsigned int load_shader(const char *fname, unsigned int sdr_type) +{ +#if defined(unix) || defined(__unix__) + struct stat st; +#endif + unsigned int sdr; + size_t filesize; + FILE *fp; + char *src; + + if(!(fp = fopen(fname, "r"))) { + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); + return 0; + } + +#if defined(unix) || defined(__unix__) + fstat(fileno(fp), &st); + filesize = st.st_size; +#else + fseek(fp, 0, SEEK_END); + filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); +#endif /* unix */ + + if(!(src = malloc(filesize + 1))) { + fclose(fp); + return 0; + } + fread(src, 1, filesize, fp); + src[filesize] = 0; + fclose(fp); + + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); + sdr = create_shader(src, sdr_type); + + free(src); + return sdr; +} + + +unsigned int get_vertex_shader(const char *fname) +{ + return get_shader(fname, GL_VERTEX_SHADER); +} + +unsigned int get_pixel_shader(const char *fname) +{ + return get_shader(fname, GL_FRAGMENT_SHADER); +} + +unsigned int get_tessctl_shader(const char *fname) +{ + return get_shader(fname, GL_TESS_CONTROL_SHADER); +} + +unsigned int get_tesseval_shader(const char *fname) +{ + return get_shader(fname, GL_TESS_EVALUATION_SHADER); +} + +unsigned int get_geometry_shader(const char *fname) +{ + return get_shader(fname, GL_GEOMETRY_SHADER); +} + +unsigned int get_shader(const char *fname, unsigned int sdr_type) +{ + unsigned int sdr; + if(!(sdr = load_shader(fname, sdr_type))) { + return 0; + } + return sdr; +} + + +/* ---- gpu programs ---- */ + +unsigned int create_program(void) +{ + unsigned int prog = glCreateProgram(); + assert(glGetError() == GL_NO_ERROR); + return prog; +} + +unsigned int create_program_link(unsigned int sdr0, ...) +{ + unsigned int prog, sdr; + va_list ap; + + if(!(prog = create_program())) { + return 0; + } + + attach_shader(prog, sdr0); + if(glGetError()) { + return 0; + } + + va_start(ap, sdr0); + while((sdr = va_arg(ap, unsigned int))) { + attach_shader(prog, sdr); + if(glGetError()) { + return 0; + } + } + va_end(ap); + + if(link_program(prog) == -1) { + free_program(prog); + return 0; + } + return prog; +} + +unsigned int create_program_load(const char *vfile, const char *pfile) +{ + unsigned int vs = 0, ps = 0; + + if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) { + return 0; + } + if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) { + return 0; + } + return create_program_link(vs, ps, 0); +} + +void free_program(unsigned int sdr) +{ + glDeleteProgram(sdr); +} + +void attach_shader(unsigned int prog, unsigned int sdr) +{ + glAttachShader(prog, sdr); + assert(glGetError() == GL_NO_ERROR); +} + +int link_program(unsigned int prog) +{ + int linked, info_len, retval = 0; + char *info_str = 0; + + glLinkProgram(prog); + assert(glGetError() == GL_NO_ERROR); + glGetProgramiv(prog, GL_LINK_STATUS, &linked); + assert(glGetError() == GL_NO_ERROR); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); + assert(glGetError() == GL_NO_ERROR); + + if(info_len) { + if((info_str = malloc(info_len + 1))) { + glGetProgramInfoLog(prog, info_len, 0, info_str); + assert(glGetError() == GL_NO_ERROR); + } + } + + if(linked) { + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); + } else { + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); + retval = -1; + } + + free(info_str); + return retval; +} + +int bind_program(unsigned int prog) +{ + GLenum err; + + glUseProgram(prog); + if(prog && (err = glGetError()) != GL_NO_ERROR) { + /* maybe the program is not linked, try linking first */ + if(err == GL_INVALID_OPERATION) { + if(link_program(prog) == -1) { + return -1; + } + glUseProgram(prog); + return glGetError() == GL_NO_ERROR ? 0 : -1; + } + return -1; + } + return 0; +} + +/* ugly but I'm not going to write the same bloody code over and over */ +#define BEGIN_UNIFORM_CODE \ + int loc, curr_prog; \ + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ + return -1; \ + } \ + if((loc = glGetUniformLocation(prog, name)) != -1) + +#define END_UNIFORM_CODE \ + if((unsigned int)curr_prog != prog) { \ + bind_program(curr_prog); \ + } \ + return loc == -1 ? -1 : 0 + +int set_uniform_int(unsigned int prog, const char *name, int val) +{ + BEGIN_UNIFORM_CODE { + glUniform1i(loc, val); + } + END_UNIFORM_CODE; +} + +int set_uniform_float(unsigned int prog, const char *name, float val) +{ + BEGIN_UNIFORM_CODE { + glUniform1f(loc, val); + } + END_UNIFORM_CODE; +} + +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) +{ + BEGIN_UNIFORM_CODE { + glUniform2f(loc, x, y); + } + END_UNIFORM_CODE; +} + +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) +{ + BEGIN_UNIFORM_CODE { + glUniform3f(loc, x, y, z); + } + END_UNIFORM_CODE; +} + +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) +{ + BEGIN_UNIFORM_CODE { + glUniform4f(loc, x, y, z, w); + } + END_UNIFORM_CODE; +} + +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) +{ + BEGIN_UNIFORM_CODE { + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); + } + END_UNIFORM_CODE; +} + +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) +{ + BEGIN_UNIFORM_CODE { + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); + } + END_UNIFORM_CODE; +} + +int get_attrib_loc(unsigned int prog, const char *name) +{ + int loc, curr_prog; + + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { + return -1; + } + + loc = glGetAttribLocation(prog, (char*)name); + + if((unsigned int)curr_prog != prog) { + bind_program(curr_prog); + } + return loc; +} + +void set_attrib_float3(int attr_loc, float x, float y, float z) +{ + glVertexAttrib3f(attr_loc, x, y, z); +} + +static const char *sdrtypestr(unsigned int sdrtype) +{ + switch(sdrtype) { + case GL_VERTEX_SHADER: + return "vertex"; + case GL_FRAGMENT_SHADER: + return "pixel"; + case GL_TESS_CONTROL_SHADER: + return "tessellation control"; + case GL_TESS_EVALUATION_SHADER: + return "tessellation evaluation"; + case GL_GEOMETRY_SHADER: + return "geometry"; + + default: + break; + } + return ""; +} diff -r 000000000000 -r 26513fdda566 src/sdr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdr.h Thu Oct 17 08:19:56 2013 +0300 @@ -0,0 +1,76 @@ +/* +Printblobs - halftoning display hack +Copyright (C) 2013 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef SDR_H_ +#define SDR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* ---- shaders ---- */ +unsigned int create_vertex_shader(const char *src); +unsigned int create_pixel_shader(const char *src); +unsigned int create_tessctl_shader(const char *src); +unsigned int create_tesseval_shader(const char *src); +unsigned int create_geometry_shader(const char *src); +unsigned int create_shader(const char *src, unsigned int sdr_type); +void free_shader(unsigned int sdr); + +unsigned int load_vertex_shader(const char *fname); +unsigned int load_pixel_shader(const char *fname); +unsigned int load_tessctl_shader(const char *fname); +unsigned int load_tesseval_shader(const char *fname); +unsigned int load_geometry_shader(const char *fname); +unsigned int load_shader(const char *src, unsigned int sdr_type); + +unsigned int get_vertex_shader(const char *fname); +unsigned int get_pixel_shader(const char *fname); +unsigned int get_tessctl_shader(const char *fname); +unsigned int get_tesseval_shader(const char *fname); +unsigned int get_geometry_shader(const char *fname); +unsigned int get_shader(const char *fname, unsigned int sdr_type); + +int add_shader(const char *fname, unsigned int sdr); +int remove_shader(const char *fname); + +/* ---- gpu programs ---- */ +unsigned int create_program(void); +unsigned int create_program_link(unsigned int sdr0, ...); +unsigned int create_program_load(const char *vfile, const char *pfile); +void free_program(unsigned int sdr); + +void attach_shader(unsigned int prog, unsigned int sdr); +int link_program(unsigned int prog); +int bind_program(unsigned int prog); + +int set_uniform_int(unsigned int prog, const char *name, int val); +int set_uniform_float(unsigned int prog, const char *name, float val); +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); + +int get_attrib_loc(unsigned int prog, const char *name); +void set_attrib_float3(int attr_loc, float x, float y, float z); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SDR_H_ */