3dphotoshoot

annotate 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
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <math.h>
nuclear@11 4 #include <assert.h>
nuclear@0 5 #include "opengl.h"
nuclear@0 6 #include "game.h"
nuclear@7 7 #include "camera.h"
nuclear@10 8 #include "sdr.h"
nuclear@11 9 #include "sanegl.h"
nuclear@17 10 #include "texture.h"
nuclear@7 11
nuclear@17 12 static void draw_quad(float hsz, float vsz, unsigned int sdr);
nuclear@0 13
nuclear@0 14 static int win_width, win_height;
nuclear@9 15 static float win_aspect;
nuclear@9 16 static int video_width, video_height;
nuclear@9 17 static float video_aspect;
nuclear@17 18 static unsigned int sdrprog, sdrprog_test;
nuclear@17 19 static int uloc_tex, uloc_test_tex;
nuclear@17 20 static struct texture *test_tex;
nuclear@17 21
nuclear@17 22 enum { ATTR_VERTEX, ATTR_TEXCOORD };
nuclear@10 23
nuclear@10 24 static const char *vsdr_source =
nuclear@11 25 "attribute vec4 attr_vertex, attr_texcoord;\n"
nuclear@11 26 "uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n"
nuclear@10 27 "varying vec4 tex_coords;\n"
nuclear@10 28 "void main()\n"
nuclear@10 29 "{\n"
nuclear@11 30 "\tmat4 mvp = matrix_projection * matrix_modelview;\n"
nuclear@11 31 "\tgl_Position = mvp * attr_vertex;\n"
nuclear@11 32 "\ttex_coords = matrix_texture * attr_texcoord;\n"
nuclear@10 33 "}\n";
nuclear@10 34
nuclear@17 35 static const char *psdr_cam_source =
nuclear@10 36 "#extension GL_OES_EGL_image_external : require\n"
nuclear@11 37 "precision mediump float;\n"
nuclear@10 38 "uniform samplerExternalOES tex;\n"
nuclear@10 39 "varying vec4 tex_coords;\n"
nuclear@10 40 "void main()\n"
nuclear@10 41 "{\n"
nuclear@10 42 "\tvec4 texel = texture2D(tex, tex_coords.xy);\n"
nuclear@10 43 "\tgl_FragColor = vec4(texel.xyz, 1.0);\n"
nuclear@10 44 "}\n";
nuclear@0 45
nuclear@17 46 static const char *psdr_tex_source =
nuclear@17 47 "precision mediump float;\n"
nuclear@17 48 "uniform sampler2D tex;\n"
nuclear@17 49 "varying vec4 tex_coords;\n"
nuclear@17 50 "void main()\n"
nuclear@17 51 "{\n"
nuclear@17 52 "\tvec4 texel = texture2D(tex, tex_coords.xy);\n"
nuclear@17 53 "\tgl_FragColor = texel;\n"
nuclear@17 54 "}\n";
nuclear@0 55
nuclear@20 56 extern "C" int game_init(void)
nuclear@0 57 {
nuclear@17 58 unsigned int vsdr, psdr_cam, psdr_tex;
nuclear@10 59
nuclear@17 60 //glEnable(GL_DEPTH_TEST);
nuclear@0 61 glEnable(GL_CULL_FACE);
nuclear@0 62
nuclear@0 63 glClearColor(0.4, 0.4, 0.4, 1);
nuclear@8 64
nuclear@10 65 if(!(vsdr = create_vertex_shader(vsdr_source)))
nuclear@10 66 return -1;
nuclear@11 67 assert(glGetError() == GL_NO_ERROR);
nuclear@17 68 if(!(psdr_cam = create_pixel_shader(psdr_cam_source)))
nuclear@10 69 return -1;
nuclear@11 70 assert(glGetError() == GL_NO_ERROR);
nuclear@17 71 if(!(psdr_tex = create_pixel_shader(psdr_tex_source)))
nuclear@17 72 return -1;
nuclear@17 73 assert(glGetError() == GL_NO_ERROR);
nuclear@17 74 if(!(sdrprog = create_program_link(vsdr, psdr_cam, 0))) {
nuclear@10 75 fprintf(stderr, "failed to create shader program\n");
nuclear@10 76 return -1;
nuclear@10 77 }
nuclear@17 78 if(!(sdrprog_test = create_program_link(vsdr, psdr_tex, 0))) {
nuclear@17 79 fprintf(stderr, "failed to create test shader program\n");
nuclear@17 80 return -1;
nuclear@17 81 }
nuclear@17 82
nuclear@10 83 glUseProgram(sdrprog);
nuclear@17 84 glBindAttribLocation(sdrprog, ATTR_VERTEX, "attr_vertex");
nuclear@17 85 glBindAttribLocation(sdrprog, ATTR_TEXCOORD, "attr_texcoord");
nuclear@11 86 uloc_tex = glGetUniformLocation(sdrprog, "tex");
nuclear@17 87 glLinkProgram(sdrprog);
nuclear@17 88
nuclear@17 89 glUseProgram(sdrprog_test);
nuclear@17 90 glBindAttribLocation(sdrprog_test, ATTR_VERTEX, "attr_vertex");
nuclear@17 91 glBindAttribLocation(sdrprog_test, ATTR_TEXCOORD, "attr_texcoord");
nuclear@17 92 uloc_test_tex = glGetUniformLocation(sdrprog_test, "tex");
nuclear@17 93 glLinkProgram(sdrprog_test);
nuclear@17 94
nuclear@17 95 if(!(test_tex = get_texture("data/opengl.png"))) {
nuclear@17 96 return -1;
nuclear@17 97 }
nuclear@10 98
nuclear@8 99 cam_start_video();
nuclear@9 100 cam_video_size(&video_width, &video_height);
nuclear@9 101 if(video_height) {
nuclear@9 102 video_aspect = (float)video_width / (float)video_height;
nuclear@9 103 } else {
nuclear@9 104 video_aspect = 1.0;
nuclear@9 105 }
nuclear@9 106
nuclear@9 107 printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect);
nuclear@0 108 return 0;
nuclear@0 109 }
nuclear@0 110
nuclear@20 111 extern "C" void game_shutdown(void)
nuclear@0 112 {
nuclear@8 113 cam_shutdown();
nuclear@10 114 free_program(sdrprog);
nuclear@0 115 }
nuclear@0 116
nuclear@20 117 extern "C" void game_display(unsigned long msec)
nuclear@0 118 {
nuclear@9 119 unsigned int tex;
nuclear@9 120 const float *tex_matrix;
nuclear@9 121 float xscale, yscale;
nuclear@9 122
nuclear@8 123 cam_update();
nuclear@9 124 tex = cam_texture();
nuclear@9 125 tex_matrix = cam_texture_matrix();
nuclear@7 126
nuclear@4 127 //float tsec = (float)msec / 1000.0f;
nuclear@0 128
nuclear@0 129 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@0 130
nuclear@11 131 gl_matrix_mode(GL_MODELVIEW);
nuclear@11 132 gl_load_identity();
nuclear@11 133 gl_matrix_mode(GL_TEXTURE);
nuclear@11 134 gl_load_matrixf(tex_matrix);
nuclear@11 135
nuclear@10 136 glUseProgram(sdrprog);
nuclear@10 137 glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
nuclear@11 138 if(uloc_tex >= 0) {
nuclear@11 139 glUniform1i(uloc_tex, 0);
nuclear@11 140 }
nuclear@7 141
nuclear@9 142 if(video_aspect > win_aspect) {
nuclear@9 143 xscale = 1.0;
nuclear@9 144 yscale = 1.0 / video_aspect;
nuclear@9 145 } else {
nuclear@9 146 xscale = video_aspect;
nuclear@9 147 yscale = 1.0;
nuclear@9 148 }
nuclear@17 149 draw_quad(xscale, yscale, sdrprog);
nuclear@17 150
nuclear@17 151 gl_matrix_mode(GL_TEXTURE);
nuclear@17 152 gl_load_identity();
nuclear@17 153 gl_translatef(0, 1, 0);
nuclear@17 154 gl_scalef(1, -1, 1);
nuclear@17 155 gl_matrix_mode(GL_MODELVIEW);
nuclear@17 156 gl_load_identity();
nuclear@17 157 gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1);
nuclear@17 158
nuclear@17 159 glUseProgram(sdrprog_test);
nuclear@17 160 glBindTexture(GL_TEXTURE_2D, test_tex->texid);
nuclear@17 161 if(uloc_test_tex >= 0) {
nuclear@17 162 glUniform1i(uloc_test_tex, 0);
nuclear@17 163 }
nuclear@17 164
nuclear@17 165 glEnable(GL_BLEND);
nuclear@17 166 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
nuclear@17 167
nuclear@17 168 draw_quad(0.5, 0.5, sdrprog_test);
nuclear@17 169
nuclear@17 170 glDisable(GL_BLEND);
nuclear@7 171 }
nuclear@7 172
nuclear@17 173 static void draw_quad(float hsz, float vsz, unsigned int sdr)
nuclear@7 174 {
nuclear@7 175 static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1};
nuclear@9 176 static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1};
nuclear@7 177
nuclear@11 178 gl_matrix_mode(GL_MODELVIEW);
nuclear@11 179 gl_push_matrix();
nuclear@11 180 gl_scalef(hsz, vsz, 1);
nuclear@11 181
nuclear@17 182 gl_apply_xform(sdr);
nuclear@7 183
nuclear@17 184 glEnableVertexAttribArray(ATTR_VERTEX);
nuclear@17 185 glEnableVertexAttribArray(ATTR_TEXCOORD);
nuclear@17 186 glVertexAttribPointer(ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr);
nuclear@17 187 glVertexAttribPointer(ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr);
nuclear@7 188
nuclear@8 189 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
nuclear@7 190
nuclear@17 191 glDisableVertexAttribArray(ATTR_VERTEX);
nuclear@17 192 glDisableVertexAttribArray(ATTR_TEXCOORD);
nuclear@11 193
nuclear@11 194 gl_pop_matrix();
nuclear@0 195 }
nuclear@0 196
nuclear@20 197 extern "C" void game_reshape(int x, int y)
nuclear@0 198 {
nuclear@0 199 win_width = x;
nuclear@0 200 win_height = y;
nuclear@9 201 win_aspect = y ? (float)x / (float)y : 1.0;
nuclear@0 202 glViewport(0, 0, x, y);
nuclear@0 203
nuclear@11 204 gl_matrix_mode(GL_PROJECTION);
nuclear@11 205 gl_load_identity();
nuclear@11 206 gl_scalef((float)win_height / (float)win_width, 1, 1);
nuclear@0 207 }
nuclear@0 208
nuclear@20 209 extern "C" void game_keyboard(int key, int pressed)
nuclear@0 210 {
nuclear@0 211 if(!pressed) return;
nuclear@0 212
nuclear@0 213 switch(key) {
nuclear@0 214 case 27:
nuclear@0 215 exit(0);
nuclear@0 216
nuclear@0 217 default:
nuclear@0 218 break;
nuclear@0 219 }
nuclear@0 220 }
nuclear@0 221
nuclear@0 222 #define MAX_TOUCH_IDS 16
nuclear@0 223 static struct {
nuclear@0 224 int bnstate[8];
nuclear@0 225 int prev_x, prev_y;
nuclear@0 226 } mstate[MAX_TOUCH_IDS];
nuclear@0 227
nuclear@20 228 extern "C" void game_mouse_button(int id, int bn, int pressed, int x, int y)
nuclear@0 229 {
nuclear@0 230 if(id >= MAX_TOUCH_IDS) return;
nuclear@0 231
nuclear@0 232 mstate[id].prev_x = x;
nuclear@0 233 mstate[id].prev_y = y;
nuclear@0 234 mstate[id].bnstate[bn] = pressed;
nuclear@0 235 }
nuclear@0 236
nuclear@20 237 extern "C" void game_mouse_motion(int id, int x, int y)
nuclear@0 238 {
nuclear@0 239 /*
nuclear@0 240 int dx, dy, cx, cy;
nuclear@0 241
nuclear@0 242 if(id >= MAX_TOUCH_IDS) return;
nuclear@0 243
nuclear@0 244 cx = win_width / 2;
nuclear@0 245 cy = win_height / 2;
nuclear@0 246
nuclear@0 247 dx = x - mstate[id].prev_x;
nuclear@0 248 dy = y - mstate[id].prev_y;
nuclear@0 249 mstate[id].prev_x = x;
nuclear@0 250 mstate[id].prev_y = y;
nuclear@0 251
nuclear@0 252 if(!dx && !dy) return;
nuclear@0 253
nuclear@0 254 if(mouselook || mstate[id].bnstate[0]) {
nuclear@0 255 player_turn(&player, dx * 0.5, dy * 0.5);
nuclear@0 256 }
nuclear@0 257 if(mstate[id].bnstate[2]) {
nuclear@0 258 dbg_cam_dist += 0.1 * dy;
nuclear@0 259 if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0;
nuclear@0 260 }
nuclear@0 261
nuclear@0 262 if(mouselook) {
nuclear@0 263 warping_mouse = 1;
nuclear@0 264 set_mouse_pos(cx, cy);
nuclear@0 265 mstate[id].prev_x = cx;
nuclear@0 266 mstate[id].prev_y = cy;
nuclear@0 267 }
nuclear@0 268 */
nuclear@0 269 }
nuclear@0 270