diff --git a/tests/caveview/cave_main.c b/tests/caveview/cave_main.c new file mode 100644 index 0000000..ad89f85 --- /dev/null +++ b/tests/caveview/cave_main.c @@ -0,0 +1,659 @@ +#define _WIN32_WINNT 0x400 + +#include +#include +#include +#include + +//#include "game.h" + +#include + +#define STB_GL_IMPLEMENTATION +#define STB_GLEXT_DEFINE "glext_list.h" +#include "stb_gl.h" + +#define STB_DEFINE +#include "stb.h" + +#include "caveview.h" + +#include "sdl.h" +#include "SDL_opengl.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#define STB_GLPROG_IMPLEMENTATION +#define STB_GLPROG_ARB_DEFINE_EXTENSIONS +#include "stb_glprog.h" + +#include "stb_easy_font.h" // doesn't require an IMPLEMENTATION + +#include "caveview.h" + +char *game_name = "caveview"; + +// assume only a single texture with all sprites +float texture_s_scale; +float texture_t_scale; +GLuint interface_tex, logo_tex; + +extern int screen_x, screen_y; // main.c + +void print_string(float x, float y, char *text, float r, float g, float b) +{ + static char buffer[99999]; + int num_quads; + + num_quads = stb_easy_font_print(x, y, text, NULL, buffer, sizeof(buffer)); + + glColor3f(r,g,b); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 16, buffer); + glDrawArrays(GL_QUADS, 0, num_quads*4); + glDisableClientState(GL_VERTEX_ARRAY); +} + +float text_color[3]; +float pos_x = 10; +float pos_y = 10; + +void print(char *text, ...) +{ + char buffer[999]; + va_list va; + va_start(va, text); + vsprintf(buffer, text, va); + va_end(va); + print_string(pos_x, pos_y, buffer, text_color[0], text_color[1], text_color[2]); + pos_y += 10; +} + +// mouse offsetting 'pixel to virtual' +float xs_p2v, ys_p2v;// xoff_p2v, yoff_p2v; + +// viewport offseting 'virtual to pixel' +float xs_v2p, ys_v2p, xoff_v2p, yoff_v2p; + +float camang[3], camloc[3] = { 0,0,75 }; +float player_zoom = 1.0; +int third_person; +float rotate_view = 0.0; + +#define REVERSE_DEPTH + + +void init_game(void) +{ +// init_graphics(); +} + +void camera_to_worldspace(float world[3], float cam_x, float cam_y, float cam_z) +{ + float vec[3] = { cam_x, cam_y, cam_z }; + float t[3]; + float s,c; + s = (float) sin(camang[0]*3.141592/180); + c = (float) cos(camang[0]*3.141592/180); + + t[0] = vec[0]; + t[1] = c*vec[1] - s*vec[2]; + t[2] = s*vec[1] + c*vec[2]; + + s = (float) sin(camang[2]*3.141592/180); + c = (float) cos(camang[2]*3.141592/180); + world[0] = c*t[0] - s*t[1]; + world[1] = s*t[0] + c*t[1]; + world[2] = t[2]; +} + +// camera worldspace velocity +float cam_vel[3]; + +int controls; + +#define MAX_VEL 150.0f // blocks per second +#define ACCEL 6.0f +#define DECEL 3.0f + +#define STATIC_FRICTION DECEL +#define EFFECTIVE_ACCEL (ACCEL+DECEL) + +// dynamic friction: +// +// if going at MAX_VEL, ACCEL and friction must cancel +// EFFECTIVE_ACCEL = DECEL + DYNAMIC_FRIC*MAX_VEL +#define DYNAMIC_FRICTION (ACCEL/(float)MAX_VEL) + +float view_x_vel = 0; +float view_z_vel = 0; +float pending_view_x; +float pending_view_z; +float pending_view_x; +float pending_view_z; + +void process_tick_raw(float dt) +{ + int i; + float thrust[3] = { 0,0,0 }; + float world_thrust[3]; + + // choose direction to apply thrust + + thrust[0] = (controls & 3)== 1 ? EFFECTIVE_ACCEL : (controls & 3)== 2 ? -EFFECTIVE_ACCEL : 0; + thrust[1] = (controls & 12)== 4 ? EFFECTIVE_ACCEL : (controls & 12)== 8 ? -EFFECTIVE_ACCEL : 0; + thrust[2] = (controls & 48)==16 ? EFFECTIVE_ACCEL : (controls & 48)==32 ? -EFFECTIVE_ACCEL : 0; + + // @TODO clamp thrust[0] & thrust[1] vector length to EFFECTIVE_ACCEL + + camera_to_worldspace(world_thrust, thrust[0], thrust[1], 0); + world_thrust[2] += thrust[2]; + + for (i=0; i < 3; ++i) { + float acc = world_thrust[i]; + cam_vel[i] += acc*dt; + } + + if (cam_vel[0] || cam_vel[1] || cam_vel[2]) + { + float vel = (float) sqrt(cam_vel[0]*cam_vel[0] + cam_vel[1]*cam_vel[1] + cam_vel[2]*cam_vel[2]); + float newvel = vel; + float dec = STATIC_FRICTION + DYNAMIC_FRICTION*vel; + newvel = vel - dec*dt; + if (newvel < 0) + newvel = 0; + cam_vel[0] *= newvel/vel; + cam_vel[1] *= newvel/vel; + cam_vel[2] *= newvel/vel; + } + + camloc[0] += cam_vel[0] * dt; + camloc[1] += cam_vel[1] * dt; + camloc[2] += cam_vel[2] * dt; + + view_x_vel *= (float) pow(0.75, dt); + view_z_vel *= (float) pow(0.75, dt); + + view_x_vel += (pending_view_x - view_x_vel)*dt*60; + view_z_vel += (pending_view_z - view_z_vel)*dt*60; + + pending_view_x -= view_x_vel * dt; + pending_view_z -= view_z_vel * dt; + camang[0] += view_x_vel * dt; + camang[2] += view_z_vel * dt; + camang[0] = stb_clamp(camang[0], -90, 90); + camang[2] = (float) fmod(camang[2], 360); +} + +void process_tick(float dt) +{ + while (dt > 1.0f/60) { + process_tick_raw(1.0f/60); + dt -= 1.0f/60; + } + process_tick_raw(dt); +} + +void update_view(float dx, float dy) +{ + // hard-coded mouse sensitivity, not resolution independent? + pending_view_z -= dx*300; + pending_view_x -= dy*700; +} + +extern int screen_x, screen_y; +extern int is_synchronous_debug; +float render_time; + +extern int chunk_locations, chunks_considered, chunks_in_frustum; +extern int quads_considered, quads_rendered; +extern int chunk_storage_rendered, chunk_storage_considered, chunk_storage_total; +extern int view_dist_in_chunks; +extern int num_threads_active, num_meshes_started, num_meshes_uploaded; +extern float chunk_server_activity; + +static Uint64 start_time, end_time; // render time + +float chunk_server_status[32]; +int chunk_server_pos; + +void draw_stats(void) +{ + int i; + + static Uint64 last_frame_time; + Uint64 cur_time = SDL_GetPerformanceCounter(); + float chunk_server=0; + float frame_time = (cur_time - last_frame_time) / (float) SDL_GetPerformanceFrequency(); + last_frame_time = cur_time; + + chunk_server_status[chunk_server_pos] = chunk_server_activity; + chunk_server_pos = (chunk_server_pos+1) %32; + + for (i=0; i < 32; ++i) + chunk_server += chunk_server_status[i] / 32.0f; + + stb_easy_font_spacing(-0.75); + pos_y = 10; + text_color[0] = text_color[1] = text_color[2] = 1.0f; + print("Frame time: %6.2fms, CPU frame render time: %5.2fms", frame_time*1000, render_time*1000); + print("Tris: %4.1fM drawn of %4.1fM in range", 2*quads_rendered/1000000.0f, 2*quads_considered/1000000.0f); + print("Vbuf storage: %dMB in frustum of %dMB in range of %dMB in cache", chunk_storage_rendered>>20, chunk_storage_considered>>20, chunk_storage_total>>20); + print("Num mesh builds started this frame: %d; num uploaded this frame: %d\n", num_meshes_started, num_meshes_uploaded); + print("QChunks: %3d in frustum of %3d valid of %3d in range", chunks_in_frustum, chunks_considered, chunk_locations); + print("Mesh worker threads active: %d", num_threads_active); + print("View distance: %d blocks", view_dist_in_chunks*16); + print("%s", glGetString(GL_RENDERER)); + + if (is_synchronous_debug) { + text_color[0] = 1.0; + text_color[1] = 0.5; + text_color[2] = 0.5; + print("SLOWNESS: Synchronous debug output is enabled!"); + } +} + +void draw_main(void) +{ + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + #ifdef REVERSE_DEPTH + glDepthFunc(GL_GREATER); + glClearDepth(0); + #else + glDepthFunc(GL_LESS); + glClearDepth(1); + #endif + glDepthMask(GL_TRUE); + glDisable(GL_SCISSOR_TEST); + glClearColor(0.6f,0.7f,0.9f,0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor3f(1,1,1); + glFrontFace(GL_CW); + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + #ifdef REVERSE_DEPTH + stbgl_Perspective(player_zoom, 90, 70, 3000, 1.0/16); + #else + stbgl_Perspective(player_zoom, 90, 70, 1.0/16, 3000); + #endif + + // now compute where the camera should be + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + stbgl_initCamera_zup_facing_y(); + + //glTranslatef(0,150,-5); + // position the camera and render it + + if (third_person) { + glTranslatef(0,2.5,0); + glRotatef(-camang[0],1,0,0); + + glTranslatef(0,2,0); + glRotatef(-camang[2]-rotate_view,0,0,1); + + //glTranslatef(0,0,1); + //glTranslatef(0,0,-1); + } else { + glRotatef(-camang[0],1,0,0); + glRotatef(-camang[2],0,0,1); + } + + glTranslatef(-camloc[0], -camloc[1], -camloc[2]); + + start_time = SDL_GetPerformanceCounter(); + render_caves(camloc); + end_time = SDL_GetPerformanceCounter(); + + render_time = (end_time - start_time) / (float) SDL_GetPerformanceFrequency(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0,screen_x/2,screen_y/2,0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + draw_stats(); +} + + + +#pragma warning(disable:4244; disable:4305; disable:4018) + +#define SCALE 2 + +void error(char *s) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", s, NULL); + exit(0); +} + +void ods(char *fmt, ...) +{ + char buffer[1000]; + va_list va; + va_start(va, fmt); + vsprintf(buffer, fmt, va); + va_end(va); + SDL_Log("%s", buffer); +} + +#define TICKS_PER_SECOND 60 + +static SDL_Window *window; + +extern void init_game(void); +extern void draw_main(void); +extern void process_tick(float dt); +extern void editor_init(void); + +void draw(void) +{ + draw_main(); + SDL_GL_SwapWindow(window); +} + + +static int initialized=0; +static float last_dt; + +int screen_x,screen_y; + +float carried_dt = 0; +#define TICKRATE 60 + + +int raw_level_time; +extern void init_game(void); +extern void draw_main(void); + +float global_timer; + +int loopmode(float dt, int real, int in_client) +{ + float actual_dt = dt; + + float jump_timer = dt; + + if (!initialized) return 0; + + if (!real) + return 0; + + // don't allow more than 6 frames to update at a time + if (dt > 0.075) dt = 0.075; + + global_timer += dt; + + carried_dt += dt; + while (carried_dt > 1.0/TICKRATE) { + //update_input(); + // if the player is dead, stop the sim + carried_dt -= 1.0/TICKRATE; + } + + process_tick(dt); + draw(); + + return 0; +} + +static int quit; + +//int winproc(void *data, stbwingraph_event *e) + +extern int editor_scale; +extern void editor_key(enum stbte_action act); +extern int controls; + +void active_control_set(int key) +{ + controls |= 1 << key; +} + +void active_control_clear(int key) +{ + controls &= ~(1 << key); +} + +extern void update_view(float dx, float dy); + +void process_sdl_mouse(SDL_Event *e) +{ + update_view((float) e->motion.xrel / screen_x, (float) e->motion.yrel / screen_y); +} + +void process_event(SDL_Event *e) +{ + switch (e->type) { + case SDL_MOUSEMOTION: + process_sdl_mouse(e); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEWHEEL: + //stbte_mouse_sdl(edit_map, e, 1.0f/editor_scale,1.0f/editor_scale,0,0); + break; + + case SDL_QUIT: + quit = 1; + break; + + case SDL_WINDOWEVENT: + switch (e->window.event) { + case SDL_WINDOWEVENT_SIZE_CHANGED: + screen_x = e->window.data1; + screen_y = e->window.data2; + loopmode(0,1,0); + break; + } + break; + + case SDL_TEXTINPUT: + switch(e->text.text[0]) { + #if 0 + case 27: { + #if 0 + int result; + SDL_ShowCursor(SDL_ENABLE); + if (MessageBox(e->handle, "Exit CLTT?", "CLTT", MB_OKCANCEL) == IDOK); + #endif + { + quit = 1; + break; + } + //SDL_ShowCursor(SDL_DISABLE); + break; + } + #endif + } + break; + + case SDL_KEYDOWN: { + int k = e->key.keysym.sym; + int s = e->key.keysym.scancode; + SDL_Keymod mod; + mod = SDL_GetModState(); + if (k == SDLK_ESCAPE) { +#ifndef DO_EDITOR + quit = 1; +#endif + } + + if (s == SDL_SCANCODE_D) active_control_set(0); + if (s == SDL_SCANCODE_A) active_control_set(1); + if (s == SDL_SCANCODE_W) active_control_set(2); + if (s == SDL_SCANCODE_S) active_control_set(3); + if (k == SDLK_SPACE) active_control_set(4); + if (s == SDL_SCANCODE_LCTRL) active_control_set(5); + if (s == SDL_SCANCODE_S) active_control_set(6); + if (s == SDL_SCANCODE_D) active_control_set(7); + + #if 0 + if (game_mode == GAME_editor) { + switch (k) { + case SDLK_RIGHT: editor_key(STBTE_scroll_right); break; + case SDLK_LEFT : editor_key(STBTE_scroll_left ); break; + case SDLK_UP : editor_key(STBTE_scroll_up ); break; + case SDLK_DOWN : editor_key(STBTE_scroll_down ); break; + } + switch (s) { + case SDL_SCANCODE_S: editor_key(STBTE_tool_select); break; + case SDL_SCANCODE_B: editor_key(STBTE_tool_brush ); break; + case SDL_SCANCODE_E: editor_key(STBTE_tool_erase ); break; + case SDL_SCANCODE_R: editor_key(STBTE_tool_rectangle ); break; + case SDL_SCANCODE_I: editor_key(STBTE_tool_eyedropper); break; + case SDL_SCANCODE_L: editor_key(STBTE_tool_link); break; + case SDL_SCANCODE_G: editor_key(STBTE_act_toggle_grid); break; + } + if ((e->key.keysym.mod & KMOD_CTRL) && !(e->key.keysym.mod & ~KMOD_CTRL)) { + switch (s) { + case SDL_SCANCODE_X: editor_key(STBTE_act_cut ); break; + case SDL_SCANCODE_C: editor_key(STBTE_act_copy ); break; + case SDL_SCANCODE_V: editor_key(STBTE_act_paste); break; + case SDL_SCANCODE_Z: editor_key(STBTE_act_undo ); break; + case SDL_SCANCODE_Y: editor_key(STBTE_act_redo ); break; + } + } + } + #endif + break; + } + case SDL_KEYUP: { + int k = e->key.keysym.sym; + int s = e->key.keysym.scancode; + if (s == SDL_SCANCODE_D) active_control_clear(0); + if (s == SDL_SCANCODE_A) active_control_clear(1); + if (s == SDL_SCANCODE_W) active_control_clear(2); + if (s == SDL_SCANCODE_S) active_control_clear(3); + if (k == SDLK_SPACE) active_control_clear(4); + if (s == SDL_SCANCODE_LCTRL) active_control_clear(5); + if (s == SDL_SCANCODE_S) active_control_clear(6); + if (s == SDL_SCANCODE_D) active_control_clear(7); + break; + } + } +} + +static SDL_GLContext *context; + +static float getTimestep(float minimum_time) +{ + float elapsedTime; + double thisTime; + static double lastTime = -1; + + if (lastTime == -1) + lastTime = SDL_GetTicks() / 1000.0 - minimum_time; + + for(;;) { + thisTime = SDL_GetTicks() / 1000.0; + elapsedTime = (float) (thisTime - lastTime); + if (elapsedTime >= minimum_time) { + lastTime = thisTime; + return elapsedTime; + } + // @TODO: compute correct delay + SDL_Delay(1); + } +} + +void APIENTRY gl_debug(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *param) +{ + #if 0 + if (severity == GL_DEBUG_SEVERITY_LOW_ARB) + return; + #endif + ods("%s\n", message); +} + +int is_synchronous_debug; +void enable_synchronous(void) +{ + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + is_synchronous_debug = 1; +} + +void prepare_threads(void); + +//void stbwingraph_main(void) +int SDL_main(int argc, char **argv) +{ + SDL_Init(SDL_INIT_VIDEO); + + prepare_threads(); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE , 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + + #ifdef GL_DEBUG + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); + #endif + + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); + + screen_x = 1920; + screen_y = 1080; + + window = SDL_CreateWindow("caveview", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + screen_x, screen_y, + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE + ); + if (!window) error("Couldn't create window"); + + context = SDL_GL_CreateContext(window); + if (!context) error("Couldn't create context"); + + SDL_GL_MakeCurrent(window, context); // is this true by default? + + // if (!IsDebuggerPresent()) + SDL_SetRelativeMouseMode(SDL_TRUE); + + stbgl_initExtensions(); + + #ifdef GL_DEBUG + if (glDebugMessageCallbackARB) { + glDebugMessageCallbackARB(gl_debug, NULL); + + enable_synchronous(); + } + #endif + + SDL_GL_SetSwapInterval(0); // only when profiling + + render_init(); + mesh_init(); + world_init(); + + init_game(); + initialized = 1; + + while (!quit) { + SDL_Event e; + while (SDL_PollEvent(&e)) + process_event(&e); + + loopmode(getTimestep(0.0166f/8), 1, 1); + quit=quit; + } + + return 0; +} diff --git a/tests/caveview/cave_render.c b/tests/caveview/cave_render.c index a220c27..63dd9f4 100644 --- a/tests/caveview/cave_render.c +++ b/tests/caveview/cave_render.c @@ -772,7 +772,7 @@ void render_caves(float campos[3]) stbglUseProgram(main_prog); setup_uniforms(campos); // set uniforms to default values inefficiently glActiveTextureARB(GL_TEXTURE2_ARB); - glEnableVertexAttribArrayARB(0); + stbglEnableVertexAttribArray(0); num_meshes_uploaded = 0; update_meshes_from_render_thread(); @@ -843,7 +843,7 @@ void render_caves(float campos[3]) } } - glDisableVertexAttribArrayARB(0); + stbglDisableVertexAttribArray(0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glActiveTextureARB(GL_TEXTURE0_ARB); diff --git a/tests/caveview/caveview.h b/tests/caveview/caveview.h index 98aa431..936118f 100644 --- a/tests/caveview/caveview.h +++ b/tests/caveview/caveview.h @@ -38,6 +38,9 @@ extern void ods(char *fmt, ...); // output debug string extern void reset_cache_size(int size); +extern void render_caves(float pos[3]); + + #include "cave_parse.h" // fast_chunk extern fast_chunk *get_converted_fastchunk(int chunk_x, int chunk_y); diff --git a/tests/caveview/game.c b/tests/caveview/game.c deleted file mode 100644 index 2c6db94..0000000 --- a/tests/caveview/game.c +++ /dev/null @@ -1,354 +0,0 @@ -#include -//#include "game.h" -#include "stb.h" - -#include "sdl.h" -#include "SDL_opengl.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -#define STB_GL_IMPLEMENTATION -#include "stb_gl.h" - -#define STB_GLPROG_IMPLEMENTATION -#define STB_GLPROG_ARB_DEFINE_EXTENSIONS -#include "stb_glprog.h" - -#include "stb_easy_font.h" - -char *game_name = "caveview"; - -// assume only a single texture with all sprites -float texture_s_scale; -float texture_t_scale; -GLuint interface_tex, logo_tex; - -extern int screen_x, screen_y; // main.c - -int tex_w, tex_h; -void *tex_data; - -GLuint load_texture(char *filename, int keep) -{ - GLuint tex; - tex_data = stbi_load(filename, &tex_w, &tex_h, NULL, 4); - if (tex_data == NULL) { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - game_name, - "Couldn't open image file.", - NULL); - exit(1); - } - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - if (!keep) { - free(tex_data); - tex_data = NULL; - } - - return tex; -} - -static void init_graphics(void) -{ - //logo_tex = load_texture("sss_logo.png",0); - //interface_tex = load_texture("game_art.png",1); - texture_s_scale = 1.0f / tex_w; - texture_t_scale = 1.0f / tex_h; -} - -void print_string(float x, float y, char *text, float r, float g, float b) -{ - static char buffer[99999]; - int num_quads; - - num_quads = stb_easy_font_print(x, y, text, NULL, buffer, sizeof(buffer)); - - glColor3f(r,g,b); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 16, buffer); - glDrawArrays(GL_QUADS, 0, num_quads*4); - glDisableClientState(GL_VERTEX_ARRAY); -} - -float text_color[3]; -float pos_x = 10; -float pos_y = 10; - -void print(char *text, ...) -{ - char buffer[999]; - va_list va; - va_start(va, text); - vsprintf(buffer, text, va); - va_end(va); - print_string(pos_x, pos_y, buffer, text_color[0], text_color[1], text_color[2]); - pos_y += 10; -} - -// mouse offsetting 'pixel to virtual' -float xs_p2v, ys_p2v;// xoff_p2v, yoff_p2v; - -// viewport offseting 'virtual to pixel' -float xs_v2p, ys_v2p, xoff_v2p, yoff_v2p; - -float camang[3], camloc[3] = { 0,0,75 }; -float player_zoom = 1.0; -int third_person; -float rotate_view = 0.0; - -#define REVERSE_DEPTH - - -void init_game(void) -{ - init_graphics(); -} - -void render_caves(float pos[3]); - -void camera_to_worldspace(float world[3], float cam_x, float cam_y, float cam_z) -{ - float vec[3] = { cam_x, cam_y, cam_z }; - float t[3]; - float s,c; - s = (float) sin(camang[0]*3.141592/180); - c = (float) cos(camang[0]*3.141592/180); - - t[0] = vec[0]; - t[1] = c*vec[1] - s*vec[2]; - t[2] = s*vec[1] + c*vec[2]; - - s = (float) sin(camang[2]*3.141592/180); - c = (float) cos(camang[2]*3.141592/180); - world[0] = c*t[0] - s*t[1]; - world[1] = s*t[0] + c*t[1]; - world[2] = t[2]; -} - -// camera worldspace velocity -float cam_vel[3]; - -int controls; - -#define MAX_VEL 150.0f // blocks per second -#define ACCEL 6.0f -#define DECEL 3.0f - -#define STATIC_FRICTION DECEL -#define EFFECTIVE_ACCEL (ACCEL+DECEL) - -// dynamic friction: -// -// if going at MAX_VEL, ACCEL and friction must cancel -// EFFECTIVE_ACCEL = DECEL + DYNAMIC_FRIC*MAX_VEL -#define DYNAMIC_FRICTION (ACCEL/(float)MAX_VEL) - -float view_x_vel = 0; -float view_z_vel = 0; -float pending_view_x; -float pending_view_z; -float pending_view_x; -float pending_view_z; - -void process_tick_raw(float dt) -{ - int i; - float thrust[3] = { 0,0,0 }; - float world_thrust[3]; - - // choose direction to apply thrust - - thrust[0] = (controls & 3)== 1 ? EFFECTIVE_ACCEL : (controls & 3)== 2 ? -EFFECTIVE_ACCEL : 0; - thrust[1] = (controls & 12)== 4 ? EFFECTIVE_ACCEL : (controls & 12)== 8 ? -EFFECTIVE_ACCEL : 0; - thrust[2] = (controls & 48)==16 ? EFFECTIVE_ACCEL : (controls & 48)==32 ? -EFFECTIVE_ACCEL : 0; - - // @TODO clamp thrust[0] & thrust[1] vector length to EFFECTIVE_ACCEL - - camera_to_worldspace(world_thrust, thrust[0], thrust[1], 0); - world_thrust[2] += thrust[2]; - - for (i=0; i < 3; ++i) { - float acc = world_thrust[i]; - cam_vel[i] += acc*dt; - } - - if (cam_vel[0] || cam_vel[1] || cam_vel[2]) - { - float vel = (float) sqrt(cam_vel[0]*cam_vel[0] + cam_vel[1]*cam_vel[1] + cam_vel[2]*cam_vel[2]); - float newvel = vel; - float dec = STATIC_FRICTION + DYNAMIC_FRICTION*vel; - newvel = vel - dec*dt; - if (newvel < 0) - newvel = 0; - cam_vel[0] *= newvel/vel; - cam_vel[1] *= newvel/vel; - cam_vel[2] *= newvel/vel; - } - - camloc[0] += cam_vel[0] * dt; - camloc[1] += cam_vel[1] * dt; - camloc[2] += cam_vel[2] * dt; - - view_x_vel *= (float) pow(0.75, dt); - view_z_vel *= (float) pow(0.75, dt); - - view_x_vel += (pending_view_x - view_x_vel)*dt*60; - view_z_vel += (pending_view_z - view_z_vel)*dt*60; - - pending_view_x -= view_x_vel * dt; - pending_view_z -= view_z_vel * dt; - camang[0] += view_x_vel * dt; - camang[2] += view_z_vel * dt; - camang[0] = stb_clamp(camang[0], -90, 90); - camang[2] = (float) fmod(camang[2], 360); -} - -void process_tick(float dt) -{ - while (dt > 1.0f/60) { - process_tick_raw(1.0f/60); - dt -= 1.0f/60; - } - process_tick_raw(dt); -} - -void update_view(float dx, float dy) -{ - // hard-coded mouse sensitivity, not resolution independent? - pending_view_z -= dx*300; - pending_view_x -= dy*700; -} - -extern int screen_x, screen_y; -extern int is_synchronous_debug; -float render_time; - -extern int chunk_locations, chunks_considered, chunks_in_frustum; -extern int quads_considered, quads_rendered; -extern int chunk_storage_rendered, chunk_storage_considered, chunk_storage_total; -extern int view_dist_in_chunks; -extern int num_threads_active, num_meshes_started, num_meshes_uploaded; -extern float chunk_server_activity; - -static Uint64 start_time, end_time; // render time - -float chunk_server_status[32]; -int chunk_server_pos; - -void draw_stats(void) -{ - int i; - - static Uint64 last_frame_time; - Uint64 cur_time = SDL_GetPerformanceCounter(); - float chunk_server=0; - float frame_time = (cur_time - last_frame_time) / (float) SDL_GetPerformanceFrequency(); - last_frame_time = cur_time; - - chunk_server_status[chunk_server_pos] = chunk_server_activity; - chunk_server_pos = (chunk_server_pos+1) %32; - - for (i=0; i < 32; ++i) - chunk_server += chunk_server_status[i] / 32.0f; - - stb_easy_font_spacing(-0.75); - pos_y = 10; - text_color[0] = text_color[1] = text_color[2] = 1.0f; - print("Frame time: %6.2fms, CPU frame render time: %5.2fms", frame_time*1000, render_time*1000); - print("Tris: %4.1fM drawn of %4.1fM in range", 2*quads_rendered/1000000.0f, 2*quads_considered/1000000.0f); - print("Vbuf storage: %dMB in frustum of %dMB in range of %dMB in cache", chunk_storage_rendered>>20, chunk_storage_considered>>20, chunk_storage_total>>20); - print("Num mesh builds started this frame: %d; num uploaded this frame: %d\n", num_meshes_started, num_meshes_uploaded); - print("QChunks: %3d in frustum of %3d valid of %3d in range", chunks_in_frustum, chunks_considered, chunk_locations); - print("Mesh worker threads active: %d", num_threads_active); - print("View distance: %d blocks", view_dist_in_chunks*16); - print("%s", glGetString(GL_RENDERER)); - - if (is_synchronous_debug) { - text_color[0] = 1.0; - text_color[1] = 0.5; - text_color[2] = 0.5; - print("SLOWNESS: Synchronous debug output is enabled!"); - } -} - -void draw_main(void) -{ - glEnable(GL_CULL_FACE); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - #ifdef REVERSE_DEPTH - glDepthFunc(GL_GREATER); - glClearDepth(0); - #else - glDepthFunc(GL_LESS); - glClearDepth(1); - #endif - glDepthMask(GL_TRUE); - glDisable(GL_SCISSOR_TEST); - glClearColor(0.6f,0.7f,0.9f,0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor3f(1,1,1); - glFrontFace(GL_CW); - glEnable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - #ifdef REVERSE_DEPTH - stbgl_Perspective(player_zoom, 90, 70, 3000, 1.0/16); - #else - stbgl_Perspective(player_zoom, 90, 70, 1.0/16, 3000); - #endif - - // now compute where the camera should be - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - stbgl_initCamera_zup_facing_y(); - - //glTranslatef(0,150,-5); - // position the camera and render it - - if (third_person) { - glTranslatef(0,2.5,0); - glRotatef(-camang[0],1,0,0); - - glTranslatef(0,2,0); - glRotatef(-camang[2]-rotate_view,0,0,1); - - //glTranslatef(0,0,1); - //glTranslatef(0,0,-1); - } else { - glRotatef(-camang[0],1,0,0); - glRotatef(-camang[2],0,0,1); - } - - glTranslatef(-camloc[0], -camloc[1], -camloc[2]); - - start_time = SDL_GetPerformanceCounter(); - render_caves(camloc); - end_time = SDL_GetPerformanceCounter(); - - render_time = (end_time - start_time) / (float) SDL_GetPerformanceFrequency(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0,screen_x/2,screen_y/2,0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - draw_stats(); -} diff --git a/tests/caveview/glext_list.h b/tests/caveview/glext_list.h index cc7948a..780fac9 100644 --- a/tests/caveview/glext_list.h +++ b/tests/caveview/glext_list.h @@ -6,27 +6,27 @@ GLEXT(TexSubImage3D,TEXSUBIMAGE3D) GLEXT(GenerateMipmap,GENERATEMIPMAP) GLARB(DebugMessageCallback,DEBUGMESSAGECALLBACK) -GLARB(DeleteObject,DELETEOBJECT) -GLARB(CreateProgramObject,CREATEPROGRAMOBJECT) -GLARB(UseProgramObject,USEPROGRAMOBJECT) -GLARB(CreateShaderObject,CREATESHADEROBJECT) -GLARB(ShaderSource,SHADERSOURCE) -GLARB(CompileShader,COMPILESHADER) -GLARB(GetInfoLog,GETINFOLOG) -GLARB(AttachObject,ATTACHOBJECT) -GLARB(LinkProgram,LINKPROGRAM) -GLARB(GetObjectParameteriv,GETOBJECTPARAMETERIV) -GLARB(GetUniformLocation,GETUNIFORMLOCATION) -GLARB(Uniform1i,UNIFORM1I) -GLARB(Uniform1f,UNIFORM1F) -GLARB(Uniform4f,UNIFORM4F) -GLARB(Uniform2fv,UNIFORM2FV) -GLARB(Uniform3fv,UNIFORM3FV) -GLARB(Uniform4fv,UNIFORM4FV) -GLARB(VertexAttribPointer,VERTEXATTRIBPOINTER) +//GLARB(DeleteObject,DELETEOBJECT) +//GLARB(CreateProgramObject,CREATEPROGRAMOBJECT) +//GLARB(UseProgramObject,USEPROGRAMOBJECT) +//GLARB(CreateShaderObject,CREATESHADEROBJECT) +//GLARB(ShaderSource,SHADERSOURCE) +//GLARB(CompileShader,COMPILESHADER) +//GLARB(GetInfoLog,GETINFOLOG) +//GLARB(AttachObject,ATTACHOBJECT) +//GLARB(LinkProgram,LINKPROGRAM) +//GLARB(GetObjectParameteriv,GETOBJECTPARAMETERIV) +//GLARB(GetUniformLocation,GETUNIFORMLOCATION) +////GLARB(Uniform1i,UNIFORM1I) +//GLARB(Uniform1f,UNIFORM1F) +//GLARB(Uniform4f,UNIFORM4F) +//GLARB(Uniform2fv,UNIFORM2FV) +//GLARB(Uniform3fv,UNIFORM3FV) +//GLARB(Uniform4fv,UNIFORM4FV) +//GLARB(VertexAttribPointer,VERTEXATTRIBPOINTER) GLCORE(VertexAttribIPointer,VERTEXATTRIBIPOINTER) -GLARB(EnableVertexAttribArray,ENABLEVERTEXATTRIBARRAY) -GLARB(DisableVertexAttribArray,DISABLEVERTEXATTRIBARRAY) +//GLARB(EnableVertexAttribArray,ENABLEVERTEXATTRIBARRAY) +//GLARB(DisableVertexAttribArray,DISABLEVERTEXATTRIBARRAY) GLEXT(BindFramebuffer,BINDFRAMEBUFFER) GLEXT(DeleteFramebuffers,DELETEFRAMEBUFFERS) diff --git a/tests/caveview/main.c b/tests/caveview/main.c index 3be2696..e69de29 100644 --- a/tests/caveview/main.c +++ b/tests/caveview/main.c @@ -1,359 +0,0 @@ -#pragma warning(disable:4244; disable:4305; disable:4018) - -#define _WIN32_WINNT 0x400 - -#include "sdl.h" -#include "sdl_mixer.h" - -#include -#include -#include -#include - -//#include "game.h" - -#include - -#define STB_GLEXT_DEFINE "glext_list.h" -#include "stb_gl.h" - -#define STB_DEFINE -#include "stb.h" - -#include "caveview.h" - -#define SCALE 2 - -void error(char *s) -{ - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", s, NULL); - exit(0); -} - -void ods(char *fmt, ...) -{ - char buffer[1000]; - va_list va; - va_start(va, fmt); - vsprintf(buffer, fmt, va); - va_end(va); - SDL_Log("%s", buffer); -} - -#define TICKS_PER_SECOND 60 - -static SDL_Window *window; - -extern void init_game(void); -extern void draw_main(void); -extern void process_tick(float dt); -extern void editor_init(void); - -void draw(void) -{ - draw_main(); - SDL_GL_SwapWindow(window); -} - - -static int initialized=0; -static float last_dt; - -int screen_x,screen_y; - -float carried_dt = 0; -#define TICKRATE 60 - - -int raw_level_time; -extern void init_game(void); -extern void draw_main(void); - -float global_timer; - -int loopmode(float dt, int real, int in_client) -{ - float actual_dt = dt; - - float jump_timer = dt; - - if (!initialized) return 0; - - if (!real) - return 0; - - // don't allow more than 6 frames to update at a time - if (dt > 0.075) dt = 0.075; - - global_timer += dt; - - carried_dt += dt; - while (carried_dt > 1.0/TICKRATE) { - //update_input(); - // if the player is dead, stop the sim - carried_dt -= 1.0/TICKRATE; - } - - process_tick(dt); - draw(); - - return 0; -} - -static int quit; - -//int winproc(void *data, stbwingraph_event *e) - -extern int editor_scale; -extern void editor_key(enum stbte_action act); -extern int controls; - -void active_control_set(int key) -{ - controls |= 1 << key; -} - -void active_control_clear(int key) -{ - controls &= ~(1 << key); -} - -extern void update_view(float dx, float dy); - -void process_sdl_mouse(SDL_Event *e) -{ - update_view((float) e->motion.xrel / screen_x, (float) e->motion.yrel / screen_y); -} - -void process_event(SDL_Event *e) -{ - switch (e->type) { - case SDL_MOUSEMOTION: - process_sdl_mouse(e); - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEWHEEL: - //stbte_mouse_sdl(edit_map, e, 1.0f/editor_scale,1.0f/editor_scale,0,0); - break; - - case SDL_QUIT: - quit = 1; - break; - - case SDL_WINDOWEVENT: - switch (e->window.event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - screen_x = e->window.data1; - screen_y = e->window.data2; - loopmode(0,1,0); - break; - } - break; - - case SDL_TEXTINPUT: - switch(e->text.text[0]) { - #if 0 - case 27: { - #if 0 - int result; - SDL_ShowCursor(SDL_ENABLE); - if (MessageBox(e->handle, "Exit CLTT?", "CLTT", MB_OKCANCEL) == IDOK); - #endif - { - quit = 1; - break; - } - //SDL_ShowCursor(SDL_DISABLE); - break; - } - #endif - } - break; - - case SDL_KEYDOWN: { - int k = e->key.keysym.sym; - int s = e->key.keysym.scancode; - SDL_Keymod mod; - mod = SDL_GetModState(); - if (k == SDLK_ESCAPE) { -#ifndef DO_EDITOR - quit = 1; -#endif - } - - if (s == SDL_SCANCODE_D) active_control_set(0); - if (s == SDL_SCANCODE_A) active_control_set(1); - if (s == SDL_SCANCODE_W) active_control_set(2); - if (s == SDL_SCANCODE_S) active_control_set(3); - if (k == SDLK_SPACE) active_control_set(4); - if (s == SDL_SCANCODE_LCTRL) active_control_set(5); - if (s == SDL_SCANCODE_S) active_control_set(6); - if (s == SDL_SCANCODE_D) active_control_set(7); - - #if 0 - if (game_mode == GAME_editor) { - switch (k) { - case SDLK_RIGHT: editor_key(STBTE_scroll_right); break; - case SDLK_LEFT : editor_key(STBTE_scroll_left ); break; - case SDLK_UP : editor_key(STBTE_scroll_up ); break; - case SDLK_DOWN : editor_key(STBTE_scroll_down ); break; - } - switch (s) { - case SDL_SCANCODE_S: editor_key(STBTE_tool_select); break; - case SDL_SCANCODE_B: editor_key(STBTE_tool_brush ); break; - case SDL_SCANCODE_E: editor_key(STBTE_tool_erase ); break; - case SDL_SCANCODE_R: editor_key(STBTE_tool_rectangle ); break; - case SDL_SCANCODE_I: editor_key(STBTE_tool_eyedropper); break; - case SDL_SCANCODE_L: editor_key(STBTE_tool_link); break; - case SDL_SCANCODE_G: editor_key(STBTE_act_toggle_grid); break; - } - if ((e->key.keysym.mod & KMOD_CTRL) && !(e->key.keysym.mod & ~KMOD_CTRL)) { - switch (s) { - case SDL_SCANCODE_X: editor_key(STBTE_act_cut ); break; - case SDL_SCANCODE_C: editor_key(STBTE_act_copy ); break; - case SDL_SCANCODE_V: editor_key(STBTE_act_paste); break; - case SDL_SCANCODE_Z: editor_key(STBTE_act_undo ); break; - case SDL_SCANCODE_Y: editor_key(STBTE_act_redo ); break; - } - } - } - #endif - break; - } - case SDL_KEYUP: { - int k = e->key.keysym.sym; - int s = e->key.keysym.scancode; - if (s == SDL_SCANCODE_D) active_control_clear(0); - if (s == SDL_SCANCODE_A) active_control_clear(1); - if (s == SDL_SCANCODE_W) active_control_clear(2); - if (s == SDL_SCANCODE_S) active_control_clear(3); - if (k == SDLK_SPACE) active_control_clear(4); - if (s == SDL_SCANCODE_LCTRL) active_control_clear(5); - if (s == SDL_SCANCODE_S) active_control_clear(6); - if (s == SDL_SCANCODE_D) active_control_clear(7); - break; - } - } -} - -static SDL_GLContext *context; - -static float getTimestep(float minimum_time) -{ - float elapsedTime; - double thisTime; - static double lastTime = -1; - - if (lastTime == -1) - lastTime = SDL_GetTicks() / 1000.0 - minimum_time; - - for(;;) { - thisTime = SDL_GetTicks() / 1000.0; - elapsedTime = (float) (thisTime - lastTime); - if (elapsedTime >= minimum_time) { - lastTime = thisTime; - return elapsedTime; - } - // @TODO: compute correct delay - SDL_Delay(1); - } -} - -void APIENTRY gl_debug(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *param) -{ - #if 0 - if (severity == GL_DEBUG_SEVERITY_LOW_ARB) - return; - #endif - ods("%s\n", message); -} - -extern void do_music(int16 *stream, int samples); - -extern void foo(void); - -void render_init(void); - -int is_synchronous_debug; -void enable_synchronous(void) -{ - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - is_synchronous_debug = 1; -} - -void prepare_threads(void); - -//void stbwingraph_main(void) -int SDL_main(int argc, char **argv) -{ - SDL_Init(SDL_INIT_VIDEO); - - prepare_threads(); - - Mix_Init(0); - Mix_OpenAudio(48000, AUDIO_S16SYS, 2, 1024); // 1024 bytes = 256 samples = - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE , 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8); - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - - #ifdef GL_DEBUG - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); - #endif - - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); - - screen_x = 1920; - screen_y = 1080; - - window = SDL_CreateWindow("caveview", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - screen_x, screen_y, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE - ); - if (!window) error("Couldn't create window"); - - context = SDL_GL_CreateContext(window); - if (!context) error("Couldn't create context"); - - SDL_GL_MakeCurrent(window, context); // is this true by default? - - // if (!IsDebuggerPresent()) - SDL_SetRelativeMouseMode(SDL_TRUE); - - stbgl_initExtensions(); - - #ifdef GL_DEBUG - if (glDebugMessageCallbackARB) { - glDebugMessageCallbackARB(gl_debug, NULL); - - enable_synchronous(); - } - #endif - - SDL_GL_SetSwapInterval(0); // only when profiling - - render_init(); - mesh_init(); - world_init(); - - init_game(); - //editor_init(); - initialized = 1; - - while (!quit) { - SDL_Event e; - while (SDL_PollEvent(&e)) - process_event(&e); - - loopmode(getTimestep(0.0166f/8), 1, 1); - quit=quit; - } - //music_end(); - - return 0; -} diff --git a/tests/caveview/stb_gl.h b/tests/caveview/stb_gl.h index 354bb30..6498e28 100644 --- a/tests/caveview/stb_gl.h +++ b/tests/caveview/stb_gl.h @@ -344,7 +344,7 @@ void stbgl_Perspective(float zoom, float max_hfov, float max_vfov, float znear, } else { vfov = (float) atan((unit_height/2) / zoom); } - vfov = stbgl_rad2deg(vfov * 2); + vfov = (float) stbgl_rad2deg(vfov * 2); gluPerspective(vfov, aspect, znear, zfar); }