]> isoptera.lcsc.edu Git - engine26/.git/commitdiff
Added special marker and exploding target
authorSeth Long <sslong@lcsc.edu>
Thu, 29 Oct 2026 17:12:45 +0000 (10:12 -0700)
committerSeth Long <sslong@lcsc.edu>
Thu, 29 Oct 2026 17:12:45 +0000 (10:12 -0700)
12 files changed:
Makefile
explodingtarget.h [new file with mode: 0644]
game.h
gameobject.cpp
helpers.cpp
load_level.cpp
misc_objects.cpp
misc_objects.h
projectile.h
shaders/fragment_shader.glsl
shaders/vertex_shader.glsl
textures/chalet.jpg [new file with mode: 0644]

index d72f6b6aeeb79de1d7d50890c4e81b9d12dd4705..b9a614049f843723d6e5f488fc89da3c49d8a073 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,4 +15,4 @@ clean:
 test:  all
        ./game
 
-${OBJS} : game.h misc_objects.h water_tank.h projectile.h
+${OBJS} : game.h misc_objects.h water_tank.h projectile.h explodingtarget.h
diff --git a/explodingtarget.h b/explodingtarget.h
new file mode 100644 (file)
index 0000000..efa727d
--- /dev/null
@@ -0,0 +1,23 @@
+#pragma once
+#include "game.h"
+
+class ExplodingTarget : public FloorPanel {
+public:
+       float get_random(){
+               return ((random() % 2000000) - 1000000.0f) / 500000.0f;
+       }
+
+       void report_collision(GameObject *other, size_t other_instance, size_t our_instance) override {
+               vec3 our_position = get_center(our_instance);
+               Projectile* projectile = (Projectile*)find_object("Projectiles");       
+               if(!projectile) {
+                       printf("Collisions without projectiles are very safe\n");
+                       return;
+               }
+               for(int i = 0; i < 100; i++){
+                       /* Make a new projectile */
+                       projectile->add_location_size(our_position, vec3(get_random(), get_random(), get_random()));
+               }
+               models.erase(models.begin() + our_instance);
+       }       
+};
diff --git a/game.h b/game.h
index 72f585ba6669a3b2e733c328778f05d9149bbf90..92ec7f434c06b8be14b9d28f652705b4afb79614 100644 (file)
--- a/game.h
+++ b/game.h
@@ -87,6 +87,7 @@ class GameObject {
                unsigned int tex;
                unsigned int element_count;
                unsigned int models_buffer;
+               unsigned int specials_buffer;
 
                /* Properties related to initialization.  Set these when initializing an object */
                string object_file, texture_file, vertex_shader, fragment_shader;
@@ -102,6 +103,7 @@ class GameObject {
 
                /* Properties not related to OpenGL */
                vector<mat4> models;
+               vector<int> specials;
                bool visible = true; 
 
                void add_location(vec3 location);
@@ -156,6 +158,9 @@ struct vertex {
 bool operator==(const vertex& a, const vertex& o);
 
 ostream& operator<<(ostream& out, vec3 v);
+GameObject* add_object(GameObject *new_object, string name, bool solid = false);
+void load_level();
+GameObject* find_object(string name);
 
 #define PLAYER_ON_OBJECT 1
 #define ACTIVATE 2
@@ -164,5 +169,4 @@ ostream& operator<<(ostream& out, vec3 v);
 #include "misc_objects.h"
 #include "water_tank.h"
 #include "projectile.h"
-GameObject* add_object(GameObject *new_object, string name, bool solid = false);
-void load_level();
+#include "explodingtarget.h"
index 2552452f2fd5c97b2de3a07c260191fea20e89ca..5a5a20563b71d7b64f3cdbbc742f518c849c81dc 100644 (file)
@@ -31,6 +31,7 @@ namespace std {
 
 void GameObject::add_location(vec3 location){
        models.push_back(translate(mat4(1.0), location));
+       specials.push_back(0);
 }
 
 char log_buffer[2048];
@@ -71,7 +72,7 @@ unsigned int load_shader(string shader_filename, unsigned int type){
                glShaderSource(vs_reference, 1, (const char**)&source, 0);
                glCompileShader(vs_reference);
                glGetShaderInfoLog(vs_reference, 2048, NULL, log_buffer);
-               puts(source);
+               puts(log_buffer);
                free(source);
                int compile_ok;
                glGetShaderiv(vs_reference, GL_COMPILE_STATUS, &compile_ok);
@@ -132,6 +133,7 @@ bool GameObject::init(){
        tex = load_texture(texture_file);
 
        glGenBuffers(1, &models_buffer);
+       glGenBuffers(1, &specials_buffer);
 
        unsigned int vs_reference = load_shader("shaders/vertex_shader.glsl", GL_VERTEX_SHADER);
        unsigned int fs_reference = load_shader("shaders/fragment_shader.glsl", GL_FRAGMENT_SHADER);
@@ -178,6 +180,10 @@ void GameObject::draw(mat4 vp){
        glBufferData(GL_SHADER_STORAGE_BUFFER, models.size() * sizeof(mat4), models.data(), GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, models_buffer);
 
+       glBindBuffer(GL_SHADER_STORAGE_BUFFER, specials_buffer);
+       glBufferData(GL_SHADER_STORAGE_BUFFER, specials.size() * sizeof(int), specials.data(), GL_DYNAMIC_DRAW);
+       glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, specials_buffer);
+
        glUniformMatrix4fv(vp_uniform, 1, 0, value_ptr(vp));
 
        glDrawElementsInstanced(GL_TRIANGLES, element_count, GL_UNSIGNED_INT, 0, models.size());
index 8639d13778f9a8c81fd0238fa0effe4f10dabe08..d4fe274e8fda8b882f1f084d197b60095f746614 100644 (file)
@@ -1,5 +1,12 @@
 #include "game.h"
 
+GameObject* find_object(string name){
+       for(auto o : game_objects)
+               if(o->name == name)
+                       return o;
+       return 0;
+}
+
 ostream& operator<<(ostream& out, vec3 v){
        return out << "{" << v.x << ", " << v.y << ", " << v.z << "}";
 }
index 59f3da3295c68376ce49900678c1bcc7380a7631..1f9670111f54044c94d07c29d70ef35d887749b0 100644 (file)
@@ -8,7 +8,8 @@ void load_level(){
        floor->texture_file = "textures/stones.png";
        for(float i = -90; i < 90; i+= 5)
                for(float j = -90; j < 90; j+= 5)
-                       floor->add_location_size(vec3(i, -2, j), vec3(5, 1, 5));
+                       for(float k = -10; k <= -2; k += 1)
+                               floor->add_location_size(vec3(i, k, j), vec3(5, 1, 5));
 
        /* New Way */
        WaterTank *tank = (WaterTank*)add_object(new WaterTank, "Water Tank", true);
@@ -33,6 +34,9 @@ void load_level(){
        for(float zpos = 6; zpos < 32; zpos += 2){
                bridge->add_location_size(vec3(0, 6, zpos), vec3(2, 2, 2));
        }
+       bridge->specials[2] = 1;
+       bridge->specials[4] = 2;
+       bridge->specials[6] = 1;
        
        SlipperyBlock *sliprock = (SlipperyBlock*)add_object(new SlipperyBlock, "Slide Area", true);
        sliprock->texture_file = "textures/rock.jpg";
@@ -43,6 +47,11 @@ void load_level(){
        Projectile *proj = (Projectile*)add_object(new Projectile, "Projectiles", false);
        proj->object_file = "objects/sphere.obj";
        proj->texture_file = "textures/projectile.jpg";
+       
+       ExplodingTarget *targ = (ExplodingTarget*)add_object(new ExplodingTarget, "Target", true);
+       targ->texture_file = "textures/chalet.jpg";
+       targ->add_location_size(vec3(20, 4, 40), vec3(6, 6, 6));
+       targ->add_location_size(vec3(20, 40, 40), vec3(6, 6, 6));
 }
 
 GameObject* add_object(GameObject *new_object, string name, bool solid){
index 4e56e51eb3673f78b5bfdc449ac612cd7a422ec1..4bb648cca05818135442cfc99359ba8df31cbf72 100644 (file)
@@ -56,6 +56,7 @@ void VanishBlock::movement(float time){
        for(size_t i = 0; i < models.size(); i++){
                if(instance_countdowns[i] == 0){
                        models.erase(models.begin() + i);
+                       specials.erase(specials.begin() + i);
                        instance_countdowns.erase(instance_countdowns.begin() + i);
                } else if(instance_countdowns[i] > 0){
                        instance_countdowns[i]--;
index a3d37ffb65da77d9b2486cc56ca90ce263c1a564..34ef0f581ed82d0f81219a32e0bc8c655f8a885f 100644 (file)
@@ -19,6 +19,7 @@ public:
        void add_location_size(vec3 location, vec3 size){
                models.push_back(translate(mat4(1.0), location));
                models[models.size() - 1] = scale(models[models.size() - 1], size);
+               specials.push_back(0);
        }
        virtual void trigger_action(size_t instance, int action) override;
        ssize_t is_inside(vec3, float) override;
@@ -40,7 +41,10 @@ public:
                return vec3(models[instance][3][0], models[instance][3][1], models[instance][3][2]);
        }
        void report_collision(GameObject *other, size_t other_instance, size_t our_instance) override {
-//             models.erase(models.begin() + our_instance);
+/*             models.erase(models.begin() + our_instance);
+               specials.erase(specials.begin() + our_instance);
+*/
+               specials[our_instance] = 2;
        };
        bool inside_instance(vec3 other, size_t instance) override {
                vec3 uloc = get_center(instance);
@@ -56,6 +60,7 @@ public:
                models.push_back(translate(mat4(1.0), location));
                models[models.size() - 1] = scale(models[models.size() - 1], size);
                instance_countdowns.push_back(-1);
+               specials.push_back(0);
        }
        void trigger_action(size_t instance, int action) override;
        void movement(float time) override;
index 2d30620fcbf512bedb9d46f821b345b5118270da..3efb817c3ee6f79f327b981239e11f5dfc8afbea 100644 (file)
@@ -11,17 +11,19 @@ public:
        Projectile() {
                moving = true;
        };
+       void add_location_size(vec3 start, vec3 vel){
+               models.push_back(translate(mat4(1.0), start));
+               models[models.size() - 1] = scale(models[models.size() - 1], vec3(proj_size, proj_size, proj_size));
+               velocities.push_back(vel * 0.1f);
+               times_to_live.push_back(20000);
+       }
        void add_location_size(){
                /* Defaults to "launched by player" */
-               models.push_back(translate(mat4(1.0), g.player_position));
-               models[models.size() - 1] = scale(models[models.size() - 1], vec3(proj_size, proj_size, proj_size));
                float gdist = cos(g.elevation);
                float vx = gdist * cos(g.heading);
                float vz = gdist * sin(g.heading);
                float vy = sin(g.elevation);
-               /* The number we multiply the vector by on the next line is the speed */
-               velocities.push_back(vec3(vx, vy, vz) * 0.01f);
-               times_to_live.push_back(200000);
+               add_location_size(g.player_position, vec3(vx, vy, vz));
        }
        void movement(float time) {
                for(size_t i = 0; i < models.size(); i++) {
index c085ecf043751a1c2614742afb0865475c2f9763..0a0a2eb05396685a51fef4382d2f68f4f8095acc 100644 (file)
@@ -3,7 +3,17 @@
 in vec2 out_texcoord;
 out vec4 outcolor;
 uniform sampler2D tex;
+in flat int special;
 
 void main(void) {
        outcolor = texture(tex, out_texcoord);
+       if(special == 1){
+               outcolor = outcolor.gbra;
+               if(outcolor.r + outcolor.g + outcolor.b < 1.5f){
+                       outcolor = vec4(outcolor.rgb * 2.0f, 1.0f);
+               }
+       }
+       if(special == 2){
+               outcolor = outcolor.bgra;
+       }
 }
index 008fd939c5a10392569c8bec5d714a873952d22b..8dbd07a4debd1fe00e06bca74cf90d7363575305 100644 (file)
@@ -3,12 +3,17 @@
 layout(packed, binding=0) buffer model_list {
        mat4 models[];
 };
+layout(packed, binding=1) buffer special_list {
+       int instance_special[];
+};
 in vec3 in_vertex;
 in vec2 in_texcoord;
 uniform mat4 vp;
 out vec2 out_texcoord;
+out flat int special;
 
 void main(void) { 
        gl_Position = vp * models[gl_InstanceID] * vec4(in_vertex, 1.0);
        out_texcoord = in_texcoord;
+       special = instance_special[gl_InstanceID];
 }
diff --git a/textures/chalet.jpg b/textures/chalet.jpg
new file mode 100644 (file)
index 0000000..55e2dae
Binary files /dev/null and b/textures/chalet.jpg differ