#include "game.h" #include "geometric_objects.h" int flat_panel::init() { // Initialization part float vertices[] = { -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); program = make_program("normal_panel_vertex_shader.glsl",0, 0, 0, "loaded_object_fragment_shader.glsl"); if (!program) return 1; tex = load_texture(texturefile); glGenBuffers(1, &models_buffer); glGenBuffers(1, &scales_buffer); glGenBuffers(1, &normals_buffer); glGenBuffers(1, &ups_buffer); glGenBuffers(1, &object_scales_buffer); v_attrib = glGetAttribLocation(program, "in_vertex"); mvp_uniform = glGetUniformLocation(program, "vp"); return 0; } void flat_panel::addpanel(glm::vec3 location, glm::vec2 object_scale, glm::vec2 texture_scale, glm::vec3 normal, glm::vec3 up){ locations.push_back(location); object_scales.push_back(object_scale); texture_scales.push_back(texture_scale); normals.push_back(glm::vec4(glm::normalize(normal), 1.0f)); ups.push_back(glm::vec4(glm::normalize(up), 1.0f)); } void flat_panel::rotate(size_t index, float angle, glm::vec3 axis){ } void flat_panel::set_normal(size_t index, glm::vec3 normal){ normals[index] = glm::vec4(glm::normalize(normal), 1.0f); } void flat_panel::set_up(size_t index, glm::vec3 up){ ups[index] = glm::vec4(glm::normalize(up), 1.0f); } std::vector flat_panel::create_models(){ std::vector 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); } return models; } void flat_panel::draw(glm::mat4 vp) { glUseProgram(program); data_mutex.lock(); std::vector models = create_models(); 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, scales_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, texture_scales.size() * sizeof(glm::vec2), texture_scales.data(), GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, scales_buffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, normals_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, normals.size() * sizeof(normals[0]), normals.data(), GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, normals_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, 3, ups_buffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, object_scales_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, object_scales.size() * sizeof(object_scales[0]), object_scales.data(), GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, object_scales_buffer); data_mutex.unlock(); glEnableVertexAttribArray(v_attrib); glBindBuffer(GL_ARRAY_BUFFER, vbuf); glVertexAttribPointer(v_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glUniformMatrix4fv(mvp_uniform, 1, 0, glm::value_ptr(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 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){ data_mutex.lock(); 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)); rotation_matrices[index] = glm::rotate(glm::mat4(1.0f), -angular_velocity, axis); data_mutex.unlock(); } void rollsphere::move(int elapsed_time){ data_mutex.lock(); 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]) < speeds[i]) speeds[i] = 0.0f; } } data_mutex.unlock(); } 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); }