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);
+}
+
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
+};
#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;
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:
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()){