3dphotoshoot

annotate src/game.cc @ 26:a460b1e5af4a

added GLUT frontend
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 18 Jun 2015 03:55:05 +0300
parents ac80210d5fbe
children 3d082c566b53
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@25 5 #include <algorithm>
nuclear@0 6 #include "opengl.h"
nuclear@0 7 #include "game.h"
nuclear@7 8 #include "camera.h"
nuclear@11 9 #include "sanegl.h"
nuclear@17 10 #include "texture.h"
nuclear@21 11 #include "shader.h"
nuclear@22 12 #include "text.h"
nuclear@24 13 #include "vmath/vmath.h"
nuclear@25 14 #include "mesh.h"
nuclear@25 15 #include "meshgen.h"
nuclear@7 16
nuclear@21 17 static void draw_quad(float hsz, float vsz);
nuclear@25 18 static void draw_rotation_gizmo();
nuclear@25 19 static void draw_disc_wedge(float start, float end, int subdiv);
nuclear@0 20
nuclear@22 21 int win_width, win_height;
nuclear@22 22
nuclear@9 23 static float win_aspect;
nuclear@9 24 static int video_width, video_height;
nuclear@9 25 static float video_aspect;
nuclear@17 26 static struct texture *test_tex;
nuclear@17 27
nuclear@25 28 static SdrProg *sdr_tex, *sdr_color, *sdr_debug;
nuclear@0 29
nuclear@25 30 static Quaternion last_rot;
nuclear@25 31 static Vector3 last_trans;
nuclear@25 32
nuclear@25 33 static Quaternion rot;
nuclear@25 34 static Vector3 rot_euler;
nuclear@25 35
nuclear@25 36 static Mesh *mesh;
nuclear@24 37
nuclear@20 38 extern "C" int game_init(void)
nuclear@0 39 {
nuclear@17 40 //glEnable(GL_DEPTH_TEST);
nuclear@22 41 //glEnable(GL_CULL_FACE);
nuclear@0 42
nuclear@0 43 glClearColor(0.4, 0.4, 0.4, 1);
nuclear@8 44
nuclear@25 45 if(!(sdr_tex = get_sdrprog("sdr/vertex.glsl", "sdr/tex.p.glsl"))) {
nuclear@10 46 return -1;
nuclear@10 47 }
nuclear@25 48 if(!(sdr_color = get_sdrprog("sdr/vertex.glsl", "sdr/color.p.glsl"))) {
nuclear@25 49 return -1;
nuclear@25 50 }
nuclear@25 51 if(!(sdr_debug = get_sdrprog("sdr/vertex.glsl", "sdr/normvis.p.glsl"))) {
nuclear@17 52 return -1;
nuclear@17 53 }
nuclear@17 54
nuclear@17 55 if(!(test_tex = get_texture("data/opengl.png"))) {
nuclear@17 56 return -1;
nuclear@17 57 }
nuclear@10 58
nuclear@25 59 mesh = new Mesh;
nuclear@25 60 gen_cylinder(mesh, 0.2, 1.0, 16, 1);
nuclear@25 61
nuclear@8 62 cam_start_video();
nuclear@9 63 cam_video_size(&video_width, &video_height);
nuclear@9 64 if(video_height) {
nuclear@9 65 video_aspect = (float)video_width / (float)video_height;
nuclear@9 66 } else {
nuclear@9 67 video_aspect = 1.0;
nuclear@9 68 }
nuclear@9 69
nuclear@9 70 printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect);
nuclear@0 71 return 0;
nuclear@0 72 }
nuclear@0 73
nuclear@20 74 extern "C" void game_shutdown(void)
nuclear@0 75 {
nuclear@8 76 cam_shutdown();
nuclear@21 77 delete sdr_tex;
nuclear@0 78 }
nuclear@0 79
nuclear@20 80 extern "C" void game_display(unsigned long msec)
nuclear@0 81 {
nuclear@9 82 unsigned int tex;
nuclear@9 83 float xscale, yscale;
nuclear@9 84
nuclear@8 85 cam_update();
nuclear@9 86 tex = cam_texture();
nuclear@7 87
nuclear@4 88 //float tsec = (float)msec / 1000.0f;
nuclear@0 89
nuclear@0 90 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@0 91
nuclear@25 92 // draw video preview frame
nuclear@25 93 gl_matrix_mode(GL_PROJECTION);
nuclear@25 94 gl_push_matrix();
nuclear@25 95 gl_load_identity();
nuclear@25 96 gl_scalef((float)win_height / (float)win_width, 1, 1);
nuclear@11 97 gl_matrix_mode(GL_MODELVIEW);
nuclear@11 98 gl_load_identity();
nuclear@7 99
nuclear@9 100 if(video_aspect > win_aspect) {
nuclear@9 101 xscale = 1.0;
nuclear@9 102 yscale = 1.0 / video_aspect;
nuclear@9 103 } else {
nuclear@9 104 xscale = video_aspect;
nuclear@9 105 yscale = 1.0;
nuclear@9 106 }
nuclear@25 107 gl_scalef(xscale, yscale, 1);
nuclear@17 108
nuclear@25 109 cam_draw_preview();
nuclear@25 110
nuclear@25 111 gl_matrix_mode(GL_PROJECTION);
nuclear@25 112 gl_pop_matrix();
nuclear@25 113 // done drawing preview
nuclear@25 114
nuclear@25 115
nuclear@17 116 gl_matrix_mode(GL_MODELVIEW);
nuclear@17 117 gl_load_identity();
nuclear@25 118 gl_translatef(0, 0, -6);
nuclear@17 119
nuclear@25 120 draw_rotation_gizmo();
nuclear@22 121
nuclear@24 122 // print the rotation quaternion
nuclear@22 123 text_color(1, 1, 1, 1);
nuclear@24 124 text_position(0, 0);
nuclear@25 125 text_printf("translation (% .3f, % .3f, % .3f)", last_trans.x, last_trans.y, last_trans.z);
nuclear@24 126 text_position(0, 1);
nuclear@25 127 text_printf("Rotation quat ([% 1.3f, % 1.3f, % 1.3f], % 1.3f)", last_rot.v.x, last_rot.v.y, last_rot.v.z, last_rot.s);
nuclear@7 128 }
nuclear@7 129
nuclear@21 130 static void draw_quad(float hsz, float vsz)
nuclear@7 131 {
nuclear@7 132 static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1};
nuclear@9 133 static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1};
nuclear@7 134
nuclear@11 135 gl_matrix_mode(GL_MODELVIEW);
nuclear@11 136 gl_push_matrix();
nuclear@11 137 gl_scalef(hsz, vsz, 1);
nuclear@11 138
nuclear@21 139 if(SdrProg::active) {
nuclear@21 140 gl_apply_xform(SdrProg::active->get_globj());
nuclear@21 141 }
nuclear@7 142
nuclear@21 143 glEnableVertexAttribArray(SDR_ATTR_VERTEX);
nuclear@21 144 glEnableVertexAttribArray(SDR_ATTR_TEXCOORD);
nuclear@21 145 glVertexAttribPointer(SDR_ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr);
nuclear@21 146 glVertexAttribPointer(SDR_ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr);
nuclear@7 147
nuclear@8 148 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
nuclear@7 149
nuclear@21 150 glDisableVertexAttribArray(SDR_ATTR_VERTEX);
nuclear@21 151 glDisableVertexAttribArray(SDR_ATTR_TEXCOORD);
nuclear@11 152
nuclear@11 153 gl_pop_matrix();
nuclear@0 154 }
nuclear@0 155
nuclear@25 156 static void draw_rotation_gizmo()
nuclear@25 157 {
nuclear@25 158 /*static const float axis[][3] = {
nuclear@25 159 {1, 0, 0}, {0, 1, 0}, {0, 0, 1}
nuclear@25 160 };*/
nuclear@25 161
nuclear@25 162 last_rot.normalize();
nuclear@25 163 Matrix4x4 rmat = last_rot.get_rotation_matrix().transposed();
nuclear@25 164 gl_matrix_mode(GL_MODELVIEW);
nuclear@25 165 gl_push_matrix();
nuclear@25 166 gl_mult_matrixf(rmat[0]);
nuclear@25 167
nuclear@25 168 sdr_debug->bind();
nuclear@26 169 gl_apply_xform(sdr_debug->get_globj());
nuclear@25 170
nuclear@25 171 mesh->draw();
nuclear@25 172
nuclear@25 173 gl_pop_matrix();
nuclear@25 174 }
nuclear@25 175
nuclear@25 176 static void draw_disc_wedge(float start, float end, int subdiv)
nuclear@25 177 {
nuclear@25 178 if(start > end) {
nuclear@25 179 float tmp = start;
nuclear@25 180 start = end;
nuclear@25 181 end = tmp;
nuclear@25 182 }
nuclear@25 183
nuclear@25 184 float arc_size = end - start;
nuclear@25 185 subdiv = std::max<int>(subdiv * arc_size, 1);
nuclear@25 186 int nverts = subdiv + 2;
nuclear@25 187
nuclear@25 188 float *varr = (float*)alloca(nverts * 3 * sizeof *varr);
nuclear@25 189 float *vptr = varr;
nuclear@25 190
nuclear@25 191 // start with the center vertex
nuclear@25 192 vptr[0] = vptr[1] = vptr[2] = 0;
nuclear@25 193 vptr += 3;
nuclear@25 194
nuclear@25 195 // then add the arc vertices in sequence
nuclear@25 196 float u = start;
nuclear@25 197 float du = arc_size / (float)subdiv;
nuclear@25 198 for(int i=0; i<subdiv + 1; i++) {
nuclear@25 199 float angle = u * M_PI * 2.0;
nuclear@25 200 vptr[0] = sin(angle);
nuclear@25 201 vptr[1] = cos(angle);
nuclear@25 202 vptr[2] = 0.0;
nuclear@25 203 vptr += 3;
nuclear@25 204 u += du;
nuclear@25 205 }
nuclear@25 206
nuclear@25 207 glEnableVertexAttribArray(SDR_ATTR_VERTEX);
nuclear@25 208 glVertexAttribPointer(SDR_ATTR_VERTEX, 3, GL_FLOAT, 0, 0, varr);
nuclear@25 209
nuclear@25 210 glDrawArrays(GL_TRIANGLE_FAN, 0, nverts);
nuclear@25 211
nuclear@25 212 glDisableVertexAttribArray(SDR_ATTR_VERTEX);
nuclear@25 213 }
nuclear@25 214
nuclear@20 215 extern "C" void game_reshape(int x, int y)
nuclear@0 216 {
nuclear@0 217 win_width = x;
nuclear@0 218 win_height = y;
nuclear@9 219 win_aspect = y ? (float)x / (float)y : 1.0;
nuclear@0 220 glViewport(0, 0, x, y);
nuclear@0 221
nuclear@11 222 gl_matrix_mode(GL_PROJECTION);
nuclear@25 223 glu_perspective(50.0, win_aspect, 0.5, 500.0);
nuclear@0 224 }
nuclear@0 225
nuclear@20 226 extern "C" void game_keyboard(int key, int pressed)
nuclear@0 227 {
nuclear@0 228 if(!pressed) return;
nuclear@0 229
nuclear@0 230 switch(key) {
nuclear@0 231 case 27:
nuclear@0 232 exit(0);
nuclear@0 233
nuclear@0 234 default:
nuclear@0 235 break;
nuclear@0 236 }
nuclear@0 237 }
nuclear@0 238
nuclear@0 239 #define MAX_TOUCH_IDS 16
nuclear@0 240 static struct {
nuclear@0 241 int bnstate[8];
nuclear@0 242 int prev_x, prev_y;
nuclear@0 243 } mstate[MAX_TOUCH_IDS];
nuclear@0 244
nuclear@20 245 extern "C" void game_mouse_button(int id, int bn, int pressed, int x, int y)
nuclear@0 246 {
nuclear@0 247 if(id >= MAX_TOUCH_IDS) return;
nuclear@0 248
nuclear@0 249 mstate[id].prev_x = x;
nuclear@0 250 mstate[id].prev_y = y;
nuclear@0 251 mstate[id].bnstate[bn] = pressed;
nuclear@0 252 }
nuclear@0 253
nuclear@20 254 extern "C" void game_mouse_motion(int id, int x, int y)
nuclear@0 255 {
nuclear@0 256 /*
nuclear@0 257 int dx, dy, cx, cy;
nuclear@0 258
nuclear@0 259 if(id >= MAX_TOUCH_IDS) return;
nuclear@0 260
nuclear@0 261 cx = win_width / 2;
nuclear@0 262 cy = win_height / 2;
nuclear@0 263
nuclear@0 264 dx = x - mstate[id].prev_x;
nuclear@0 265 dy = y - mstate[id].prev_y;
nuclear@0 266 mstate[id].prev_x = x;
nuclear@0 267 mstate[id].prev_y = y;
nuclear@0 268
nuclear@0 269 if(!dx && !dy) return;
nuclear@0 270
nuclear@0 271 if(mouselook || mstate[id].bnstate[0]) {
nuclear@0 272 player_turn(&player, dx * 0.5, dy * 0.5);
nuclear@0 273 }
nuclear@0 274 if(mstate[id].bnstate[2]) {
nuclear@0 275 dbg_cam_dist += 0.1 * dy;
nuclear@0 276 if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0;
nuclear@0 277 }
nuclear@0 278
nuclear@0 279 if(mouselook) {
nuclear@0 280 warping_mouse = 1;
nuclear@0 281 set_mouse_pos(cx, cy);
nuclear@0 282 mstate[id].prev_x = cx;
nuclear@0 283 mstate[id].prev_y = cy;
nuclear@0 284 }
nuclear@0 285 */
nuclear@0 286 }
nuclear@0 287
nuclear@24 288 void game_6dof_translation(float dx, float dy, float dz)
nuclear@24 289 {
nuclear@25 290 last_trans.x = dx;
nuclear@25 291 last_trans.y = dy;
nuclear@25 292 last_trans.z = dz;
nuclear@24 293 }
nuclear@24 294
nuclear@24 295 void game_6dof_rotation(float qx, float qy, float qz, float qw)
nuclear@24 296 {
nuclear@25 297 last_rot.v.x = qx;
nuclear@25 298 last_rot.v.y = qy;
nuclear@25 299 last_rot.v.z = qz;
nuclear@25 300 last_rot.s = qw;
nuclear@25 301
nuclear@25 302 rot.rotate(last_rot);
nuclear@24 303 }