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
--- /dev/null
+#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);
+ }
+};
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;
/* Properties not related to OpenGL */
vector<mat4> models;
+ vector<int> specials;
bool visible = true;
void add_location(vec3 location);
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
#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"
void GameObject::add_location(vec3 location){
models.push_back(translate(mat4(1.0), location));
+ specials.push_back(0);
}
char log_buffer[2048];
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);
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);
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());
#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 << "}";
}
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);
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";
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){
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]--;
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;
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);
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;
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++) {
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;
+ }
}
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];
}