A WIP 3D game engine in C++ using OpenGL
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
6.3 KiB

#include "drawing.h"
#include "glutil.h"
#include "level.h"
#include "debug_flags.h"
namespace drawing {
void instanced_draw(const instanced_renderer r, const glm::mat4 view, const glm::mat4 projection) {
r.shader->use();
int loc = r.shader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
glDrawArraysInstanced(GL_TRIANGLES, 0,36,1000);
}
instanced_renderer instanced_setup(Shader* shader, const std::vector<position> &positions) {
GLuint instance_VBO;
glGenBuffers(1, &instance_VBO);
glBindBuffer(GL_ARRAY_BUFFER, instance_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(object) * positions.size(), &positions[0], GL_STATIC_DRAW);
glVertexAttribPointer(3,3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)offsetof(position, position));
glVertexAttribPointer(5,16, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void *)offsetof(position, orientation));
glVertexAttribDivisor(3,1);
glVertexAttribDivisor(5,1);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(5);
return instanced_renderer {instance_VBO, shader};
}
void instanced_update(const instanced_renderer r, const std::vector<position> &positions) {
glBindBuffer(GL_ARRAY_BUFFER, r.vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(object) * positions.size(), &positions[0], GL_STATIC_DRAW);
}
void noninstanced_set_camera(Shader *shader, const glm::mat4 view, const glm::mat4 projection) {
shader->use();
glCheckError();
int loc = shader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
glCheckError();
}
void noninstanced_draw(std::vector<position> objects, Model * model, Shader *shader, const glm::mat4 view, const glm::mat4 projection) {
int i = 0;
for (auto obj: objects) {
glCheckError();
int loc = shader->get_uniform("model");
glCheckError();
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(obj.orientation));
glCheckError();
auto this_view = glm::translate(view, obj.position);
loc = shader->get_uniform("view");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(this_view));
glCheckError();
model->draw(shader);
glCheckError();
}
}
}
// class simple_object_draw_system : public drawing_object_handle {
simple_object_draw_system::simple_object_draw_system(Shader *shader) : shader(shader) {}
int simple_object_draw_system::add(std::shared_ptr<Model> model, glm::vec3 position, glm::mat4 orientation) {
objects.push_back({position, orientation, model});
return objects.size() - 1;
}
void simple_object_draw_system::remove(int i) {
do_not_draw.insert(i);
}
void simple_object_draw_system::return_to_draw_list(int i) {
do_not_draw.erase(i);
}
void simple_object_draw_system::draw(int i, const glm::mat4 view, const glm::mat4 projection) {
shader->use();
int loc = shader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
auto obj = objects[i];
loc = shader->get_uniform("model");
glCheckError();
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(obj.orientation));
glCheckError();
printProgramLog(shader->program);
auto this_view = glm::translate(view, obj.position);
loc = shader->get_uniform("view");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(this_view));
glCheckError();
obj.model->draw(shader);
glCheckError();
}
void simple_object_draw_system::draw(const glm::mat4 view, const glm::mat4 projection) {
shader->use();
glCheckError();
glCheckError();
int loc = shader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
glCheckError();
int i = 0;
for (auto obj: objects) {
glCheckError();
int loc = shader->get_uniform("model");
glCheckError();
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(obj.orientation));
glCheckError();
auto this_view = glm::translate(view, obj.position);
loc = shader->get_uniform("view");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(this_view));
glCheckError();
obj.model->draw(shader);
glCheckError();
}
}
void setup_shader(Shader *shader, const glm::mat4 view, const glm::mat4 projection, const glm::vec3 position, const glm::mat4 orientation) {
shader->use();
shader->setMat4("projection", projection);
shader->setMat4("model", orientation);
shader->setMat4("view", glm::translate(view, position));
}
void draw_objects(Shader *shader, const std::vector<physics_model> positions, std::shared_ptr<Model> m, const glm::mat4 view, const glm::mat4 projection) {
shader->use();
shader->setMat4("projection", projection);
int i = 0;
for (auto obj: positions) {
shader->setMat4("model", obj.orientation);
auto this_view = glm::translate(view, obj.pos);
shader->setMat4("view", this_view);
glCheckError();
m->draw(shader);
glCheckError();
}
}
/* Draw a lot of the same object. */
instanced_drawing::instanced_drawing (Model *model, Shader *shader, std::vector<object> obj_models)
: models(obj_models), model(model), shader(shader)
{}
instanced_drawing::instanced_drawing (Model *model, Shader *shader)
: model(model), shader(shader)
{}
int instanced_drawing::finalize () {
glGenBuffers(1, &instance_VBO);
glBindBuffer(GL_ARRAY_BUFFER, instance_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(object) * models.size(), &models[0], GL_STATIC_DRAW);
glVertexAttribPointer(3,3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL);
glVertexAttribPointer(5,16, GL_FLOAT, GL_FALSE, 16 * sizeof(float), (void *)offsetof(object, model));
glVertexAttribDivisor(3,1);
glVertexAttribDivisor(5,1);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(5);
return 0;
}
int instanced_drawing::add(glm::vec3 position, glm::mat4 orientation) {
models.push_back({position, orientation});
return models.size() - 1;
}
void instanced_drawing::draw(const glm::mat4 view, const glm::mat4 projection) {
shader->use();
int loc = shader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
glDrawArraysInstanced(GL_TRIANGLES, 0,36,1000);
}