From e4225085e0cbfff72cf297d82ad47fc83e372368 Mon Sep 17 00:00:00 2001 From: Seth Long Date: Tue, 29 Oct 2024 10:34:09 -0700 Subject: [PATCH] Added crosshairs, object spawning, time scaling --- Makefile | 2 +- activation_area.h | 2 +- aimpoint.h | 36 +++++++++++ game.h | 2 +- hud_fragment_shader.glsl | 7 ++ hud_vertex_shader.glsl | 8 +++ main.cpp | 134 +++++++++++++++++++++++---------------- moving_platform.h | 2 +- projectiles.h | 12 ++-- turret.h | 2 +- 10 files changed, 140 insertions(+), 67 deletions(-) create mode 100644 aimpoint.h create mode 100644 hud_fragment_shader.glsl create mode 100644 hud_vertex_shader.glsl diff --git a/Makefile b/Makefile index ca9d8c7..a9c2bcd 100644 --- a/Makefile +++ b/Makefile @@ -16,4 +16,4 @@ test: all ./a.out ${OBJS} : game.h -main.o : projectiles.h activation_area.h turret.h tile_floor.h old_objects.h moving_platform.h geometric_objects.h +main.o : projectiles.h activation_area.h turret.h tile_floor.h old_objects.h moving_platform.h geometric_objects.h aimpoint.h diff --git a/activation_area.h b/activation_area.h index d969abd..92049b4 100644 --- a/activation_area.h +++ b/activation_area.h @@ -45,7 +45,7 @@ class activation_area : public gameobject { } return -1; // Don't block movement } - void move(){ + void move(int elapsed_time){ for(size_t i = 0; i < types.size(); i++){ if(types[i] == 101){ if(!collision_with_index(player_position, i, 0.2f)){ // Note: Included collision check as a magic number diff --git a/aimpoint.h b/aimpoint.h new file mode 100644 index 0000000..5c029b5 --- /dev/null +++ b/aimpoint.h @@ -0,0 +1,36 @@ +class aimpoint : public gameobject { + public: + int init(){ + float vertices[] { + -.2, .002, 0, + .2, .002, 0, + .2, -.002, 0, + -.2, .002, 0, + .2, -.002, 0, + -.2, -.002, 0, + + -.002, .2, 0, + .002, .2, 0, + .002, -.2, 0, + -.002, .2, 0, + .002, -.2, 0, + -.002, -.2, 0, + }; + glGenBuffers(1, &vbuf); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, vbuf); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + program = make_program("hud_vertex_shader.glsl",0, 0, 0, "hud_fragment_shader.glsl"); + if (!program) + return 1; + v_attrib = glGetAttribLocation(program, "in_vertex"); + return 0; + } + + void draw(glm::mat4 vp){ + glUseProgram(program); + glEnableVertexAttribArray(v_attrib); + glBindBuffer(GL_ARRAY_BUFFER, vbuf); + glVertexAttribPointer(v_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0); + glDrawArrays(GL_TRIANGLES, 0, 12); + } +}; diff --git a/game.h b/game.h index a2d6244..bf4158c 100644 --- a/game.h +++ b/game.h @@ -45,7 +45,7 @@ class gameobject { virtual void deinit() {}; virtual void draw(glm::mat4) {} virtual std::vector create_models(); - virtual void move() {} + virtual void move(int elapsed_time) {} virtual void animate() {} virtual bool is_on_idx(glm::vec3 position, size_t index, float height) {return false;} virtual ssize_t is_on(glm::vec3 position, float height) {return -1;} diff --git a/hud_fragment_shader.glsl b/hud_fragment_shader.glsl new file mode 100644 index 0000000..3cb4cb1 --- /dev/null +++ b/hud_fragment_shader.glsl @@ -0,0 +1,7 @@ +#version 460 + +out vec4 outcolor; + +void main(void) { + outcolor = vec4(1.0f, 0.0f, 0.0f, 1.0f); +} diff --git a/hud_vertex_shader.glsl b/hud_vertex_shader.glsl new file mode 100644 index 0000000..66f119b --- /dev/null +++ b/hud_vertex_shader.glsl @@ -0,0 +1,8 @@ +#version 460 + +in vec3 in_vertex; +out vec4 gl_Position; + +void main(void) { + gl_Position = vec4(in_vertex, 1.0); +} diff --git a/main.cpp b/main.cpp index 74d0aeb..2fc9802 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,7 @@ #include "moving_platform.h" #include "turret.h" #include "geometric_objects.h" +#include "aimpoint.h" std::mutex grand_mutex; @@ -24,20 +25,31 @@ int framecount = 0; std::vector objects; projectile ice_balls; - +wall_block spawned_blocks("cube.obj", "projectile.jpg", glm::vec3(2, 2, 2)); fragment brick_fragments; + class target : public loaded_object, public block_object { -public: - target() : loaded_object("monkey.obj", "brick.jpg", glm::vec3(15.0f, 10.0f, 15.0f)) { - collision_check = true; - } - void hit_index(size_t index){ - brick_fragments.create_burst(100, locations[index], 0.01f); - locations.erase(locations.begin() + index); - } - + public: + target() : loaded_object("monkey.obj", "brick.jpg", glm::vec3(15.0f, 10.0f, 15.0f)) { + collision_check = true; + } + void hit_index(size_t index){ + brick_fragments.create_burst(100, locations[index], 0.01f); + locations.erase(locations.begin() + index); + } + }; +ssize_t is_empty(glm::vec3 position, float distance = 0.2f){ + for(gameobject* o : objects) { + ssize_t collide_index = o->collision_index(position, distance); + if(collide_index != -1) + return false; + } + return true; + +} + struct key_status { int forward, backward, left, right; }; @@ -56,6 +68,21 @@ void mouse_click_callback(GLFWwindow* window, int button, int action, int mods){ fire(); if(button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) fire(true); + if(button == 2 && action == GLFW_PRESS){ + // Spawn a block + glm::vec3 look_at_point = 2.0f * glm::vec3(roundf(player_position.x/2.0f), roundf(player_position.y/2.0f), roundf(player_position.z/2.0f)) ; + look_at_point.x += 2.0f * roundf(4.0f * cosf(player_elevation) * sinf(player_heading)); + look_at_point.y += 2.0f * roundf(4.0f * sinf(player_elevation)); + look_at_point.z += 2.0f * roundf(4.0f * cosf(player_elevation) * cosf(player_heading)); + if(!is_empty(look_at_point, 0.0f)){ + look_at_point = 2.0f * glm::vec3(roundf(player_position.x/2.0f), roundf(player_position.y/2.0f), roundf(player_position.z/2.0f)) ; + look_at_point.x += 2.0f * roundf(2.0f * cosf(player_elevation) * sinf(player_heading)); + look_at_point.y += 2.0f * roundf(2.0f * sinf(player_elevation)); + look_at_point.z += 2.0f * roundf(2.0f * cosf(player_elevation) * cosf(player_heading)); + } + if(is_empty(look_at_point, 0.0f)) + spawned_blocks.locations.push_back(look_at_point); + } } void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){ @@ -84,21 +111,11 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod } } -ssize_t is_empty(glm::vec3 position, float distance){ - for(gameobject* o : objects) { - ssize_t collide_index = o->collision_index(position, 0.2f); - if(collide_index != -1) - return false; - } - return true; - -} - int shutdown_engine = 0; /* Must be called at a consistent rate */ void player_movement(){ while(!shutdown_engine){ -// grand_mutex.lock(); + // grand_mutex.lock(); auto start = std::chrono::system_clock::now(); glm::vec3 step_to_point = player_position; if(player_key_status.forward){ @@ -114,23 +131,23 @@ void player_movement(){ step_to_point += 0.05f * glm::vec3(-sinf(player_heading + M_PI/2), 0, -cosf(player_heading + M_PI/2)); } for(gameobject* o : objects) { - ssize_t collide_index = o->collision_index(step_to_point, 0.2f); - if(collide_index != -1) { - if(is_empty(glm::vec3(player_position.x, step_to_point.y, step_to_point.z), 0.2f)) { - step_to_point.x = player_position.x; - break; - } - else if(is_empty(glm::vec3(step_to_point.x, step_to_point.y, player_position.z), 0.2f)) { - step_to_point.z = player_position.z; - break; - } - else { - step_to_point = player_position; - break; - } - - - } + ssize_t collide_index = o->collision_index(step_to_point, 0.2f); + if(collide_index != -1) { + if(is_empty(glm::vec3(player_position.x, step_to_point.y, step_to_point.z), 0.2f)) { + step_to_point.x = player_position.x; + break; + } + else if(is_empty(glm::vec3(step_to_point.x, step_to_point.y, player_position.z), 0.2f)) { + step_to_point.z = player_position.z; + break; + } + else { + step_to_point = player_position; + break; + } + + + } } player_position = step_to_point; @@ -157,7 +174,7 @@ void player_movement(){ player_position.y = floor_height + player_height; } } -// grand_mutex.unlock(); + // grand_mutex.unlock(); auto end = std::chrono::system_clock::now(); // double difference = std::chrono::duration_cast(start - end).count(); // printf("Time difference: %lf\n", difference); @@ -171,21 +188,21 @@ void object_movement(){ while(!shutdown_engine){ auto start_time = std::chrono::system_clock::now(); loop_time = std::chrono::duration_cast(start_time - last_call).count(); - -// grand_mutex.lock(); + + // grand_mutex.lock(); if(player_platform){ glm::vec3 pltloc = player_platform->locations[player_platform_index]; float floor_height = pltloc.y + (player_platform->size.y / 2); player_position.y = floor_height + player_height; } -// grand_mutex.unlock(); + // grand_mutex.unlock(); for(gameobject* o : objects) - o->move(); // move needs a parameter which indicates how long since we last called move (loop_time) + o->move(loop_time); // move needs a parameter which indicates how long since we last called move (loop_time) auto end_time = std::chrono::system_clock::now(); int cpu_time = std::chrono::duration_cast(end_time - start_time).count(); last_call = start_time; int sleep_time = 1000 - cpu_time; -// printf("Loop time: %d Sleep time: %d CPU time: %d\n", loop_time, sleep_time, cpu_time); + // printf("Loop time: %d Sleep time: %d CPU time: %d\n", loop_time, sleep_time, cpu_time); if(sleep_time > 100 ) std::this_thread::sleep_for(std::chrono::microseconds(sleep_time)); } @@ -265,11 +282,11 @@ void debug_callback(GLenum, GLenum, GLuint, GLenum severity, GLsizei, const GLch puts(RED(message).c_str()); else if(severity == GL_DEBUG_SEVERITY_MEDIUM) puts(YELLOW(message).c_str()); -/* Only uncomment if you want a lot of messages */ -/* - else + /* Only uncomment if you want a lot of messages */ + /* + else puts(message); -*/ + */ } int main(int argc, char** argv) { @@ -304,7 +321,7 @@ int main(int argc, char** argv) { /* Level Loading (hardcoded at the moment) */ - + tile_floor fl; objects.push_back(&ice_balls); objects.push_back(&fl); @@ -333,11 +350,11 @@ int main(int argc, char** argv) { /* - wall_block monster_box("cube.obj", "monster1.png", glm::vec3(10, 10, 10)); - monster_box.scale = 5.0; - monster_box.locations.push_back(glm::vec3(53, -10, 50)); - objects.push_back(&monster_box); - */ + wall_block monster_box("cube.obj", "monster1.png", glm::vec3(10, 10, 10)); + monster_box.scale = 5.0; + monster_box.locations.push_back(glm::vec3(53, -10, 50)); + objects.push_back(&monster_box); + */ // What if it wasn't a cube? wall_block bwb("cube.obj", "brick.jpg", glm::vec3(20, 20, 20)); @@ -361,6 +378,11 @@ int main(int argc, char** argv) { p.addpanel(glm::vec3(10, -9.99, 450), glm::vec2(5, 5), glm::vec2(1, 1)); objects.push_back(&p); + aimpoint main_aimpoint; + objects.push_back(&main_aimpoint); + + objects.push_back(&spawned_blocks); + /* Initialize game objects */ for(gameobject* o : objects){ if(o->init()){ @@ -383,7 +405,7 @@ int main(int argc, char** argv) { glClear(GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT); -// grand_mutex.lock(); + // grand_mutex.lock(); /* Where are we? A: player_position * What are we looking at? @@ -398,7 +420,7 @@ int main(int argc, char** argv) { for(gameobject* o : objects) o->draw(vp); -// grand_mutex.unlock(); + // grand_mutex.unlock(); glfwSwapBuffers(window); } diff --git a/moving_platform.h b/moving_platform.h index 19c4bbf..e952cc5 100644 --- a/moving_platform.h +++ b/moving_platform.h @@ -5,7 +5,7 @@ class elevator : public loaded_object, public block_object { bool up = true; elevator(const char* of, const char* tf, glm::vec3 s) : loaded_object(of, tf, s) {} - void move(){ + void move(int elapsed_time){ // TODO: Incorporate elapsed_time // Just one elevator for now if(up) { locations[0].y += .1; diff --git a/projectiles.h b/projectiles.h index f838cb6..5886cc0 100644 --- a/projectiles.h +++ b/projectiles.h @@ -17,13 +17,13 @@ public: bursting.push_back(false); } } - void move() { + void move(int elapsed_time) { data_mutex.lock(); for(size_t i = 0; i < locations.size(); i++){ if(bursting[i]) - directions[i].y -= 0.0002; - locations[i] += directions[i]; - lifetimes[i] -= 10; // TODO: Manage time resolutions better + directions[i].y -= 0.0002 * elapsed_time/1000.0f; + locations[i] += directions[i] * (elapsed_time/1000.0f); + lifetimes[i] -= 10 * elapsed_time/1000.0f; // TODO: Manage time resolutions better if(lifetimes[i] <= 0.0f) { if(bursting[i]) create_burst(200, locations[i], 0.003); @@ -81,10 +81,10 @@ public: } } - void move() override { + void move(int elapsed_time) override { for(size_t i = 0; i < locations.size(); i++){ life_counts[i] -= 0.01f; - locations[i] += trajectories[i]; + locations[i] += trajectories[i] * (elapsed_time/1000.0f); // Is it on the ground? // Import player fall code to make this more elaborate and probably buggy if(locations[i].y <= -9.0){ diff --git a/turret.h b/turret.h index 9f082dc..64ca880 100644 --- a/turret.h +++ b/turret.h @@ -14,7 +14,7 @@ public: scale = 5; } - void move() { + void move(int elapsed_time) { // TODO: Incorporate elapsed_time /* At some rate (every so many calls to this function) * Pick a target (How do we know what targets we have?) * Launch a projectile at it (How do we launch a projectile from here?) -- 2.39.5