vrheights
changeset 5:053a52f0cb64
console
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 26 Sep 2014 18:40:15 +0300 |
parents | 690ef7fa791f |
children | 608e03b688f8 |
files | src/console.cc src/console.h src/game.cc src/game.h src/main.cc src/opengl.h src/teapot.c vrheights.vcxproj vrheights.vcxproj.filters |
diffstat | 9 files changed, 677 insertions(+), 45 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/console.cc Fri Sep 26 18:40:15 2014 +0300 1.3 @@ -0,0 +1,434 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <stdarg.h> 1.8 +#include <assert.h> 1.9 +#include <algorithm> 1.10 +#include "opengl.h" 1.11 +#include "console.h" 1.12 + 1.13 +Console::Console() 1.14 + : prompt("> ") 1.15 +{ 1.16 + visible = false; 1.17 + nlines = 16; 1.18 + ncolumns = 80; 1.19 + pos_x = pos_y = 0; 1.20 + anchor = TOP_LEFT; 1.21 + 1.22 + inpq_front = inpq_back = 0; 1.23 + 1.24 + max_hist_lines = 64; 1.25 + max_output_lines = 128; 1.26 + 1.27 + hist_iter_valid = false; 1.28 + 1.29 + echo = true; 1.30 + font = 0; 1.31 + font_size = 0; 1.32 + 1.33 + cursor = 0; 1.34 + input_win = 0; 1.35 +} 1.36 + 1.37 +void Console::set_cursor(int x) 1.38 +{ 1.39 + if(x < 0 || x > (int)input.size()) { 1.40 + return; 1.41 + } 1.42 + cursor = x; 1.43 + 1.44 + int max_chars = ncolumns - (int)prompt.size() - 1; 1.45 + 1.46 + if(cursor < input_win) { 1.47 + input_win = cursor; 1.48 + } else if(cursor > input_win + max_chars) { 1.49 + input_win = std::max(cursor - max_chars, 0); 1.50 + } 1.51 +} 1.52 + 1.53 +int Console::get_cursor() const 1.54 +{ 1.55 + return cursor; 1.56 +} 1.57 + 1.58 +void Console::set_font(dtx_font *font, int sz) 1.59 +{ 1.60 + this->font = font; 1.61 + font_size = sz; 1.62 +} 1.63 + 1.64 +void Console::set_history_size(int hsz) 1.65 +{ 1.66 + max_hist_lines = hsz; 1.67 + 1.68 + int drop = hist.size() - hsz; 1.69 + if(drop > 0) { 1.70 + auto it = hist.begin(); 1.71 + for(int i=0; i<drop; i++) { 1.72 + ++it; 1.73 + } 1.74 + hist.erase(hist.begin(), it); 1.75 + } 1.76 +} 1.77 + 1.78 +void Console::set_output_buffer_size(int sz) 1.79 +{ 1.80 + max_output_lines = sz; 1.81 + 1.82 + int drop = output.size() - sz; 1.83 + if(drop > 0) { 1.84 + output.erase(output.begin(), output.begin() + drop); 1.85 + } 1.86 +} 1.87 + 1.88 +void Console::set_command_func(std::function<void (const char*)> func) 1.89 +{ 1.90 + cmd_handler = func; 1.91 +} 1.92 + 1.93 +void Console::set_echo(bool echo) 1.94 +{ 1.95 + this->echo = echo; 1.96 +} 1.97 + 1.98 +bool Console::get_echo() const 1.99 +{ 1.100 + return echo; 1.101 +} 1.102 + 1.103 +void Console::set_visible(bool v) 1.104 +{ 1.105 + visible = v; 1.106 +} 1.107 + 1.108 +bool Console::is_visible() const 1.109 +{ 1.110 + return visible; 1.111 +} 1.112 + 1.113 +void Console::set_size(int lines, int columns) 1.114 +{ 1.115 + nlines = lines; 1.116 + ncolumns = columns; 1.117 +} 1.118 + 1.119 +int Console::get_size_lines() const 1.120 +{ 1.121 + return nlines; 1.122 +} 1.123 + 1.124 +int Console::get_size_columns() const 1.125 +{ 1.126 + return ncolumns; 1.127 +} 1.128 + 1.129 +void Console::set_position(int x, int y, Anchor anchor) 1.130 +{ 1.131 + pos_x = x; 1.132 + pos_y = y; 1.133 + this->anchor = anchor; 1.134 +} 1.135 + 1.136 +bool Console::update() 1.137 +{ 1.138 + bool must_redraw = false; 1.139 + 1.140 + while(inpq_front != inpq_back) { 1.141 + int c = keybuf[inpq_front]; 1.142 + inpq_front = (inpq_front + 1) % INPUTQ_SIZE; 1.143 + 1.144 + switch(c) { 1.145 + case '\n': 1.146 + case '\r': 1.147 + if(echo) { 1.148 + puts(input.c_str()); 1.149 + putchar('\n'); 1.150 + } 1.151 + if(!input.empty() && cmd_handler) { 1.152 + cmd_handler(input.c_str()); 1.153 + } 1.154 + 1.155 + hist.push_back(std::move(input)); // move the input string into the history buffer 1.156 + if((int)hist.size() > max_hist_lines) { 1.157 + hist.pop_front(); 1.158 + } 1.159 + hist_iter_valid = false; 1.160 + 1.161 + set_cursor(0); 1.162 + must_redraw = true; 1.163 + break; 1.164 + 1.165 + case '\t': 1.166 + // TODO: completion 1.167 + break; 1.168 + 1.169 + case '\b': 1.170 + if(!input.empty()) { 1.171 + if(cursor == (int)input.size()) { 1.172 + input.pop_back(); 1.173 + set_cursor(get_cursor() - 1); 1.174 + must_redraw = true; 1.175 + } else if(cursor > 0) { 1.176 + input.erase(cursor - 1, 1); 1.177 + set_cursor(get_cursor() - 1); 1.178 + must_redraw = true; 1.179 + } 1.180 + } 1.181 + break; 1.182 + 1.183 + case KEY_UP: 1.184 + if(!hist.empty()) { 1.185 + if(!hist_iter_valid) { 1.186 + hist_iter = hist.rbegin(); 1.187 + hist_iter_valid = true; 1.188 + input = *hist_iter; 1.189 + } else { 1.190 + if(++hist_iter == hist.rend()) { 1.191 + --hist_iter; 1.192 + break; 1.193 + } 1.194 + input = *hist_iter; 1.195 + } 1.196 + set_cursor(input.size()); 1.197 + } 1.198 + break; 1.199 + 1.200 + case KEY_DOWN: 1.201 + if(!hist.empty()) { 1.202 + if(!hist_iter_valid) { 1.203 + hist_iter = hist.rbegin(); 1.204 + hist_iter_valid = true; 1.205 + } 1.206 + if(hist_iter != hist.rbegin()) { 1.207 + input = *--hist_iter; 1.208 + set_cursor(input.size()); 1.209 + } 1.210 + } 1.211 + break; 1.212 + 1.213 + case KEY_LEFT: 1.214 + if(cursor > 0) { 1.215 + set_cursor(get_cursor() - 1); 1.216 + must_redraw = true; 1.217 + } 1.218 + break; 1.219 + 1.220 + case KEY_RIGHT: 1.221 + if(cursor < (int)input.size()) { 1.222 + set_cursor(get_cursor() + 1); 1.223 + must_redraw = true; 1.224 + } 1.225 + break; 1.226 + 1.227 + case KEY_HOME: 1.228 + set_cursor(0); 1.229 + must_redraw = true; 1.230 + break; 1.231 + 1.232 + case KEY_END: 1.233 + set_cursor(input.size()); 1.234 + must_redraw = true; 1.235 + break; 1.236 + 1.237 + case KEY_PGUP: 1.238 + case KEY_PGDOWN: 1.239 + // TODO scroll output buffer 1.240 + break; 1.241 + 1.242 + default: 1.243 + if(c < 256 && isprint(c)) { 1.244 + if(cursor == (int)input.size()) { 1.245 + input.push_back(c); 1.246 + } else { 1.247 + input.insert(cursor, 1, c); 1.248 + } 1.249 + set_cursor(get_cursor() + 1); 1.250 + must_redraw = true; 1.251 + } 1.252 + } 1.253 + } 1.254 + return must_redraw; 1.255 +} 1.256 + 1.257 +void Console::draw() const 1.258 +{ 1.259 + if(!font || !visible) return; 1.260 + dtx_use_font(font, font_size); 1.261 + 1.262 + std::string buflines; 1.263 + 1.264 + int num_lines = std::min(nlines, (int)output.size()); 1.265 + auto it = output.cbegin() + (output.size() - num_lines); 1.266 + 1.267 + float max_width = dtx_glyph_width('Q') * ncolumns; 1.268 + 1.269 + while(it != output.cend()) { 1.270 + const std::string &line = *it++; 1.271 + buflines += line + std::string("\n"); 1.272 + 1.273 + //max_width = std::max(max_width, dtx_string_width(line.c_str())); 1.274 + } 1.275 + 1.276 + // draw the output box 1.277 + float line_height = dtx_line_height(); 1.278 + float outbox_height = nlines * line_height; 1.279 + float console_height = outbox_height + line_height * 1.5; 1.280 + 1.281 + 1.282 + int vp[4]; 1.283 + glGetIntegerv(GL_VIEWPORT, vp); 1.284 + 1.285 + int px, py; 1.286 + switch(anchor) { 1.287 + case TOP_LEFT: 1.288 + px = pos_x; 1.289 + py = pos_y; 1.290 + break; 1.291 + 1.292 + case BOTTOM_LEFT: 1.293 + px = pos_x; 1.294 + py = vp[3] - console_height - pos_y; 1.295 + break; 1.296 + 1.297 + case CENTER: 1.298 + px = (vp[2] - max_width) / 2 + pos_x; 1.299 + py = (vp[3] - console_height) / 2 + pos_y; 1.300 + break; 1.301 + } 1.302 + 1.303 + glMatrixMode(GL_PROJECTION); 1.304 + glPushMatrix(); 1.305 + glLoadIdentity(); 1.306 + glOrtho(0, vp[2], 0, vp[3], -1, 1); 1.307 + 1.308 + glMatrixMode(GL_MODELVIEW); 1.309 + glPushMatrix(); 1.310 + glLoadIdentity(); 1.311 + glTranslatef(px, vp[3] - py, 0); 1.312 + 1.313 + 1.314 + glPushAttrib(GL_ENABLE_BIT); 1.315 + glDisable(GL_DEPTH_TEST); 1.316 + glDisable(GL_LIGHTING); 1.317 + glDisable(GL_STENCIL_TEST); 1.318 + glEnable(GL_BLEND); 1.319 + glDisable(GL_TEXTURE_2D); 1.320 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.321 + 1.322 + glEnable(GL_SCISSOR_TEST); 1.323 + glScissor(vp[0] + px, vp[1] + (vp[3] - py) - console_height, max_width, console_height); 1.324 + 1.325 + glBegin(GL_QUADS); 1.326 + glColor4f(0.1, 0.2, 0.5, 0.7); 1.327 + glVertex2f(0, -outbox_height); 1.328 + glVertex2f(max_width, -outbox_height); 1.329 + glVertex2f(max_width, 0); 1.330 + glVertex2f(0, 0); 1.331 + 1.332 + glColor4f(0.5, 0.2, 0.1, 0.7); 1.333 + glVertex2f(0, -console_height); 1.334 + glVertex2f(max_width, -console_height); 1.335 + glVertex2f(max_width, -outbox_height); 1.336 + glVertex2f(0, -outbox_height); 1.337 + glEnd(); 1.338 + 1.339 + // draw the output text 1.340 + glPushMatrix(); 1.341 + glTranslatef(0, -line_height, 0); 1.342 + glColor4f(1, 1, 1, 0.7); 1.343 + dtx_string(buflines.c_str()); 1.344 + glPopMatrix(); 1.345 + 1.346 + // draw the input line 1.347 + glTranslatef(0, -outbox_height - line_height, 0); 1.348 + 1.349 + std::string inpline = prompt + input.substr(input_win); 1.350 + dtx_string(inpline.c_str()); 1.351 + glDisable(GL_TEXTURE_2D); 1.352 + 1.353 + float cursor_x = dtx_char_pos(inpline.c_str(), cursor - input_win + prompt.size()); 1.354 + glBegin(GL_QUADS); 1.355 + glColor4f(1, 1, 1, 0.7); 1.356 + glVertex2f(cursor_x, -2); 1.357 + glVertex2f(cursor_x + 2, -2); 1.358 + glVertex2f(cursor_x + 2, line_height - 2); 1.359 + glVertex2f(cursor_x, line_height - 2); 1.360 + glEnd(); 1.361 + 1.362 + glPopAttrib(); 1.363 + 1.364 + glMatrixMode(GL_PROJECTION); 1.365 + glPopMatrix(); 1.366 + glMatrixMode(GL_MODELVIEW); 1.367 + glPopMatrix(); 1.368 +} 1.369 + 1.370 +void Console::input_key(int key) 1.371 +{ 1.372 + keybuf[inpq_back] = key; 1.373 + inpq_back = (inpq_back + 1) % INPUTQ_SIZE; 1.374 +} 1.375 + 1.376 +void Console::putchar(char c) 1.377 +{ 1.378 + if(output.empty()) { 1.379 + output.push_back(std::string("")); 1.380 + } 1.381 + 1.382 + if(c == '\n' || c == '\r') { 1.383 + output.push_back(std::string("")); 1.384 + if((int)output.size() > max_output_lines) { 1.385 + output.erase(output.begin()); 1.386 + } 1.387 + } else { 1.388 + output.back().push_back(c); 1.389 + } 1.390 +} 1.391 + 1.392 +void Console::puts(const char *str) 1.393 +{ 1.394 + while(*str) { 1.395 + putchar(*str++); 1.396 + } 1.397 +} 1.398 + 1.399 +void Console::printf(const char *fmt, ...) 1.400 +{ 1.401 + static char buf[1024]; 1.402 + va_list ap; 1.403 + 1.404 + va_start(ap, fmt); 1.405 + vsnprintf(buf, sizeof buf, fmt, ap); 1.406 + va_end(ap); 1.407 + 1.408 + puts(buf); 1.409 +} 1.410 + 1.411 +void Console::debug() 1.412 +{ 1.413 + fprintf(stderr, "visible: %s\n", visible ? "true" : "false"); 1.414 + fprintf(stderr, "size: %d lines x %d columns\n", nlines, ncolumns); 1.415 + fprintf(stderr, "cursor: %d\n", cursor); 1.416 + 1.417 + int qsize = 0; 1.418 + int qidx = inpq_front; 1.419 + while(qidx != inpq_back) { 1.420 + qsize++; 1.421 + qidx = (qidx + 1) % INPUTQ_SIZE; 1.422 + } 1.423 + 1.424 + fprintf(stderr, "input queue size: %d\n", qsize); 1.425 + fprintf(stderr, "current input line: \"%s\"\n", input.c_str()); 1.426 + fprintf(stderr, "%d saved inputs in the history (max %d)\n", (int)hist.size(), max_hist_lines); 1.427 + auto it = hist.begin(); 1.428 + int idx = 0; 1.429 + while(it != hist.end()) { 1.430 + fprintf(stderr, " h(%d): \"%s\"\n", idx++, it++->c_str()); 1.431 + } 1.432 + 1.433 + fprintf(stderr, "output buffer (lines: %d/%d):\n", (int)output.size(), max_output_lines); 1.434 + for(size_t i=0; i<output.size(); i++) { 1.435 + fprintf(stderr, "o(%d): \"%s\"\n", (int)i, output[i].c_str()); 1.436 + } 1.437 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/console.h Fri Sep 26 18:40:15 2014 +0300 2.3 @@ -0,0 +1,96 @@ 2.4 +#ifndef CONSOLE_H_ 2.5 +#define CONSOLE_H_ 2.6 + 2.7 +#include <vector> 2.8 +#include <list> 2.9 +#include <string> 2.10 +#include <functional> 2.11 +#include <drawtext.h> 2.12 + 2.13 +#define INPUTQ_SIZE 64 2.14 + 2.15 +class Console { 2.16 +public: 2.17 + enum Anchor {TOP_LEFT, BOTTOM_LEFT, CENTER}; 2.18 + 2.19 +private: 2.20 + bool visible; 2.21 + int nlines, ncolumns; 2.22 + int pos_x, pos_y; 2.23 + Anchor anchor; 2.24 + 2.25 + int inpq_front, inpq_back; 2.26 + int keybuf[INPUTQ_SIZE]; 2.27 + 2.28 + std::string prompt; 2.29 + std::string input; // current input line 2.30 + int cursor; 2.31 + int input_win; // first character to show in the input "window" 2.32 + 2.33 + // input history 2.34 + int max_hist_lines; 2.35 + std::list<std::string> hist; 2.36 + bool hist_iter_valid; 2.37 + std::list<std::string>::const_reverse_iterator hist_iter; 2.38 + 2.39 + // console output 2.40 + int max_output_lines; 2.41 + std::vector<std::string> output; 2.42 + bool echo; 2.43 + 2.44 + std::function<void (const char*)> cmd_handler; 2.45 + 2.46 + int font_size; 2.47 + dtx_font *font; 2.48 + 2.49 + void set_cursor(int x); 2.50 + int get_cursor() const; 2.51 + 2.52 +public: 2.53 + enum { 2.54 + KEY_LEFT = 256, 2.55 + KEY_RIGHT, 2.56 + KEY_UP, KEY_DOWN, 2.57 + KEY_INS, 2.58 + KEY_DEL, 2.59 + KEY_HOME, 2.60 + KEY_END, 2.61 + KEY_PGUP, 2.62 + KEY_PGDOWN 2.63 + }; 2.64 + 2.65 + Console(); 2.66 + 2.67 + void set_font(dtx_font *font, int sz); 2.68 + void set_history_size(int hsz); 2.69 + void set_output_buffer_size(int sz); 2.70 + void set_command_func(std::function<void (const char*)> func); 2.71 + 2.72 + void set_echo(bool echo); 2.73 + bool get_echo() const; 2.74 + 2.75 + void show() { set_visible(true); } 2.76 + void hide() { set_visible(false); } 2.77 + void set_visible(bool v); 2.78 + bool is_visible() const; 2.79 + 2.80 + void set_size(int lines, int columns = 80); 2.81 + int get_size_lines() const; 2.82 + int get_size_columns() const; 2.83 + 2.84 + void set_position(int x, int y, Anchor anchor = TOP_LEFT); 2.85 + 2.86 + // update returns true if what it did makes a redraw necessary 2.87 + bool update(); 2.88 + void draw() const; 2.89 + 2.90 + void input_key(int key); // send a keystroke to the console 2.91 + 2.92 + void putchar(char c); 2.93 + void puts(const char *str); 2.94 + void printf(const char *fmt, ...); 2.95 + 2.96 + void debug(); 2.97 +}; 2.98 + 2.99 +#endif // CONSOLE_H_
3.1 --- a/src/game.cc Fri Sep 26 13:19:22 2014 +0300 3.2 +++ b/src/game.cc Fri Sep 26 18:40:15 2014 +0300 3.3 @@ -6,6 +6,8 @@ 3.4 #include "game.h" 3.5 #include "goatvr.h" 3.6 #include "teapot.h" 3.7 +#include "console.h" 3.8 +#include "drawtext.h" 3.9 3.10 static void draw_scene(); 3.11 static void material(float r, float g, float b, float roughness); 3.12 @@ -13,16 +15,23 @@ 3.13 static void create_rtarg(int x, int y); 3.14 static int next_pow2(int x); 3.15 3.16 +bool opt_separate_walk_look; 3.17 + 3.18 static int win_width, win_height; 3.19 static unsigned int fb_tex; 3.20 static unsigned int fbo, fb_depth; 3.21 static int fb_xsz, fb_ysz; 3.22 static int fb_tex_xsz, fb_tex_ysz; 3.23 3.24 +static unsigned int chess_tex; 3.25 + 3.26 static float cam_theta, cam_phi; 3.27 static Vector3 cam_pos; 3.28 static bool keystate[256]; 3.29 3.30 +static Console con; 3.31 +static dtx_font *con_font; 3.32 + 3.33 bool game_init() 3.34 { 3.35 init_opengl(); 3.36 @@ -35,6 +44,24 @@ 3.37 glEnable(GL_CULL_FACE); 3.38 glEnable(GL_LIGHTING); 3.39 3.40 + unsigned char chess_pixels[] = { 3.41 + 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 3.42 + 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff 3.43 + }; 3.44 + glGenTextures(1, &chess_tex); 3.45 + glBindTexture(GL_TEXTURE_2D, chess_tex); 3.46 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3.47 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3.48 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, chess_pixels); 3.49 + 3.50 + if(!(con_font = dtx_open_font_glyphmap("data/mono14.glyphmap"))) { 3.51 + fprintf(stderr, "failed to open console font\n"); 3.52 + return false; 3.53 + } 3.54 + con.set_size(6, 40); 3.55 + con.set_font(con_font, 14); 3.56 + con.set_position(0, 0, Console::CENTER); 3.57 + 3.58 return true; 3.59 } 3.60 3.61 @@ -49,7 +76,12 @@ 3.62 float dt = (tm - prev_upd) / 1000.0; 3.63 prev_upd = tm; 3.64 3.65 - float offs = dt * 1.0; 3.66 + if(con.is_visible()) { 3.67 + con.update(); 3.68 + return; 3.69 + } 3.70 + 3.71 + float offs = dt * 5.0; 3.72 Vector3 dir; 3.73 3.74 if(keystate['d'] || keystate['D']) { 3.75 @@ -65,8 +97,13 @@ 3.76 dir += Vector3(0, 0, offs); 3.77 } 3.78 3.79 - cam_pos.x += dir.x * cos(cam_theta) - dir.y * sin(cam_theta); 3.80 - cam_pos.z += dir.x * sin(cam_theta) + dir.y * cos(cam_theta); 3.81 + float cos_theta = cos(DEG_TO_RAD(cam_theta)); 3.82 + float sin_theta = sin(DEG_TO_RAD(cam_theta)); 3.83 + cam_pos.x += dir.x * cos_theta - dir.z * sin_theta; 3.84 + cam_pos.z += dir.x * sin_theta + dir.z * cos_theta; 3.85 + 3.86 + if(!opt_separate_walk_look) { 3.87 + } 3.88 } 3.89 3.90 void game_display() 3.91 @@ -96,6 +133,7 @@ 3.92 glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); 3.93 3.94 draw_scene(); 3.95 + con.draw(); 3.96 3.97 vr_end(); 3.98 } 3.99 @@ -112,7 +150,7 @@ 3.100 win_width = x; 3.101 win_height = y; 3.102 3.103 - create_rtarg(vr_geti_def(VR_RENDER_XRES, x), vr_geti_def(VR_RENDER_YRES, y)); 3.104 + create_rtarg(vr_geti_def(VR_RENDER_XRES, x * 2), vr_geti_def(VR_RENDER_YRES, y)); 3.105 vr_output_texture(fb_tex, 0, 0, (float)fb_xsz / (float)fb_tex_xsz, (float)fb_ysz / (float)fb_tex_ysz); 3.106 3.107 /* these might be overriden in VR mode (see game_display) */ 3.108 @@ -125,21 +163,33 @@ 3.109 void game_keyboard(int key, bool pressed) 3.110 { 3.111 if(pressed) { 3.112 - switch(key) { 3.113 - case 27: 3.114 - exit_game(); 3.115 - break; 3.116 + if(con.is_visible()) { 3.117 + if(key == 27 || key == '`') { 3.118 + con.hide(); 3.119 + } else { 3.120 + con.input_key(key); 3.121 + } 3.122 + } else { 3.123 + switch(key) { 3.124 + case 27: 3.125 + exit_game(); 3.126 + break; 3.127 3.128 - case 'f': 3.129 - toggle_hmd_fullscr(); 3.130 - break; 3.131 + case 'f': 3.132 + toggle_hmd_fullscr(); 3.133 + break; 3.134 3.135 - case 'r': 3.136 - vr_recenter(); 3.137 - break; 3.138 + case 'r': 3.139 + vr_recenter(); 3.140 + break; 3.141 3.142 - default: 3.143 - break; 3.144 + case '`': 3.145 + con.show(); 3.146 + break; 3.147 + 3.148 + default: 3.149 + break; 3.150 + } 3.151 } 3.152 } 3.153 3.154 @@ -197,14 +247,17 @@ 3.155 3.156 glMatrixMode(GL_MODELVIEW); 3.157 3.158 + glBindTexture(GL_TEXTURE_2D, chess_tex); 3.159 + glEnable(GL_TEXTURE_2D); 3.160 material(1, 1, 1, 1); 3.161 glBegin(GL_QUADS); 3.162 glNormal3f(0, 1, 0); 3.163 - glVertex3f(-10, 0, 10); 3.164 - glVertex3f(10, 0, 10); 3.165 - glVertex3f(10, 0, -10); 3.166 - glVertex3f(-10, 0, -10); 3.167 + glTexCoord2f(0, 0); glVertex3f(-10, 0, 10); 3.168 + glTexCoord2f(1, 0); glVertex3f(10, 0, 10); 3.169 + glTexCoord2f(1, 1); glVertex3f(10, 0, -10); 3.170 + glTexCoord2f(0, 1); glVertex3f(-10, 0, -10); 3.171 glEnd(); 3.172 + glDisable(GL_TEXTURE_2D); 3.173 3.174 material(1, 1, 1, 0.4); 3.175 glPushMatrix(); 3.176 @@ -272,6 +325,8 @@ 3.177 fb_tex_xsz = next_pow2(fb_xsz); 3.178 fb_tex_ysz = next_pow2(fb_ysz); 3.179 3.180 + printf("creating %dx%d render target (tex size: %dx%d)\n", fb_xsz, fb_ysz, fb_tex_xsz, fb_tex_ysz); 3.181 + 3.182 if(!fbo) { 3.183 glGenFramebuffers(1, &fbo); 3.184
4.1 --- a/src/game.h Fri Sep 26 13:19:22 2014 +0300 4.2 +++ b/src/game.h Fri Sep 26 18:40:15 2014 +0300 4.3 @@ -1,6 +1,8 @@ 4.4 #ifndef GAME_H_ 4.5 #define GAME_H_ 4.6 4.7 +extern bool opt_separate_walk_look; 4.8 + 4.9 bool game_init(); 4.10 void game_cleanup(); 4.11
5.1 --- a/src/main.cc Fri Sep 26 13:19:22 2014 +0300 5.2 +++ b/src/main.cc Fri Sep 26 18:40:15 2014 +0300 5.3 @@ -124,6 +124,10 @@ 5.4 game_mouse_motion(ev->motion.x, ev->motion.y); 5.5 break; 5.6 5.7 + case SDL_QUIT: 5.8 + exit_game(); 5.9 + break; 5.10 + 5.11 default: 5.12 break; 5.13 }
6.1 --- a/src/opengl.h Fri Sep 26 13:19:22 2014 +0300 6.2 +++ b/src/opengl.h Fri Sep 26 18:40:15 2014 +0300 6.3 @@ -3,6 +3,8 @@ 6.4 6.5 #include <GL/glew.h> 6.6 6.7 +#ifdef __cplusplus 6.8 bool init_opengl(); 6.9 +#endif 6.10 6.11 #endif /* OPENGL_H_ */
7.1 --- a/src/teapot.c Fri Sep 26 13:19:22 2014 +0300 7.2 +++ b/src/teapot.c Fri Sep 26 18:40:15 2014 +0300 7.3 @@ -1,9 +1,4 @@ 7.4 -#ifndef __APPLE__ 7.5 -#include <GL/gl.h> 7.6 -#else 7.7 -#include <OpenGL/gl.h> 7.8 -#endif 7.9 - 7.10 +#include "opengl.h" 7.11 #include "teapot.h" 7.12 #include "teapot_data.h" 7.13 7.14 @@ -11,27 +6,41 @@ 7.15 7.16 int patch_subdivision = 6; 7.17 7.18 +static int dlist_sub[32]; 7.19 + 7.20 void bezier_teapot(float scale) 7.21 { 7.22 int i; 7.23 7.24 + glMatrixMode(GL_MODELVIEW); 7.25 + 7.26 + if(!dlist_sub[patch_subdivision]) { 7.27 + dlist_sub[patch_subdivision] = glGenLists(1); 7.28 + glNewList(dlist_sub[patch_subdivision], GL_COMPILE); 7.29 + 7.30 + for(i=0; i<NUM_TEAPOT_PATCHES; i++) { 7.31 + float flip = teapot_part_flip[i]; 7.32 + float rot = teapot_part_rot[i]; 7.33 + 7.34 + glPushMatrix(); 7.35 + glTranslatef(0, -3.15 * 0.5, 0); 7.36 + glRotatef(rot, 0, 1, 0); 7.37 + glScalef(1, 1, flip); 7.38 + glRotatef(-90, 1, 0, 0); 7.39 + 7.40 + draw_patch(teapot_verts, teapot_index + i * 16, flip < 0.0 ? 1 : 0, patch_subdivision, patch_subdivision, 1.0); 7.41 + 7.42 + glPopMatrix(); 7.43 + } 7.44 + 7.45 + glEndList(); 7.46 + } 7.47 + 7.48 scale /= 2.0; 7.49 - 7.50 - for(i=0; i<NUM_TEAPOT_PATCHES; i++) { 7.51 - float flip = teapot_part_flip[i]; 7.52 - float rot = teapot_part_rot[i]; 7.53 - 7.54 - glMatrixMode(GL_MODELVIEW); 7.55 - glPushMatrix(); 7.56 - glTranslatef(0, -3.15 * scale * 0.5, 0); 7.57 - glRotatef(rot, 0, 1, 0); 7.58 - glScalef(1, 1, flip); 7.59 - glRotatef(-90, 1, 0, 0); 7.60 - 7.61 - draw_patch(teapot_verts, teapot_index + i * 16, flip < 0.0 ? 1 : 0, patch_subdivision, patch_subdivision, scale); 7.62 - 7.63 - glPopMatrix(); 7.64 - } 7.65 + glPushMatrix(); 7.66 + glScalef(scale, scale, scale); 7.67 + glCallList(dlist_sub[patch_subdivision]); 7.68 + glPopMatrix(); 7.69 } 7.70 7.71 static void draw_patch(struct vec3 *bez_cp, int *index, int flip, int useg, int vseg, float scale)
8.1 --- a/vrheights.vcxproj Fri Sep 26 13:19:22 2014 +0300 8.2 +++ b/vrheights.vcxproj Fri Sep 26 18:40:15 2014 +0300 8.3 @@ -52,11 +52,12 @@ 8.4 <WarningLevel>Level3</WarningLevel> 8.5 <Optimization>Disabled</Optimization> 8.6 <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 8.7 + <DisableSpecificWarnings>4244;4305;4996</DisableSpecificWarnings> 8.8 </ClCompile> 8.9 <Link> 8.10 - <SubSystem>Windows</SubSystem> 8.11 + <SubSystem>Console</SubSystem> 8.12 <GenerateDebugInformation>true</GenerateDebugInformation> 8.13 - <AdditionalDependencies>SDL2.lib;SDL2main.lib;opengl32.lib;glew32.lib;libgoatvr.lib;goat3d.lib;%(AdditionalDependencies)</AdditionalDependencies> 8.14 + <AdditionalDependencies>SDL2.lib;SDL2main.lib;opengl32.lib;glu32.lib;glew32.lib;libgoatvr.lib;libvmath.lib;libdrawtext.lib;%(AdditionalDependencies)</AdditionalDependencies> 8.15 </Link> 8.16 </ItemDefinitionGroup> 8.17 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 8.18 @@ -68,23 +69,31 @@ 8.19 <FunctionLevelLinking>true</FunctionLevelLinking> 8.20 <IntrinsicFunctions>true</IntrinsicFunctions> 8.21 <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 8.22 + <DisableSpecificWarnings>4244;4305;4996</DisableSpecificWarnings> 8.23 </ClCompile> 8.24 <Link> 8.25 <SubSystem>Windows</SubSystem> 8.26 <GenerateDebugInformation>true</GenerateDebugInformation> 8.27 <EnableCOMDATFolding>true</EnableCOMDATFolding> 8.28 <OptimizeReferences>true</OptimizeReferences> 8.29 - <AdditionalDependencies>SDL2.lib;SDL2main.lib;opengl32.lib;glew32.lib;libgoatvr.lib;goat3d.lib;%(AdditionalDependencies)</AdditionalDependencies> 8.30 + <AdditionalDependencies>SDL2.lib;SDL2main.lib;opengl32.lib;glu32.lib;glew32.lib;libgoatvr.lib;libvmath.lib;libdrawtext.lib;%(AdditionalDependencies)</AdditionalDependencies> 8.31 </Link> 8.32 </ItemDefinitionGroup> 8.33 <ItemGroup> 8.34 + <ClCompile Include="src\bezmath.c" /> 8.35 + <ClCompile Include="src\console.cc" /> 8.36 <ClCompile Include="src\game.cc" /> 8.37 <ClCompile Include="src\main.cc" /> 8.38 <ClCompile Include="src\opengl.cc" /> 8.39 + <ClCompile Include="src\teapot.c" /> 8.40 </ItemGroup> 8.41 <ItemGroup> 8.42 + <ClInclude Include="src\bezmath.h" /> 8.43 + <ClInclude Include="src\console.h" /> 8.44 <ClInclude Include="src\game.h" /> 8.45 <ClInclude Include="src\opengl.h" /> 8.46 + <ClInclude Include="src\teapot.h" /> 8.47 + <ClInclude Include="src\teapot_data.h" /> 8.48 </ItemGroup> 8.49 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 8.50 <ImportGroup Label="ExtensionTargets">
9.1 --- a/vrheights.vcxproj.filters Fri Sep 26 13:19:22 2014 +0300 9.2 +++ b/vrheights.vcxproj.filters Fri Sep 26 18:40:15 2014 +0300 9.3 @@ -16,6 +16,15 @@ 9.4 <ClCompile Include="src\opengl.cc"> 9.5 <Filter>src</Filter> 9.6 </ClCompile> 9.7 + <ClCompile Include="src\bezmath.c"> 9.8 + <Filter>src</Filter> 9.9 + </ClCompile> 9.10 + <ClCompile Include="src\teapot.c"> 9.11 + <Filter>src</Filter> 9.12 + </ClCompile> 9.13 + <ClCompile Include="src\console.cc"> 9.14 + <Filter>src</Filter> 9.15 + </ClCompile> 9.16 </ItemGroup> 9.17 <ItemGroup> 9.18 <ClInclude Include="src\game.h"> 9.19 @@ -24,5 +33,17 @@ 9.20 <ClInclude Include="src\opengl.h"> 9.21 <Filter>src</Filter> 9.22 </ClInclude> 9.23 + <ClInclude Include="src\bezmath.h"> 9.24 + <Filter>src</Filter> 9.25 + </ClInclude> 9.26 + <ClInclude Include="src\teapot.h"> 9.27 + <Filter>src</Filter> 9.28 + </ClInclude> 9.29 + <ClInclude Include="src\teapot_data.h"> 9.30 + <Filter>src</Filter> 9.31 + </ClInclude> 9.32 + <ClInclude Include="src\console.h"> 9.33 + <Filter>src</Filter> 9.34 + </ClInclude> 9.35 </ItemGroup> 9.36 </Project> 9.37 \ No newline at end of file