3dphotoshoot
diff src/game.cc @ 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 | src/game.c@aef7f51f6397 |
children | 4ca4e3c5a754 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/game.cc Thu Jun 11 02:53:43 2015 +0300 1.3 @@ -0,0 +1,270 @@ 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 +extern "C" 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 +extern "C" void game_shutdown(void) 1.115 +{ 1.116 + cam_shutdown(); 1.117 + free_program(sdrprog); 1.118 +} 1.119 + 1.120 +extern "C" 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 +extern "C" 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 +extern "C" 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 +extern "C" 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 +extern "C" 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 +