]> isoptera.lcsc.edu Git - example_engine/.git/commitdiff
Added rolling spheres
authorSeth Long <sslong@lcsc.edu>
Thu, 21 Nov 2024 05:08:44 +0000 (21:08 -0800)
committerSeth Long <sslong@lcsc.edu>
Thu, 21 Nov 2024 05:08:44 +0000 (21:08 -0800)
12 files changed:
carpet.jpg [new file with mode: 0644]
floor_fragment_shader.glsl
game.h
geometric_objects.cpp
geometric_objects.h
main.cpp
sphere_fs.glsl [new file with mode: 0644]
sphere_gs.glsl [new file with mode: 0644]
sphere_tcs.glsl [new file with mode: 0644]
sphere_tes.glsl [new file with mode: 0644]
sphere_vs.glsl [new file with mode: 0644]
vehicle.h

diff --git a/carpet.jpg b/carpet.jpg
new file mode 100644 (file)
index 0000000..1067016
Binary files /dev/null and b/carpet.jpg differ
index ac6612a6106991a54b5d12e6446dcffd91f29b77..6f7e078f583ad7e71a2c6b6002de20cb2beaa54e 100644 (file)
@@ -4,5 +4,6 @@ in vec4 fcolor;
 out vec4 outcolor;
 
 void main(void) {
-  outcolor = vec4(fcolor.xyz, 1);
+  float brightness = 0.25 * (fcolor.x + fcolor.y + fcolor.z);
+  outcolor = vec4(brightness, brightness, brightness, 1);
 }
diff --git a/game.h b/game.h
index 8ba01d775d14ba424ffd59cb8c4e236799f1cddc..e49caaba43847afa475edb97cf8175155e8924c8 100644 (file)
--- a/game.h
+++ b/game.h
@@ -124,3 +124,8 @@ EXTERN vehicle *current_vehicle INIT(0);
 EXTERN size_t vehicle_index INIT(0);
 
 
+// Objects defined in other header files that need to be global anyway
+#include "hud.h"
+EXTERN hud main_hud;
+
+
index afbe5bda2dfa4c0163e1545d052160d3dbc17170..abf15433fe57be5b3764c51747624f071260ae27 100644 (file)
@@ -99,3 +99,153 @@ void flat_panel::draw(glm::mat4 vp)  {
 
        glDrawArraysInstanced(GL_TRIANGLES, 0, 6, models.size());
 }
+
+int sphere::init() {
+       /* Note:  These are not really interpreted literally!
+        * x = sideways
+        * y = foward
+        * z = up
+        * sideways is forward cross up
+        * color, for now, is the color of each corner, with -1 interpreted as 0
+        */
+       size = glm::vec3(10, 10, 10);
+       float vertices[] = {
+               // front
+               -1.0, -1.0,  1.0,
+               1.0, -1.0,  1.0,
+               1.0,  1.0,  1.0,
+               -1.0,  1.0,  1.0,
+               // back
+               -1.0, -1.0, -1.0,
+               1.0, -1.0, -1.0,
+               1.0,  1.0, -1.0,
+               -1.0,  1.0, -1.0,
+       };
+       glGenBuffers(1, &vbuf);
+       glBindBuffer(GL_SHADER_STORAGE_BUFFER, vbuf);
+       glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+       GLushort cube_elements[] = {
+               // front
+               0, 1, 2,
+               2, 3, 0,
+               // top
+               1, 5, 6,
+               6, 2, 1,
+               // back
+               7, 6, 5,
+               5, 4, 7,
+               // bottom
+               4, 0, 3,
+               3, 7, 4,
+               // left
+               4, 5, 1,
+               1, 0, 4,
+               // right
+               3, 2, 6,
+               6, 7, 3,
+       };
+       glGenBuffers(1, &ebuf);
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebuf);
+       glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);
+
+       program = make_program("sphere_vs.glsl", "sphere_tcs.glsl", "sphere_tes.glsl", "sphere_gs.glsl", "sphere_fs.glsl");
+       if (!program)
+               return 1;
+
+
+       glGenBuffers(1, &models_buffer);
+       glGenBuffers(1, &ups_buffer);
+       glGenBuffers(1, &forwards_buffer);
+       glGenBuffers(1, &radii_buffer);
+
+       v_attrib = glGetAttribLocation(program, "in_vertex");
+       mvp_uniform = glGetUniformLocation(program, "vp");
+       return 0;
+}
+
+void sphere::draw(glm::mat4 vp){
+       glUseProgram(program);
+       data_mutex.lock();
+
+       std::vector<glm::mat4> models;
+       models.reserve(locations.size());
+       for(size_t i = 0; i < locations.size(); i++){
+               glm::mat4 new_model = glm::mat4(1.0f);
+               new_model = glm::translate(new_model, locations[i]);
+               models.push_back(new_model);
+       }
+
+
+       glBindBuffer(GL_SHADER_STORAGE_BUFFER, models_buffer);
+       glBufferData(GL_SHADER_STORAGE_BUFFER, models.size() * sizeof(glm::mat4), models.data(), GL_STATIC_DRAW);
+       glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, models_buffer);
+       
+       glBindBuffer(GL_SHADER_STORAGE_BUFFER, ups_buffer);
+       glBufferData(GL_SHADER_STORAGE_BUFFER, ups.size() * sizeof(ups[0]), ups.data(), GL_STATIC_DRAW);
+       glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ups_buffer);
+       
+       glBindBuffer(GL_SHADER_STORAGE_BUFFER, forwards_buffer);
+       glBufferData(GL_SHADER_STORAGE_BUFFER, forwards.size() * sizeof(forwards[0]), forwards.data(), GL_STATIC_DRAW);
+       glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, forwards_buffer);
+
+       glBindBuffer(GL_SHADER_STORAGE_BUFFER, radii_buffer);
+       glBufferData(GL_SHADER_STORAGE_BUFFER, radii.size() * sizeof(float), radii.data(), GL_STATIC_DRAW);
+       glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, radii_buffer);
+       
+       
+       data_mutex.unlock();
+
+       glEnableVertexAttribArray(v_attrib);
+       glBindBuffer(GL_ARRAY_BUFFER, vbuf);
+       glVertexAttribPointer(v_attrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
+       
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebuf);
+
+       glUniformMatrix4fv(mvp_uniform, 1, 0, glm::value_ptr(vp));
+
+       glPatchParameteri(GL_PATCH_VERTICES, 3);
+       glDrawElementsInstanced(GL_PATCHES, 36, GL_UNSIGNED_SHORT, 0, models.size());
+}
+
+void sphere::addsphere(glm::vec3 location, float radius, glm::vec3 up, glm::vec3 forward){
+       locations.push_back(location);
+       radii.push_back(radius);
+       ups.push_back(glm::vec4(up, 1.0f));
+       forwards.push_back(glm::vec4(forward, 1.0f));
+}
+
+void rollsphere::roll_to(size_t index, glm::vec3 new_location, float speed){
+       speeds[index] = speed;
+       new_locations[index] = new_location;
+       new_locations[index].y = locations[index].y;
+       float angular_velocity = speed / radii[index];
+       glm::vec3 axis = glm::cross(new_locations[index] - locations[index], glm::vec3(0, 1, 0));
+       main_hud.lprintf(0, "Angular Velocity:  %f, axis %f, %f, %f\n", angular_velocity, axis.x, axis.y, axis.z);
+       rotation_matrices[index] = glm::rotate(glm::mat4(1.0f), -angular_velocity, axis);
+}
+
+void rollsphere::move(int elapsed_time){
+       for(size_t i = 0; i < locations.size(); i++){
+               if(speeds[i] > 0.0001){
+                       glm::vec3 direction = glm::normalize(new_locations[i] - locations[i]);
+                       locations[i] += speeds[i] * direction;
+                       ups[i] = rotation_matrices[i] * ups[i];
+                       forwards[i] = rotation_matrices[i] * forwards[i];
+                       if(glm::length(new_locations[i] - locations[i]) < 0.01)
+                               speeds[i] = 0.0f;
+               }
+       }
+}
+
+void rollsphere::addsphere(glm::vec3 location, float radius, glm::vec3 up, glm::vec3 forward){
+       sphere::addsphere(location, radius, up, forward);
+       new_locations.push_back(location);
+       speeds.push_back(0);
+       rotation_matrices.push_back(glm::mat4(1.0));
+}
+
+void rollsphere::activate(size_t index){
+       roll_to(index, locations[index] + glm::normalize(locations[index] - player_position) * 100.0f, 0.01);
+}
+
index 107ec5d5a6378d6c201098f7eb5aca309c93337b..4e5751c060059a1f7a3720930b44933009b5a5f2 100644 (file)
@@ -52,3 +52,28 @@ public:
                        set_normal(i, locations[i] - player_position);
        }
 };
+
+class sphere : virtual public gameobject {
+public:
+       std::vector<float> radii;
+       std::vector<glm::vec4> ups;
+       std::vector<glm::vec4> forwards;
+       unsigned radii_buffer, ups_buffer, forwards_buffer;
+       const char* texturefile;
+
+       int init() override;
+       void draw(glm::mat4 vp) override;
+       virtual void addsphere(glm::vec3 location, float radius, glm::vec3 up = glm::vec3(0, 1, 0), glm::vec3 forward = glm::vec3(0, 0, 1));
+};
+
+class rollsphere : virtual public sphere, virtual public block_object {
+public:
+       std::vector<glm::vec3> new_locations;
+       std::vector<float> speeds;
+       std::vector<glm::mat4> rotation_matrices;
+
+       void roll_to(size_t index, glm::vec3 new_location, float speed);
+       void move(int elapsed_time);
+       void addsphere(glm::vec3 location, float radius, glm::vec3 up = glm::vec3(0, 1, 0), glm::vec3 forward = glm::vec3(0, 0, 1));
+       void activate(size_t index); // For testing, roll 30 units along -x
+};
index b2e8fa6f88484234706c3530e9de82a61c095b78..0c2f50707ccdc67f01a2730ca6671f0f6517dc4a 100644 (file)
--- a/main.cpp
+++ b/main.cpp
 #include "moving_platform.h"
 #include "turret.h"
 #include "geometric_objects.h"
-#include "hud.h"
 #include "door.h"
 #include "vehicle.h"
 
 std::mutex grand_mutex;
 
-float height = 1600;
-float width = 2550;
+float height = 2080 ;
+float width = 3820 ;
 
 /* Global section */
 int time_resolution = 10;
@@ -30,7 +29,6 @@ std::vector<gameobject*> objects;
 projectile ice_balls;
 wall_block spawned_blocks("cube.obj", "projectile.jpg", glm::vec3(2, 2, 2));
 fragment brick_fragments;
-hud main_hud;
 
 class target : public loaded_object, public block_object {
        public:
@@ -432,6 +430,13 @@ int main(int argc, char** argv) {
        fc.addpanel(glm::vec3(30, -5, 450), glm::vec2(3.0, 3.0), glm::vec2(1, 1));
        objects.push_back(&fc);
 
+       rollsphere test_sphere;
+       test_sphere.addsphere(glm::vec3(30, 0, 510), 5);
+       test_sphere.addsphere(glm::vec3(30, 40, 510), 20);
+       test_sphere.addsphere(glm::vec3(20, -2, 530), 3);
+       test_sphere.addsphere(glm::vec3(-30, 10, 530), 20);
+       objects.push_back(&test_sphere);
+
        /* Initialize game objects */
        for(gameobject* o : objects){
                if(o->init()){
diff --git a/sphere_fs.glsl b/sphere_fs.glsl
new file mode 100644 (file)
index 0000000..3072216
--- /dev/null
@@ -0,0 +1,8 @@
+#version 460
+
+in vec4 gs_colorout;
+out vec4 outcolor;
+
+void main(void) {
+  outcolor = vec4(gs_colorout.xyz, 1); 
+}
diff --git a/sphere_gs.glsl b/sphere_gs.glsl
new file mode 100644 (file)
index 0000000..f245b13
--- /dev/null
@@ -0,0 +1,23 @@
+#version 450
+
+layout(triangles, invocations=1) in;
+in vec4 tes_colorout[]; 
+layout(line_strip, max_vertices=6) out;
+out vec4 gs_colorout;
+
+void main(void) {
+
+       gl_Position = gl_in[0].gl_Position;
+       gs_colorout = tes_colorout[0];
+       EmitVertex();
+       gl_Position = gl_in[1].gl_Position;
+       gs_colorout = tes_colorout[1];
+       EmitVertex();
+       gl_Position = gl_in[2].gl_Position;
+       gs_colorout = tes_colorout[2];
+       EmitVertex();
+       gl_Position = gl_in[0].gl_Position;
+       gs_colorout = tes_colorout[0];
+       EmitVertex();
+       EndPrimitive();
+}
diff --git a/sphere_tcs.glsl b/sphere_tcs.glsl
new file mode 100644 (file)
index 0000000..262e02e
--- /dev/null
@@ -0,0 +1,18 @@
+#version 460
+layout(vertices=3) out;
+
+in int vs_id[];
+in vec4 v_colorout[];
+out vec4 tcs_colorout[];
+out int vs_id_tcs[];
+
+void main(void) {
+       int tesslv = 12;
+       gl_TessLevelOuter[0] = tesslv;
+       gl_TessLevelOuter[1] = tesslv;
+       gl_TessLevelOuter[2] = tesslv;
+       gl_TessLevelInner[0] = tesslv;
+       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
+       tcs_colorout[gl_InvocationID] = v_colorout[gl_InvocationID];
+       vs_id_tcs[gl_InvocationID] = vs_id[gl_InvocationID];
+}
diff --git a/sphere_tes.glsl b/sphere_tes.glsl
new file mode 100644 (file)
index 0000000..973f7aa
--- /dev/null
@@ -0,0 +1,41 @@
+#version 460
+layout(triangles, equal_spacing, ccw) in;
+
+  
+layout(packed, binding=0) buffer model_list {
+        mat4 models[];
+};
+layout(packed, binding=1) buffer up_list {
+        vec3 ups[];
+};
+layout(packed, binding=2) buffer forward_list {
+        vec3 forwards[];
+};
+layout(packed, binding=3) buffer radii_list {
+        float radii[];
+};
+
+uniform mat4 vp;
+in vec4 tcs_colorout[];
+in int vs_id_tcs[];
+out vec4 tes_colorout;
+
+vec4 n4(vec4 p){
+       vec3 offset = p.xyz;// - cntr[0].xyz;
+       return vec4(normalize(offset) * radii[vs_id_tcs[0]], 1);
+}
+
+void main(){
+       vec4 p = 
+                       gl_TessCoord.x * gl_in[0].gl_Position +
+                       gl_TessCoord.y * gl_in[1].gl_Position +
+                       gl_TessCoord.z * gl_in[2].gl_Position;
+
+       gl_Position = vp * models[vs_id_tcs[0]] * n4(p);
+
+       tes_colorout = 
+                       gl_TessCoord.x * tcs_colorout[0] +
+                       gl_TessCoord.y * tcs_colorout[1] +
+                       gl_TessCoord.z * tcs_colorout[2];
+}
+
diff --git a/sphere_vs.glsl b/sphere_vs.glsl
new file mode 100644 (file)
index 0000000..d1bd307
--- /dev/null
@@ -0,0 +1,39 @@
+#version 460
+
+  
+layout(packed, binding=0) buffer model_list {
+        mat4 models[];
+};
+layout(packed, binding=1) buffer up_list {
+        vec3 ups[];
+};
+layout(packed, binding=2) buffer forward_list {
+        vec3 forwards[];
+};
+layout(packed, binding=3) buffer radii_list {
+        float radii[];
+};
+
+
+in vec3 in_vertex;
+uniform mat4 vp;
+out vec4 v_colorout;
+out int vs_id;
+
+void main(void) {
+       vec3 sideways = normalize(cross(ups[gl_InstanceID], forwards[gl_InstanceID]));
+       vec3 pos =  in_vertex.x * sideways +
+         in_vertex.y * forwards[gl_InstanceID] +
+         in_vertex.z * ups[gl_InstanceID]; 
+
+       gl_Position = vec4(pos, 1.0);
+       v_colorout = vec4(in_vertex, 1.0);
+       if(v_colorout.r < 0)
+               v_colorout.r = 0;
+       if(v_colorout.g < 0)
+               v_colorout.g = 0;
+       if(v_colorout.b < 0)
+               v_colorout.b = 0;
+       vs_id = gl_InstanceID;
+
+}
index 54829bb3acf2bd0a7bfe067c4c359f02417a2d63..92219e23c560db61a2aeca7436d880ed7e95898e 100644 (file)
--- a/vehicle.h
+++ b/vehicle.h
@@ -4,7 +4,7 @@
 
 class flying_carpet : virtual public vehicle, virtual public flat_panel {
 public:
-       flying_carpet() : flat_panel("brick.jpg") {
+       flying_carpet() : flat_panel("carpet.jpg") {
                size = glm::vec3(10, 1, 10);
        }