# HG changeset patch # User John Tsiombikas # Date 1433980423 -10800 # Node ID c14613d27a3a10c256e30939a8ea503e069e9956 # Parent 94b8ef9b8caa0ded39c7da8d8b7dca7361fb1b66 writing a C++ shader class for this diff -r 94b8ef9b8caa -r c14613d27a3a src/game.c --- a/src/game.c Wed Jun 10 22:28:48 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -#include -#include -#include -#include -#include "opengl.h" -#include "game.h" -#include "camera.h" -#include "sdr.h" -#include "sanegl.h" -#include "texture.h" - -static void draw_quad(float hsz, float vsz, unsigned int sdr); - -static int win_width, win_height; -static float win_aspect; -static int video_width, video_height; -static float video_aspect; -static unsigned int sdrprog, sdrprog_test; -static int uloc_tex, uloc_test_tex; -static struct texture *test_tex; - -enum { ATTR_VERTEX, ATTR_TEXCOORD }; - -static const char *vsdr_source = - "attribute vec4 attr_vertex, attr_texcoord;\n" - "uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n" - "varying vec4 tex_coords;\n" - "void main()\n" - "{\n" - "\tmat4 mvp = matrix_projection * matrix_modelview;\n" - "\tgl_Position = mvp * attr_vertex;\n" - "\ttex_coords = matrix_texture * attr_texcoord;\n" - "}\n"; - -static const char *psdr_cam_source = - "#extension GL_OES_EGL_image_external : require\n" - "precision mediump float;\n" - "uniform samplerExternalOES tex;\n" - "varying vec4 tex_coords;\n" - "void main()\n" - "{\n" - "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" - "\tgl_FragColor = vec4(texel.xyz, 1.0);\n" - "}\n"; - -static const char *psdr_tex_source = - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "varying vec4 tex_coords;\n" - "void main()\n" - "{\n" - "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" - "\tgl_FragColor = texel;\n" - "}\n"; - -int game_init(void) -{ - unsigned int vsdr, psdr_cam, psdr_tex; - - //glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - glClearColor(0.4, 0.4, 0.4, 1); - - if(!(vsdr = create_vertex_shader(vsdr_source))) - return -1; - assert(glGetError() == GL_NO_ERROR); - if(!(psdr_cam = create_pixel_shader(psdr_cam_source))) - return -1; - assert(glGetError() == GL_NO_ERROR); - if(!(psdr_tex = create_pixel_shader(psdr_tex_source))) - return -1; - assert(glGetError() == GL_NO_ERROR); - if(!(sdrprog = create_program_link(vsdr, psdr_cam, 0))) { - fprintf(stderr, "failed to create shader program\n"); - return -1; - } - if(!(sdrprog_test = create_program_link(vsdr, psdr_tex, 0))) { - fprintf(stderr, "failed to create test shader program\n"); - return -1; - } - - glUseProgram(sdrprog); - glBindAttribLocation(sdrprog, ATTR_VERTEX, "attr_vertex"); - glBindAttribLocation(sdrprog, ATTR_TEXCOORD, "attr_texcoord"); - uloc_tex = glGetUniformLocation(sdrprog, "tex"); - glLinkProgram(sdrprog); - - glUseProgram(sdrprog_test); - glBindAttribLocation(sdrprog_test, ATTR_VERTEX, "attr_vertex"); - glBindAttribLocation(sdrprog_test, ATTR_TEXCOORD, "attr_texcoord"); - uloc_test_tex = glGetUniformLocation(sdrprog_test, "tex"); - glLinkProgram(sdrprog_test); - - if(!(test_tex = get_texture("data/opengl.png"))) { - return -1; - } - - cam_start_video(); - cam_video_size(&video_width, &video_height); - if(video_height) { - video_aspect = (float)video_width / (float)video_height; - } else { - video_aspect = 1.0; - } - - printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect); - return 0; -} - -void game_shutdown(void) -{ - cam_shutdown(); - free_program(sdrprog); -} - -void game_display(unsigned long msec) -{ - unsigned int tex; - const float *tex_matrix; - float xscale, yscale; - - cam_update(); - tex = cam_texture(); - tex_matrix = cam_texture_matrix(); - - //float tsec = (float)msec / 1000.0f; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - gl_matrix_mode(GL_MODELVIEW); - gl_load_identity(); - gl_matrix_mode(GL_TEXTURE); - gl_load_matrixf(tex_matrix); - - glUseProgram(sdrprog); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); - if(uloc_tex >= 0) { - glUniform1i(uloc_tex, 0); - } - - if(video_aspect > win_aspect) { - xscale = 1.0; - yscale = 1.0 / video_aspect; - } else { - xscale = video_aspect; - yscale = 1.0; - } - draw_quad(xscale, yscale, sdrprog); - - gl_matrix_mode(GL_TEXTURE); - gl_load_identity(); - gl_translatef(0, 1, 0); - gl_scalef(1, -1, 1); - gl_matrix_mode(GL_MODELVIEW); - gl_load_identity(); - gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1); - - glUseProgram(sdrprog_test); - glBindTexture(GL_TEXTURE_2D, test_tex->texid); - if(uloc_test_tex >= 0) { - glUniform1i(uloc_test_tex, 0); - } - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - draw_quad(0.5, 0.5, sdrprog_test); - - glDisable(GL_BLEND); -} - -static void draw_quad(float hsz, float vsz, unsigned int sdr) -{ - static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1}; - static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1}; - - gl_matrix_mode(GL_MODELVIEW); - gl_push_matrix(); - gl_scalef(hsz, vsz, 1); - - gl_apply_xform(sdr); - - glEnableVertexAttribArray(ATTR_VERTEX); - glEnableVertexAttribArray(ATTR_TEXCOORD); - glVertexAttribPointer(ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr); - glVertexAttribPointer(ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glDisableVertexAttribArray(ATTR_VERTEX); - glDisableVertexAttribArray(ATTR_TEXCOORD); - - gl_pop_matrix(); -} - -void game_reshape(int x, int y) -{ - win_width = x; - win_height = y; - win_aspect = y ? (float)x / (float)y : 1.0; - glViewport(0, 0, x, y); - - gl_matrix_mode(GL_PROJECTION); - gl_load_identity(); - gl_scalef((float)win_height / (float)win_width, 1, 1); -} - -void game_keyboard(int key, int pressed) -{ - if(!pressed) return; - - switch(key) { - case 27: - exit(0); - - default: - break; - } -} - -#define MAX_TOUCH_IDS 16 -static struct { - int bnstate[8]; - int prev_x, prev_y; -} mstate[MAX_TOUCH_IDS]; - -void game_mouse_button(int id, int bn, int pressed, int x, int y) -{ - if(id >= MAX_TOUCH_IDS) return; - - mstate[id].prev_x = x; - mstate[id].prev_y = y; - mstate[id].bnstate[bn] = pressed; -} - -void game_mouse_motion(int id, int x, int y) -{ - /* - int dx, dy, cx, cy; - - if(id >= MAX_TOUCH_IDS) return; - - cx = win_width / 2; - cy = win_height / 2; - - dx = x - mstate[id].prev_x; - dy = y - mstate[id].prev_y; - mstate[id].prev_x = x; - mstate[id].prev_y = y; - - if(!dx && !dy) return; - - if(mouselook || mstate[id].bnstate[0]) { - player_turn(&player, dx * 0.5, dy * 0.5); - } - if(mstate[id].bnstate[2]) { - dbg_cam_dist += 0.1 * dy; - if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; - } - - if(mouselook) { - warping_mouse = 1; - set_mouse_pos(cx, cy); - mstate[id].prev_x = cx; - mstate[id].prev_y = cy; - } - */ -} - diff -r 94b8ef9b8caa -r c14613d27a3a src/game.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/game.cc Thu Jun 11 02:53:43 2015 +0300 @@ -0,0 +1,270 @@ +#include +#include +#include +#include +#include "opengl.h" +#include "game.h" +#include "camera.h" +#include "sdr.h" +#include "sanegl.h" +#include "texture.h" + +static void draw_quad(float hsz, float vsz, unsigned int sdr); + +static int win_width, win_height; +static float win_aspect; +static int video_width, video_height; +static float video_aspect; +static unsigned int sdrprog, sdrprog_test; +static int uloc_tex, uloc_test_tex; +static struct texture *test_tex; + +enum { ATTR_VERTEX, ATTR_TEXCOORD }; + +static const char *vsdr_source = + "attribute vec4 attr_vertex, attr_texcoord;\n" + "uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n" + "varying vec4 tex_coords;\n" + "void main()\n" + "{\n" + "\tmat4 mvp = matrix_projection * matrix_modelview;\n" + "\tgl_Position = mvp * attr_vertex;\n" + "\ttex_coords = matrix_texture * attr_texcoord;\n" + "}\n"; + +static const char *psdr_cam_source = + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "uniform samplerExternalOES tex;\n" + "varying vec4 tex_coords;\n" + "void main()\n" + "{\n" + "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" + "\tgl_FragColor = vec4(texel.xyz, 1.0);\n" + "}\n"; + +static const char *psdr_tex_source = + "precision mediump float;\n" + "uniform sampler2D tex;\n" + "varying vec4 tex_coords;\n" + "void main()\n" + "{\n" + "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" + "\tgl_FragColor = texel;\n" + "}\n"; + +extern "C" int game_init(void) +{ + unsigned int vsdr, psdr_cam, psdr_tex; + + //glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glClearColor(0.4, 0.4, 0.4, 1); + + if(!(vsdr = create_vertex_shader(vsdr_source))) + return -1; + assert(glGetError() == GL_NO_ERROR); + if(!(psdr_cam = create_pixel_shader(psdr_cam_source))) + return -1; + assert(glGetError() == GL_NO_ERROR); + if(!(psdr_tex = create_pixel_shader(psdr_tex_source))) + return -1; + assert(glGetError() == GL_NO_ERROR); + if(!(sdrprog = create_program_link(vsdr, psdr_cam, 0))) { + fprintf(stderr, "failed to create shader program\n"); + return -1; + } + if(!(sdrprog_test = create_program_link(vsdr, psdr_tex, 0))) { + fprintf(stderr, "failed to create test shader program\n"); + return -1; + } + + glUseProgram(sdrprog); + glBindAttribLocation(sdrprog, ATTR_VERTEX, "attr_vertex"); + glBindAttribLocation(sdrprog, ATTR_TEXCOORD, "attr_texcoord"); + uloc_tex = glGetUniformLocation(sdrprog, "tex"); + glLinkProgram(sdrprog); + + glUseProgram(sdrprog_test); + glBindAttribLocation(sdrprog_test, ATTR_VERTEX, "attr_vertex"); + glBindAttribLocation(sdrprog_test, ATTR_TEXCOORD, "attr_texcoord"); + uloc_test_tex = glGetUniformLocation(sdrprog_test, "tex"); + glLinkProgram(sdrprog_test); + + if(!(test_tex = get_texture("data/opengl.png"))) { + return -1; + } + + cam_start_video(); + cam_video_size(&video_width, &video_height); + if(video_height) { + video_aspect = (float)video_width / (float)video_height; + } else { + video_aspect = 1.0; + } + + printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect); + return 0; +} + +extern "C" void game_shutdown(void) +{ + cam_shutdown(); + free_program(sdrprog); +} + +extern "C" void game_display(unsigned long msec) +{ + unsigned int tex; + const float *tex_matrix; + float xscale, yscale; + + cam_update(); + tex = cam_texture(); + tex_matrix = cam_texture_matrix(); + + //float tsec = (float)msec / 1000.0f; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + gl_matrix_mode(GL_MODELVIEW); + gl_load_identity(); + gl_matrix_mode(GL_TEXTURE); + gl_load_matrixf(tex_matrix); + + glUseProgram(sdrprog); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); + if(uloc_tex >= 0) { + glUniform1i(uloc_tex, 0); + } + + if(video_aspect > win_aspect) { + xscale = 1.0; + yscale = 1.0 / video_aspect; + } else { + xscale = video_aspect; + yscale = 1.0; + } + draw_quad(xscale, yscale, sdrprog); + + gl_matrix_mode(GL_TEXTURE); + gl_load_identity(); + gl_translatef(0, 1, 0); + gl_scalef(1, -1, 1); + gl_matrix_mode(GL_MODELVIEW); + gl_load_identity(); + gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1); + + glUseProgram(sdrprog_test); + glBindTexture(GL_TEXTURE_2D, test_tex->texid); + if(uloc_test_tex >= 0) { + glUniform1i(uloc_test_tex, 0); + } + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + draw_quad(0.5, 0.5, sdrprog_test); + + glDisable(GL_BLEND); +} + +static void draw_quad(float hsz, float vsz, unsigned int sdr) +{ + static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1}; + static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1}; + + gl_matrix_mode(GL_MODELVIEW); + gl_push_matrix(); + gl_scalef(hsz, vsz, 1); + + gl_apply_xform(sdr); + + glEnableVertexAttribArray(ATTR_VERTEX); + glEnableVertexAttribArray(ATTR_TEXCOORD); + glVertexAttribPointer(ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr); + glVertexAttribPointer(ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(ATTR_VERTEX); + glDisableVertexAttribArray(ATTR_TEXCOORD); + + gl_pop_matrix(); +} + +extern "C" void game_reshape(int x, int y) +{ + win_width = x; + win_height = y; + win_aspect = y ? (float)x / (float)y : 1.0; + glViewport(0, 0, x, y); + + gl_matrix_mode(GL_PROJECTION); + gl_load_identity(); + gl_scalef((float)win_height / (float)win_width, 1, 1); +} + +extern "C" void game_keyboard(int key, int pressed) +{ + if(!pressed) return; + + switch(key) { + case 27: + exit(0); + + default: + break; + } +} + +#define MAX_TOUCH_IDS 16 +static struct { + int bnstate[8]; + int prev_x, prev_y; +} mstate[MAX_TOUCH_IDS]; + +extern "C" void game_mouse_button(int id, int bn, int pressed, int x, int y) +{ + if(id >= MAX_TOUCH_IDS) return; + + mstate[id].prev_x = x; + mstate[id].prev_y = y; + mstate[id].bnstate[bn] = pressed; +} + +extern "C" void game_mouse_motion(int id, int x, int y) +{ + /* + int dx, dy, cx, cy; + + if(id >= MAX_TOUCH_IDS) return; + + cx = win_width / 2; + cy = win_height / 2; + + dx = x - mstate[id].prev_x; + dy = y - mstate[id].prev_y; + mstate[id].prev_x = x; + mstate[id].prev_y = y; + + if(!dx && !dy) return; + + if(mouselook || mstate[id].bnstate[0]) { + player_turn(&player, dx * 0.5, dy * 0.5); + } + if(mstate[id].bnstate[2]) { + dbg_cam_dist += 0.1 * dy; + if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; + } + + if(mouselook) { + warping_mouse = 1; + set_mouse_pos(cx, cy); + mstate[id].prev_x = cx; + mstate[id].prev_y = cy; + } + */ +} + diff -r 94b8ef9b8caa -r c14613d27a3a src/game.h --- a/src/game.h Wed Jun 10 22:28:48 2015 +0300 +++ b/src/game.h Thu Jun 11 02:53:43 2015 +0300 @@ -1,6 +1,10 @@ #ifndef GAME_H_ #define GAME_H_ +#ifdef __cplusplus +extern "C" { +#endif + int game_init(void); void game_shutdown(void); @@ -15,5 +19,9 @@ void set_mouse_pos(int x, int y); void set_mouse_cursor(int enable); +#ifdef __cplusplus +} +#endif + #endif /* GAME_H_ */ diff -r 94b8ef9b8caa -r c14613d27a3a src/shader.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/shader.cc Thu Jun 11 02:53:43 2015 +0300 @@ -0,0 +1,182 @@ +#include +#include +#include +#include "shader.h" +#include "sdr.h" +#include "opengl.h" + +std::map sdrdb; + +SdrProg::SdrProg() +{ + prog = 0; + valid = false; +} + +SdrProg::~SdrProg() +{ + destroy(); +} + +void SdrProg::create() +{ + destroy(); + prog = glCreateProgram(); +} + +void SdrProg::destroy() +{ + if(prog) { + glDeleteProgram(prog); + } + valid = false; + + for(size_t i=0; i::const_iterator it = sdrdb.find(name); + if(it != sdrdb.end()) { + return it->second; + } + + unsigned int sdr = load_shader(name, type); + if(!sdr) { + return 0; + } + + sdrdb[name] = sdr; + return sdr; +} diff -r 94b8ef9b8caa -r c14613d27a3a src/shader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/shader.h Thu Jun 11 02:53:43 2015 +0300 @@ -0,0 +1,36 @@ +#ifndef SHADER_H_ +#define SHADER_H_ + +#include + +class SdrProg { +private: + std::vector priv_sdr; + unsigned int prog; + mutable bool valid; + +public: + SdrProg(); + ~SdrProg(); + + void create(); + void destroy(); + + bool attach_shader(unsigned int sdr); + + bool create(unsigned int vsdr, unsigned int psdr); + bool create(const char *vsrc, const char *psrc); + bool load(const char *vfname, const char *pfname); + + bool link() const; + + int get_uniform(const char *name) const; + int get_attrib(const char *name) const; + bool bind_attrib(const char *name, int loc) const; + + bool bind() const; +}; + +unsigned int get_shader(const char *name, unsigned int type); + +#endif /* SHADER_H_ */