3dphotoshoot
changeset 20:c14613d27a3a
writing a C++ shader class for this
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 11 Jun 2015 02:53:43 +0300 |
parents | 94b8ef9b8caa |
children | 4ca4e3c5a754 |
files | src/game.c src/game.cc src/game.h src/shader.cc src/shader.h |
diffstat | 5 files changed, 496 insertions(+), 270 deletions(-) [+] |
line diff
1.1 --- a/src/game.c Wed Jun 10 22:28:48 2015 +0300 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,270 +0,0 @@ 1.4 -#include <stdio.h> 1.5 -#include <stdlib.h> 1.6 -#include <math.h> 1.7 -#include <assert.h> 1.8 -#include "opengl.h" 1.9 -#include "game.h" 1.10 -#include "camera.h" 1.11 -#include "sdr.h" 1.12 -#include "sanegl.h" 1.13 -#include "texture.h" 1.14 - 1.15 -static void draw_quad(float hsz, float vsz, unsigned int sdr); 1.16 - 1.17 -static int win_width, win_height; 1.18 -static float win_aspect; 1.19 -static int video_width, video_height; 1.20 -static float video_aspect; 1.21 -static unsigned int sdrprog, sdrprog_test; 1.22 -static int uloc_tex, uloc_test_tex; 1.23 -static struct texture *test_tex; 1.24 - 1.25 -enum { ATTR_VERTEX, ATTR_TEXCOORD }; 1.26 - 1.27 -static const char *vsdr_source = 1.28 - "attribute vec4 attr_vertex, attr_texcoord;\n" 1.29 - "uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n" 1.30 - "varying vec4 tex_coords;\n" 1.31 - "void main()\n" 1.32 - "{\n" 1.33 - "\tmat4 mvp = matrix_projection * matrix_modelview;\n" 1.34 - "\tgl_Position = mvp * attr_vertex;\n" 1.35 - "\ttex_coords = matrix_texture * attr_texcoord;\n" 1.36 - "}\n"; 1.37 - 1.38 -static const char *psdr_cam_source = 1.39 - "#extension GL_OES_EGL_image_external : require\n" 1.40 - "precision mediump float;\n" 1.41 - "uniform samplerExternalOES tex;\n" 1.42 - "varying vec4 tex_coords;\n" 1.43 - "void main()\n" 1.44 - "{\n" 1.45 - "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" 1.46 - "\tgl_FragColor = vec4(texel.xyz, 1.0);\n" 1.47 - "}\n"; 1.48 - 1.49 -static const char *psdr_tex_source = 1.50 - "precision mediump float;\n" 1.51 - "uniform sampler2D tex;\n" 1.52 - "varying vec4 tex_coords;\n" 1.53 - "void main()\n" 1.54 - "{\n" 1.55 - "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" 1.56 - "\tgl_FragColor = texel;\n" 1.57 - "}\n"; 1.58 - 1.59 -int game_init(void) 1.60 -{ 1.61 - unsigned int vsdr, psdr_cam, psdr_tex; 1.62 - 1.63 - //glEnable(GL_DEPTH_TEST); 1.64 - glEnable(GL_CULL_FACE); 1.65 - 1.66 - glClearColor(0.4, 0.4, 0.4, 1); 1.67 - 1.68 - if(!(vsdr = create_vertex_shader(vsdr_source))) 1.69 - return -1; 1.70 - assert(glGetError() == GL_NO_ERROR); 1.71 - if(!(psdr_cam = create_pixel_shader(psdr_cam_source))) 1.72 - return -1; 1.73 - assert(glGetError() == GL_NO_ERROR); 1.74 - if(!(psdr_tex = create_pixel_shader(psdr_tex_source))) 1.75 - return -1; 1.76 - assert(glGetError() == GL_NO_ERROR); 1.77 - if(!(sdrprog = create_program_link(vsdr, psdr_cam, 0))) { 1.78 - fprintf(stderr, "failed to create shader program\n"); 1.79 - return -1; 1.80 - } 1.81 - if(!(sdrprog_test = create_program_link(vsdr, psdr_tex, 0))) { 1.82 - fprintf(stderr, "failed to create test shader program\n"); 1.83 - return -1; 1.84 - } 1.85 - 1.86 - glUseProgram(sdrprog); 1.87 - glBindAttribLocation(sdrprog, ATTR_VERTEX, "attr_vertex"); 1.88 - glBindAttribLocation(sdrprog, ATTR_TEXCOORD, "attr_texcoord"); 1.89 - uloc_tex = glGetUniformLocation(sdrprog, "tex"); 1.90 - glLinkProgram(sdrprog); 1.91 - 1.92 - glUseProgram(sdrprog_test); 1.93 - glBindAttribLocation(sdrprog_test, ATTR_VERTEX, "attr_vertex"); 1.94 - glBindAttribLocation(sdrprog_test, ATTR_TEXCOORD, "attr_texcoord"); 1.95 - uloc_test_tex = glGetUniformLocation(sdrprog_test, "tex"); 1.96 - glLinkProgram(sdrprog_test); 1.97 - 1.98 - if(!(test_tex = get_texture("data/opengl.png"))) { 1.99 - return -1; 1.100 - } 1.101 - 1.102 - cam_start_video(); 1.103 - cam_video_size(&video_width, &video_height); 1.104 - if(video_height) { 1.105 - video_aspect = (float)video_width / (float)video_height; 1.106 - } else { 1.107 - video_aspect = 1.0; 1.108 - } 1.109 - 1.110 - printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect); 1.111 - return 0; 1.112 -} 1.113 - 1.114 -void game_shutdown(void) 1.115 -{ 1.116 - cam_shutdown(); 1.117 - free_program(sdrprog); 1.118 -} 1.119 - 1.120 -void game_display(unsigned long msec) 1.121 -{ 1.122 - unsigned int tex; 1.123 - const float *tex_matrix; 1.124 - float xscale, yscale; 1.125 - 1.126 - cam_update(); 1.127 - tex = cam_texture(); 1.128 - tex_matrix = cam_texture_matrix(); 1.129 - 1.130 - //float tsec = (float)msec / 1000.0f; 1.131 - 1.132 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.133 - 1.134 - gl_matrix_mode(GL_MODELVIEW); 1.135 - gl_load_identity(); 1.136 - gl_matrix_mode(GL_TEXTURE); 1.137 - gl_load_matrixf(tex_matrix); 1.138 - 1.139 - glUseProgram(sdrprog); 1.140 - glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); 1.141 - if(uloc_tex >= 0) { 1.142 - glUniform1i(uloc_tex, 0); 1.143 - } 1.144 - 1.145 - if(video_aspect > win_aspect) { 1.146 - xscale = 1.0; 1.147 - yscale = 1.0 / video_aspect; 1.148 - } else { 1.149 - xscale = video_aspect; 1.150 - yscale = 1.0; 1.151 - } 1.152 - draw_quad(xscale, yscale, sdrprog); 1.153 - 1.154 - gl_matrix_mode(GL_TEXTURE); 1.155 - gl_load_identity(); 1.156 - gl_translatef(0, 1, 0); 1.157 - gl_scalef(1, -1, 1); 1.158 - gl_matrix_mode(GL_MODELVIEW); 1.159 - gl_load_identity(); 1.160 - gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1); 1.161 - 1.162 - glUseProgram(sdrprog_test); 1.163 - glBindTexture(GL_TEXTURE_2D, test_tex->texid); 1.164 - if(uloc_test_tex >= 0) { 1.165 - glUniform1i(uloc_test_tex, 0); 1.166 - } 1.167 - 1.168 - glEnable(GL_BLEND); 1.169 - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.170 - 1.171 - draw_quad(0.5, 0.5, sdrprog_test); 1.172 - 1.173 - glDisable(GL_BLEND); 1.174 -} 1.175 - 1.176 -static void draw_quad(float hsz, float vsz, unsigned int sdr) 1.177 -{ 1.178 - static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1}; 1.179 - static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1}; 1.180 - 1.181 - gl_matrix_mode(GL_MODELVIEW); 1.182 - gl_push_matrix(); 1.183 - gl_scalef(hsz, vsz, 1); 1.184 - 1.185 - gl_apply_xform(sdr); 1.186 - 1.187 - glEnableVertexAttribArray(ATTR_VERTEX); 1.188 - glEnableVertexAttribArray(ATTR_TEXCOORD); 1.189 - glVertexAttribPointer(ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr); 1.190 - glVertexAttribPointer(ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr); 1.191 - 1.192 - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1.193 - 1.194 - glDisableVertexAttribArray(ATTR_VERTEX); 1.195 - glDisableVertexAttribArray(ATTR_TEXCOORD); 1.196 - 1.197 - gl_pop_matrix(); 1.198 -} 1.199 - 1.200 -void game_reshape(int x, int y) 1.201 -{ 1.202 - win_width = x; 1.203 - win_height = y; 1.204 - win_aspect = y ? (float)x / (float)y : 1.0; 1.205 - glViewport(0, 0, x, y); 1.206 - 1.207 - gl_matrix_mode(GL_PROJECTION); 1.208 - gl_load_identity(); 1.209 - gl_scalef((float)win_height / (float)win_width, 1, 1); 1.210 -} 1.211 - 1.212 -void game_keyboard(int key, int pressed) 1.213 -{ 1.214 - if(!pressed) return; 1.215 - 1.216 - switch(key) { 1.217 - case 27: 1.218 - exit(0); 1.219 - 1.220 - default: 1.221 - break; 1.222 - } 1.223 -} 1.224 - 1.225 -#define MAX_TOUCH_IDS 16 1.226 -static struct { 1.227 - int bnstate[8]; 1.228 - int prev_x, prev_y; 1.229 -} mstate[MAX_TOUCH_IDS]; 1.230 - 1.231 -void game_mouse_button(int id, int bn, int pressed, int x, int y) 1.232 -{ 1.233 - if(id >= MAX_TOUCH_IDS) return; 1.234 - 1.235 - mstate[id].prev_x = x; 1.236 - mstate[id].prev_y = y; 1.237 - mstate[id].bnstate[bn] = pressed; 1.238 -} 1.239 - 1.240 -void game_mouse_motion(int id, int x, int y) 1.241 -{ 1.242 - /* 1.243 - int dx, dy, cx, cy; 1.244 - 1.245 - if(id >= MAX_TOUCH_IDS) return; 1.246 - 1.247 - cx = win_width / 2; 1.248 - cy = win_height / 2; 1.249 - 1.250 - dx = x - mstate[id].prev_x; 1.251 - dy = y - mstate[id].prev_y; 1.252 - mstate[id].prev_x = x; 1.253 - mstate[id].prev_y = y; 1.254 - 1.255 - if(!dx && !dy) return; 1.256 - 1.257 - if(mouselook || mstate[id].bnstate[0]) { 1.258 - player_turn(&player, dx * 0.5, dy * 0.5); 1.259 - } 1.260 - if(mstate[id].bnstate[2]) { 1.261 - dbg_cam_dist += 0.1 * dy; 1.262 - if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; 1.263 - } 1.264 - 1.265 - if(mouselook) { 1.266 - warping_mouse = 1; 1.267 - set_mouse_pos(cx, cy); 1.268 - mstate[id].prev_x = cx; 1.269 - mstate[id].prev_y = cy; 1.270 - } 1.271 - */ 1.272 -} 1.273 -
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/game.cc Thu Jun 11 02:53:43 2015 +0300 2.3 @@ -0,0 +1,270 @@ 2.4 +#include <stdio.h> 2.5 +#include <stdlib.h> 2.6 +#include <math.h> 2.7 +#include <assert.h> 2.8 +#include "opengl.h" 2.9 +#include "game.h" 2.10 +#include "camera.h" 2.11 +#include "sdr.h" 2.12 +#include "sanegl.h" 2.13 +#include "texture.h" 2.14 + 2.15 +static void draw_quad(float hsz, float vsz, unsigned int sdr); 2.16 + 2.17 +static int win_width, win_height; 2.18 +static float win_aspect; 2.19 +static int video_width, video_height; 2.20 +static float video_aspect; 2.21 +static unsigned int sdrprog, sdrprog_test; 2.22 +static int uloc_tex, uloc_test_tex; 2.23 +static struct texture *test_tex; 2.24 + 2.25 +enum { ATTR_VERTEX, ATTR_TEXCOORD }; 2.26 + 2.27 +static const char *vsdr_source = 2.28 + "attribute vec4 attr_vertex, attr_texcoord;\n" 2.29 + "uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n" 2.30 + "varying vec4 tex_coords;\n" 2.31 + "void main()\n" 2.32 + "{\n" 2.33 + "\tmat4 mvp = matrix_projection * matrix_modelview;\n" 2.34 + "\tgl_Position = mvp * attr_vertex;\n" 2.35 + "\ttex_coords = matrix_texture * attr_texcoord;\n" 2.36 + "}\n"; 2.37 + 2.38 +static const char *psdr_cam_source = 2.39 + "#extension GL_OES_EGL_image_external : require\n" 2.40 + "precision mediump float;\n" 2.41 + "uniform samplerExternalOES tex;\n" 2.42 + "varying vec4 tex_coords;\n" 2.43 + "void main()\n" 2.44 + "{\n" 2.45 + "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" 2.46 + "\tgl_FragColor = vec4(texel.xyz, 1.0);\n" 2.47 + "}\n"; 2.48 + 2.49 +static const char *psdr_tex_source = 2.50 + "precision mediump float;\n" 2.51 + "uniform sampler2D tex;\n" 2.52 + "varying vec4 tex_coords;\n" 2.53 + "void main()\n" 2.54 + "{\n" 2.55 + "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" 2.56 + "\tgl_FragColor = texel;\n" 2.57 + "}\n"; 2.58 + 2.59 +extern "C" int game_init(void) 2.60 +{ 2.61 + unsigned int vsdr, psdr_cam, psdr_tex; 2.62 + 2.63 + //glEnable(GL_DEPTH_TEST); 2.64 + glEnable(GL_CULL_FACE); 2.65 + 2.66 + glClearColor(0.4, 0.4, 0.4, 1); 2.67 + 2.68 + if(!(vsdr = create_vertex_shader(vsdr_source))) 2.69 + return -1; 2.70 + assert(glGetError() == GL_NO_ERROR); 2.71 + if(!(psdr_cam = create_pixel_shader(psdr_cam_source))) 2.72 + return -1; 2.73 + assert(glGetError() == GL_NO_ERROR); 2.74 + if(!(psdr_tex = create_pixel_shader(psdr_tex_source))) 2.75 + return -1; 2.76 + assert(glGetError() == GL_NO_ERROR); 2.77 + if(!(sdrprog = create_program_link(vsdr, psdr_cam, 0))) { 2.78 + fprintf(stderr, "failed to create shader program\n"); 2.79 + return -1; 2.80 + } 2.81 + if(!(sdrprog_test = create_program_link(vsdr, psdr_tex, 0))) { 2.82 + fprintf(stderr, "failed to create test shader program\n"); 2.83 + return -1; 2.84 + } 2.85 + 2.86 + glUseProgram(sdrprog); 2.87 + glBindAttribLocation(sdrprog, ATTR_VERTEX, "attr_vertex"); 2.88 + glBindAttribLocation(sdrprog, ATTR_TEXCOORD, "attr_texcoord"); 2.89 + uloc_tex = glGetUniformLocation(sdrprog, "tex"); 2.90 + glLinkProgram(sdrprog); 2.91 + 2.92 + glUseProgram(sdrprog_test); 2.93 + glBindAttribLocation(sdrprog_test, ATTR_VERTEX, "attr_vertex"); 2.94 + glBindAttribLocation(sdrprog_test, ATTR_TEXCOORD, "attr_texcoord"); 2.95 + uloc_test_tex = glGetUniformLocation(sdrprog_test, "tex"); 2.96 + glLinkProgram(sdrprog_test); 2.97 + 2.98 + if(!(test_tex = get_texture("data/opengl.png"))) { 2.99 + return -1; 2.100 + } 2.101 + 2.102 + cam_start_video(); 2.103 + cam_video_size(&video_width, &video_height); 2.104 + if(video_height) { 2.105 + video_aspect = (float)video_width / (float)video_height; 2.106 + } else { 2.107 + video_aspect = 1.0; 2.108 + } 2.109 + 2.110 + printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect); 2.111 + return 0; 2.112 +} 2.113 + 2.114 +extern "C" void game_shutdown(void) 2.115 +{ 2.116 + cam_shutdown(); 2.117 + free_program(sdrprog); 2.118 +} 2.119 + 2.120 +extern "C" void game_display(unsigned long msec) 2.121 +{ 2.122 + unsigned int tex; 2.123 + const float *tex_matrix; 2.124 + float xscale, yscale; 2.125 + 2.126 + cam_update(); 2.127 + tex = cam_texture(); 2.128 + tex_matrix = cam_texture_matrix(); 2.129 + 2.130 + //float tsec = (float)msec / 1000.0f; 2.131 + 2.132 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.133 + 2.134 + gl_matrix_mode(GL_MODELVIEW); 2.135 + gl_load_identity(); 2.136 + gl_matrix_mode(GL_TEXTURE); 2.137 + gl_load_matrixf(tex_matrix); 2.138 + 2.139 + glUseProgram(sdrprog); 2.140 + glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); 2.141 + if(uloc_tex >= 0) { 2.142 + glUniform1i(uloc_tex, 0); 2.143 + } 2.144 + 2.145 + if(video_aspect > win_aspect) { 2.146 + xscale = 1.0; 2.147 + yscale = 1.0 / video_aspect; 2.148 + } else { 2.149 + xscale = video_aspect; 2.150 + yscale = 1.0; 2.151 + } 2.152 + draw_quad(xscale, yscale, sdrprog); 2.153 + 2.154 + gl_matrix_mode(GL_TEXTURE); 2.155 + gl_load_identity(); 2.156 + gl_translatef(0, 1, 0); 2.157 + gl_scalef(1, -1, 1); 2.158 + gl_matrix_mode(GL_MODELVIEW); 2.159 + gl_load_identity(); 2.160 + gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1); 2.161 + 2.162 + glUseProgram(sdrprog_test); 2.163 + glBindTexture(GL_TEXTURE_2D, test_tex->texid); 2.164 + if(uloc_test_tex >= 0) { 2.165 + glUniform1i(uloc_test_tex, 0); 2.166 + } 2.167 + 2.168 + glEnable(GL_BLEND); 2.169 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2.170 + 2.171 + draw_quad(0.5, 0.5, sdrprog_test); 2.172 + 2.173 + glDisable(GL_BLEND); 2.174 +} 2.175 + 2.176 +static void draw_quad(float hsz, float vsz, unsigned int sdr) 2.177 +{ 2.178 + static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1}; 2.179 + static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1}; 2.180 + 2.181 + gl_matrix_mode(GL_MODELVIEW); 2.182 + gl_push_matrix(); 2.183 + gl_scalef(hsz, vsz, 1); 2.184 + 2.185 + gl_apply_xform(sdr); 2.186 + 2.187 + glEnableVertexAttribArray(ATTR_VERTEX); 2.188 + glEnableVertexAttribArray(ATTR_TEXCOORD); 2.189 + glVertexAttribPointer(ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr); 2.190 + glVertexAttribPointer(ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr); 2.191 + 2.192 + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2.193 + 2.194 + glDisableVertexAttribArray(ATTR_VERTEX); 2.195 + glDisableVertexAttribArray(ATTR_TEXCOORD); 2.196 + 2.197 + gl_pop_matrix(); 2.198 +} 2.199 + 2.200 +extern "C" void game_reshape(int x, int y) 2.201 +{ 2.202 + win_width = x; 2.203 + win_height = y; 2.204 + win_aspect = y ? (float)x / (float)y : 1.0; 2.205 + glViewport(0, 0, x, y); 2.206 + 2.207 + gl_matrix_mode(GL_PROJECTION); 2.208 + gl_load_identity(); 2.209 + gl_scalef((float)win_height / (float)win_width, 1, 1); 2.210 +} 2.211 + 2.212 +extern "C" void game_keyboard(int key, int pressed) 2.213 +{ 2.214 + if(!pressed) return; 2.215 + 2.216 + switch(key) { 2.217 + case 27: 2.218 + exit(0); 2.219 + 2.220 + default: 2.221 + break; 2.222 + } 2.223 +} 2.224 + 2.225 +#define MAX_TOUCH_IDS 16 2.226 +static struct { 2.227 + int bnstate[8]; 2.228 + int prev_x, prev_y; 2.229 +} mstate[MAX_TOUCH_IDS]; 2.230 + 2.231 +extern "C" void game_mouse_button(int id, int bn, int pressed, int x, int y) 2.232 +{ 2.233 + if(id >= MAX_TOUCH_IDS) return; 2.234 + 2.235 + mstate[id].prev_x = x; 2.236 + mstate[id].prev_y = y; 2.237 + mstate[id].bnstate[bn] = pressed; 2.238 +} 2.239 + 2.240 +extern "C" void game_mouse_motion(int id, int x, int y) 2.241 +{ 2.242 + /* 2.243 + int dx, dy, cx, cy; 2.244 + 2.245 + if(id >= MAX_TOUCH_IDS) return; 2.246 + 2.247 + cx = win_width / 2; 2.248 + cy = win_height / 2; 2.249 + 2.250 + dx = x - mstate[id].prev_x; 2.251 + dy = y - mstate[id].prev_y; 2.252 + mstate[id].prev_x = x; 2.253 + mstate[id].prev_y = y; 2.254 + 2.255 + if(!dx && !dy) return; 2.256 + 2.257 + if(mouselook || mstate[id].bnstate[0]) { 2.258 + player_turn(&player, dx * 0.5, dy * 0.5); 2.259 + } 2.260 + if(mstate[id].bnstate[2]) { 2.261 + dbg_cam_dist += 0.1 * dy; 2.262 + if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; 2.263 + } 2.264 + 2.265 + if(mouselook) { 2.266 + warping_mouse = 1; 2.267 + set_mouse_pos(cx, cy); 2.268 + mstate[id].prev_x = cx; 2.269 + mstate[id].prev_y = cy; 2.270 + } 2.271 + */ 2.272 +} 2.273 +
3.1 --- a/src/game.h Wed Jun 10 22:28:48 2015 +0300 3.2 +++ b/src/game.h Thu Jun 11 02:53:43 2015 +0300 3.3 @@ -1,6 +1,10 @@ 3.4 #ifndef GAME_H_ 3.5 #define GAME_H_ 3.6 3.7 +#ifdef __cplusplus 3.8 +extern "C" { 3.9 +#endif 3.10 + 3.11 int game_init(void); 3.12 void game_shutdown(void); 3.13 3.14 @@ -15,5 +19,9 @@ 3.15 void set_mouse_pos(int x, int y); 3.16 void set_mouse_cursor(int enable); 3.17 3.18 +#ifdef __cplusplus 3.19 +} 3.20 +#endif 3.21 + 3.22 #endif /* GAME_H_ */ 3.23
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/shader.cc Thu Jun 11 02:53:43 2015 +0300 4.3 @@ -0,0 +1,182 @@ 4.4 +#include <assert.h> 4.5 +#include <string> 4.6 +#include <map> 4.7 +#include "shader.h" 4.8 +#include "sdr.h" 4.9 +#include "opengl.h" 4.10 + 4.11 +std::map<std::string, unsigned int> sdrdb; 4.12 + 4.13 +SdrProg::SdrProg() 4.14 +{ 4.15 + prog = 0; 4.16 + valid = false; 4.17 +} 4.18 + 4.19 +SdrProg::~SdrProg() 4.20 +{ 4.21 + destroy(); 4.22 +} 4.23 + 4.24 +void SdrProg::create() 4.25 +{ 4.26 + destroy(); 4.27 + prog = glCreateProgram(); 4.28 +} 4.29 + 4.30 +void SdrProg::destroy() 4.31 +{ 4.32 + if(prog) { 4.33 + glDeleteProgram(prog); 4.34 + } 4.35 + valid = false; 4.36 + 4.37 + for(size_t i=0; i<priv_sdr.size(); i++) { 4.38 + glDeleteShader(priv_sdr[i]); 4.39 + } 4.40 + priv_sdr.clear(); 4.41 +} 4.42 + 4.43 +bool SdrProg::attach_shader(unsigned int sdr) 4.44 +{ 4.45 + assert(glGetError() == GL_NO_ERROR); 4.46 + 4.47 + glAttachShader(prog, sdr); 4.48 + if(glGetError() != GL_NO_ERROR) { 4.49 + fprintf(stderr, "failed to attach shader %u to program %u\n", sdr, prog); 4.50 + return false; 4.51 + } 4.52 + 4.53 + valid = false; 4.54 + return true; 4.55 +} 4.56 + 4.57 +bool SdrProg::create(unsigned int vsdr, unsigned int psdr) 4.58 +{ 4.59 + create(); 4.60 + 4.61 + if(!attach_shader(vsdr) || !attach_shader(psdr)) { 4.62 + return false; 4.63 + } 4.64 + 4.65 + if(!link()) { 4.66 + return false; 4.67 + } 4.68 + return true; 4.69 +} 4.70 + 4.71 +bool SdrProg::create(const char *vsrc, const char *psrc) 4.72 +{ 4.73 + unsigned int vs = create_shader(vsrc, GL_VERTEX_SHADER); 4.74 + if(!vs) { 4.75 + return false; 4.76 + } 4.77 + 4.78 + unsigned int ps = create_shader(psrc, GL_FRAGMENT_SHADER); 4.79 + if(!ps) { 4.80 + glDeleteShader(vs); 4.81 + return false; 4.82 + } 4.83 + 4.84 + if(!create(vs, ps)) { 4.85 + glDeleteShader(vs); 4.86 + glDeleteShader(ps); 4.87 + return false; 4.88 + } 4.89 + 4.90 + priv_sdr.push_back(vs); 4.91 + priv_sdr.push_back(ps); 4.92 + return true; 4.93 +} 4.94 + 4.95 +bool SdrProg::load(const char *vfname, const char *pfname) 4.96 +{ 4.97 + unsigned int vs = load_vertex_shader(vfname); 4.98 + if(!vs) { 4.99 + return false; 4.100 + } 4.101 + sdrdb[vfname] = vs; 4.102 + 4.103 + unsigned int ps = load_pixel_shader(pfname); 4.104 + if(!ps) { 4.105 + return false; 4.106 + } 4.107 + sdrdb[pfname] = ps; 4.108 + 4.109 + printf("creating shader program (%s, %s)\n", vfname, pfname); 4.110 + if(!(prog = create_program_link(vs, ps, 0))) { 4.111 + return false; 4.112 + } 4.113 + valid = true; 4.114 + return true; 4.115 +} 4.116 + 4.117 +bool SdrProg::link() const 4.118 +{ 4.119 + return link_program(prog) != -1; 4.120 +} 4.121 + 4.122 +int SdrProg::get_uniform(const char *name) const 4.123 +{ 4.124 + if(!bind()) { 4.125 + return -1; 4.126 + } 4.127 + return glGetUniformLocation(prog, name); 4.128 +} 4.129 + 4.130 +int SdrProg::get_attrib(const char *name) const 4.131 +{ 4.132 + if(!bind()) { 4.133 + return -1; 4.134 + } 4.135 + return glGetAttribLocation(prog, name); 4.136 +} 4.137 + 4.138 +bool SdrProg::bind_attrib(const char *name, int loc) const 4.139 +{ 4.140 + if(!prog) { 4.141 + return false; 4.142 + } 4.143 + 4.144 + assert(glGetError() == GL_NO_ERROR); 4.145 + glBindAttribLocation(prog, loc, name); 4.146 + if(glGetError() != GL_NO_ERROR) { 4.147 + fprintf(stderr, "failed to bind attribute %s of program %u to location %d\n", 4.148 + name, prog, loc); 4.149 + return false; 4.150 + } 4.151 + valid = false; /* must relink after the glBindAttribLocation call */ 4.152 + return true; 4.153 +} 4.154 + 4.155 +bool SdrProg::bind() const 4.156 +{ 4.157 + if(!prog || (!valid && !link())) { 4.158 + return false; 4.159 + } 4.160 + 4.161 + assert(glGetError() == GL_NO_ERROR); 4.162 + glUseProgram(prog); 4.163 + if(glGetError() != GL_NO_ERROR) { 4.164 + fprintf(stderr, "failed to bind program %d\n", prog); 4.165 + return false; 4.166 + } 4.167 + return true; 4.168 +} 4.169 + 4.170 + 4.171 +unsigned int get_shader(const char *name, unsigned int type) 4.172 +{ 4.173 + std::map<std::string, unsigned int>::const_iterator it = sdrdb.find(name); 4.174 + if(it != sdrdb.end()) { 4.175 + return it->second; 4.176 + } 4.177 + 4.178 + unsigned int sdr = load_shader(name, type); 4.179 + if(!sdr) { 4.180 + return 0; 4.181 + } 4.182 + 4.183 + sdrdb[name] = sdr; 4.184 + return sdr; 4.185 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/shader.h Thu Jun 11 02:53:43 2015 +0300 5.3 @@ -0,0 +1,36 @@ 5.4 +#ifndef SHADER_H_ 5.5 +#define SHADER_H_ 5.6 + 5.7 +#include <vector> 5.8 + 5.9 +class SdrProg { 5.10 +private: 5.11 + std::vector<unsigned int> priv_sdr; 5.12 + unsigned int prog; 5.13 + mutable bool valid; 5.14 + 5.15 +public: 5.16 + SdrProg(); 5.17 + ~SdrProg(); 5.18 + 5.19 + void create(); 5.20 + void destroy(); 5.21 + 5.22 + bool attach_shader(unsigned int sdr); 5.23 + 5.24 + bool create(unsigned int vsdr, unsigned int psdr); 5.25 + bool create(const char *vsrc, const char *psrc); 5.26 + bool load(const char *vfname, const char *pfname); 5.27 + 5.28 + bool link() const; 5.29 + 5.30 + int get_uniform(const char *name) const; 5.31 + int get_attrib(const char *name) const; 5.32 + bool bind_attrib(const char *name, int loc) const; 5.33 + 5.34 + bool bind() const; 5.35 +}; 5.36 + 5.37 +unsigned int get_shader(const char *name, unsigned int type); 5.38 + 5.39 +#endif /* SHADER_H_ */