|
|
|
@ -11,12 +11,15 @@
@@ -11,12 +11,15 @@
|
|
|
|
|
#include <SDL2/SDL_opengl.h> |
|
|
|
|
#include <SDL2/SDL_timer.h> |
|
|
|
|
#include <GL/glu.h> |
|
|
|
|
#include <stdexcept> |
|
|
|
|
#include <string> |
|
|
|
|
#include <iostream> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <cmath> |
|
|
|
|
#include <vector> |
|
|
|
|
#include <map> |
|
|
|
|
#include <stack> |
|
|
|
|
#include <set> |
|
|
|
|
|
|
|
|
|
#include "shaders.h" |
|
|
|
|
#include "mesh.h" |
|
|
|
@ -59,6 +62,8 @@ class Cubemap {
@@ -59,6 +62,8 @@ class Cubemap {
|
|
|
|
|
|
|
|
|
|
int width, height, nrChannels; |
|
|
|
|
|
|
|
|
|
stbi_set_flip_vertically_on_load(false); |
|
|
|
|
|
|
|
|
|
glGenTextures(1, &id); |
|
|
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, id); |
|
|
|
|
|
|
|
|
@ -86,6 +91,150 @@ class Cubemap {
@@ -86,6 +91,150 @@ class Cubemap {
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// handles shaders, models, meshes for drawing a collection of similar objects
|
|
|
|
|
class drawing_object_handle { |
|
|
|
|
public: |
|
|
|
|
virtual void draw(const glm::mat4 view, const glm::mat4 projection) = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class simple_object_draw_system : public drawing_object_handle { |
|
|
|
|
Shader *shader; |
|
|
|
|
|
|
|
|
|
struct object { |
|
|
|
|
glm::vec3 position; |
|
|
|
|
glm::mat4 orientation; |
|
|
|
|
Model model; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
std::vector<object> objects; |
|
|
|
|
std::set<int> do_not_draw; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
simple_object_draw_system(Shader *shader) : shader(shader) {} |
|
|
|
|
|
|
|
|
|
int add(Model model, glm::vec3 position, glm::mat4 orientation) { |
|
|
|
|
objects.push_back({position, orientation, model}); |
|
|
|
|
return objects.size() - 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void remove(int i) { |
|
|
|
|
do_not_draw.insert(i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void return_to_draw_list(int i) { |
|
|
|
|
do_not_draw.erase(i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void draw(const glm::mat4 view, const glm::mat4 projection) override { |
|
|
|
|
shader->use(); |
|
|
|
|
|
|
|
|
|
int loc = shader->get_uniform("projection"); |
|
|
|
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection)); |
|
|
|
|
|
|
|
|
|
int i = 0; |
|
|
|
|
for (auto obj: objects) { |
|
|
|
|
if (do_not_draw.count(i++)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Draw a lot of the same object. */ |
|
|
|
|
class instanced_drawing : public drawing_object_handle { |
|
|
|
|
public: |
|
|
|
|
struct object { |
|
|
|
|
glm::vec3 position; |
|
|
|
|
glm::mat4 model; |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
private: |
|
|
|
|
|
|
|
|
|
std::vector<object> models; |
|
|
|
|
|
|
|
|
|
Model *model; |
|
|
|
|
Shader *shader; |
|
|
|
|
|
|
|
|
|
unsigned int instance_VBO; |
|
|
|
|
public: |
|
|
|
|
instanced_drawing (Model *model, Shader *shader, std::vector<object> obj_models)
|
|
|
|
|
: models(obj_models), model(model), shader(shader)
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
|
instanced_drawing (Model *model, Shader *shader) |
|
|
|
|
: model(model), shader(shader)
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
|
int 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 add(glm::vec3 position, glm::mat4 orientation) { |
|
|
|
|
models.push_back({position, orientation}); |
|
|
|
|
return models.size() - 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void draw(const glm::mat4 view, const glm::mat4 projection) override { |
|
|
|
|
shader->use(); |
|
|
|
|
|
|
|
|
|
int loc = shader->get_uniform("projection"); |
|
|
|
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glDrawArraysInstanced(GL_TRIANGLES, 0,36,1000); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class drawing_system { |
|
|
|
|
|
|
|
|
|
std::vector<drawing_object_handle *> draw_systems; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
void add_system(drawing_object_handle *obj) { |
|
|
|
|
draw_systems.push_back(obj); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void run (void) { |
|
|
|
|
for (auto a : draw_systems) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
void printProgramLog( GLuint program ) |
|
|
|
|
{ |
|
|
|
|
//Make sure name is shader
|
|
|
|
@ -153,17 +302,21 @@ class SDLGLGLWindow {
@@ -153,17 +302,21 @@ class SDLGLGLWindow {
|
|
|
|
|
glm::mat4 model = glm::mat3(1.0f); |
|
|
|
|
glm::mat4 view = glm::mat4(1.0f); |
|
|
|
|
private: |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
Shader *shader; |
|
|
|
|
Shader *modelShader; |
|
|
|
|
Shader *texShader; |
|
|
|
|
Shader *skyboxShader; |
|
|
|
|
Model *bp_model; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int screen_width; |
|
|
|
|
int screen_height; |
|
|
|
|
unsigned int framebuffer; |
|
|
|
|
unsigned int textureColorBufferMultiSampled; |
|
|
|
|
unsigned int textureColorBufferMultiSampledHDR; |
|
|
|
|
unsigned int rbo; |
|
|
|
|
unsigned int intermediateFBO; |
|
|
|
|
unsigned int screenTexture; |
|
|
|
@ -183,6 +336,7 @@ class SDLGLGLWindow {
@@ -183,6 +336,7 @@ class SDLGLGLWindow {
|
|
|
|
|
|
|
|
|
|
float cam_pitch = 0;
|
|
|
|
|
float cam_yaw = -90; |
|
|
|
|
simple_object_draw_system *objects ; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SDLGLGLWindow(int width, int height)
|
|
|
|
@ -194,7 +348,8 @@ class SDLGLGLWindow {
@@ -194,7 +348,8 @@ class SDLGLGLWindow {
|
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lightPositions.push_back(glm::vec3(5.2f, 0.0f, 3.7f)); |
|
|
|
|
lightPositions.push_back(glm::vec3(5.0f, 3.0f, 5.0f)); |
|
|
|
|
lightPositions.push_back(glm::vec3(3.2f, 0.4f, -3.7f)); |
|
|
|
|
lightPositions.push_back(glm::vec3(-3.5f, 0.9f, 7.3f)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -276,6 +431,12 @@ class SDLGLGLWindow {
@@ -276,6 +431,12 @@ class SDLGLGLWindow {
|
|
|
|
|
skyboxShader = new Shader("src/shaders/sky.vert", "src/shaders/sky.frag"); |
|
|
|
|
glCheckError(); |
|
|
|
|
|
|
|
|
|
objects = new simple_object_draw_system(shader); |
|
|
|
|
|
|
|
|
|
modelShader->use(); |
|
|
|
|
stbi_set_flip_vertically_on_load(true); |
|
|
|
|
objects->add(Model("src/assets/objects/backpack/backpack.obj"), {0,0,0}, glm::mat4(1.0)); |
|
|
|
|
|
|
|
|
|
//Link program
|
|
|
|
|
stbi_set_flip_vertically_on_load(true); |
|
|
|
|
|
|
|
|
@ -287,6 +448,10 @@ class SDLGLGLWindow {
@@ -287,6 +448,10 @@ class SDLGLGLWindow {
|
|
|
|
|
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); |
|
|
|
|
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* generate a framebuffer to draw to
|
|
|
|
|
glGenFramebuffers(1, &framebuffer); |
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); |
|
|
|
@ -320,11 +485,13 @@ class SDLGLGLWindow {
@@ -320,11 +485,13 @@ class SDLGLGLWindow {
|
|
|
|
|
glGenFramebuffers(1, &framebuffer); |
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); |
|
|
|
|
// create a multisampled color attachment texture
|
|
|
|
|
glGenTextures(1, &textureColorBufferMultiSampled); |
|
|
|
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled); |
|
|
|
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, screen_width, screen_height, GL_TRUE); |
|
|
|
|
glGenTextures(1, &textureColorBufferMultiSampledHDR); |
|
|
|
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampledHDR); |
|
|
|
|
|
|
|
|
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA16F, screen_width, screen_height, GL_TRUE); |
|
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); |
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0); |
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampledHDR, 0); |
|
|
|
|
// create a (also multisampled) renderbuffer object for depth and stencil attachments
|
|
|
|
|
glGenRenderbuffers(1, &rbo); |
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, rbo); |
|
|
|
@ -528,7 +695,7 @@ class SDLGLGLWindow {
@@ -528,7 +695,7 @@ class SDLGLGLWindow {
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, instance_VBO); |
|
|
|
|
glVertexAttribPointer(3,3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); |
|
|
|
|
glVertexAttribDivisor(3,1); |
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0); |
|
|
|
|
//glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
glEnableVertexAttribArray(3); |
|
|
|
|
|
|
|
|
|
/*********** ENDCUBES **************/ |
|
|
|
@ -620,8 +787,9 @@ class SDLGLGLWindow {
@@ -620,8 +787,9 @@ class SDLGLGLWindow {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
modelShader->setInt("num_lights", 1); |
|
|
|
|
modelShader->setInt("lights[0].type", 0); |
|
|
|
|
modelShader->setInt("lights[0].type", 1); |
|
|
|
|
modelShader->setFloat("lights[0].angle_cutoff", glm::cos(glm::radians(12.5f))); |
|
|
|
|
modelShader->setFloat("lights[0].outer_angle_cutoff", glm::cos(glm::radians(17.5f))); |
|
|
|
|
|
|
|
|
@ -629,28 +797,28 @@ class SDLGLGLWindow {
@@ -629,28 +797,28 @@ class SDLGLGLWindow {
|
|
|
|
|
modelShader->setVec3("lights[0].position", camera_pos); |
|
|
|
|
|
|
|
|
|
modelShader->setVec3("lights[0].ambient", glm::vec3(0.1)); |
|
|
|
|
modelShader->setVec3("lights[0].diffuse", glm::vec3(0.8,0.7,1.0) * glm::vec3(0.5)); |
|
|
|
|
modelShader->setVec3("lights[0].diffuse", glm::vec3(0.8,0.7,1.0) * glm::vec3(200)); |
|
|
|
|
modelShader->setVec3("lights[0].specular", glm::vec3(1.0)); |
|
|
|
|
modelShader->setBool("lights[0].attenuate", false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
shader->setInt("num_lights", 3); |
|
|
|
|
shader->setInt("lights[0].type", 0); |
|
|
|
|
shader->setInt("lights[0].type", 1); |
|
|
|
|
shader->setFloat("lights[0].angle_cutoff", glm::cos(glm::radians(12.5f))); |
|
|
|
|
shader->setFloat("lights[0].outer_angle_cutoff", glm::cos(glm::radians(17.5f))); |
|
|
|
|
|
|
|
|
|
shader->setVec3("lights[0].direction", glm::vec3(0,-1,0)); |
|
|
|
|
shader->setVec3("lights[0].position", camera_pos); |
|
|
|
|
// shader->setVec3("lights[0].position", camera_pos);
|
|
|
|
|
|
|
|
|
|
shader->setVec3("lights[0].ambient", glm::vec3(0.1)); |
|
|
|
|
shader->setVec3("lights[0].diffuse", glm::vec3(0.8,0.7,1.0) * glm::vec3(0.5)); |
|
|
|
|
shader->setVec3("lights[0].position", lightPositions[0]); |
|
|
|
|
shader->setVec3("lights[0].ambient", glm::vec3(0.5)); |
|
|
|
|
shader->setVec3("lights[0].diffuse", glm::vec3(0.9,0.7,1.0) * glm::vec3(10)); |
|
|
|
|
shader->setVec3("lights[0].specular", glm::vec3(1.0)); |
|
|
|
|
shader->setBool("lights[0].attenuate", false); |
|
|
|
|
// shader->setVec3("lights[0].attenuation", glm::vec3(1.0, 0.09, 0.032));
|
|
|
|
|
shader->setInt("lights[1].type", 1); |
|
|
|
|
shader->setVec3("lights[1].position", lightPositions[0]); |
|
|
|
|
shader->setVec3("lights[0].attenuation", glm::vec3(1.0, 0.09, 0.032)); |
|
|
|
|
|
|
|
|
|
shader->setInt("lights[1].type", 1); |
|
|
|
|
shader->setVec3("lights[1].position", lightPositions[1]); |
|
|
|
|
shader->setVec3("lights[1].ambient", glm::vec3(0.1)); |
|
|
|
|
shader->setVec3("lights[1].diffuse", glm::vec3(0.6, 0.4, 0.4)); |
|
|
|
|
shader->setVec3("lights[1].specular", glm::vec3(1.0)); |
|
|
|
@ -708,6 +876,7 @@ class SDLGLGLWindow {
@@ -708,6 +876,7 @@ class SDLGLGLWindow {
|
|
|
|
|
|
|
|
|
|
glm::mat4 model = glm::mat4(1.0f); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int loc = shader->get_uniform("model");
|
|
|
|
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model)); |
|
|
|
|
glCheckError(); |
|
|
|
@ -726,25 +895,27 @@ class SDLGLGLWindow {
@@ -726,25 +895,27 @@ class SDLGLGLWindow {
|
|
|
|
|
glCheckError(); |
|
|
|
|
|
|
|
|
|
model = glm::mat4(1.0); |
|
|
|
|
model = glm::rotate(model, glm::radians( 20.0f + 160.0f *(float)SDL_GetTicks() / 1000.0f), glm::vec3(0.6, 0.3, 1.0)); |
|
|
|
|
// model = glm::rotate(model, glm::radians( 20.0f + 160.0f *(float)SDL_GetTicks() / 1000.0f), glm::vec3(0.6, 0.3, 1.0));
|
|
|
|
|
glCheckError(); |
|
|
|
|
loc = modelShader->get_uniform("model"); |
|
|
|
|
loc = shader->get_uniform("model"); |
|
|
|
|
glCheckError(); |
|
|
|
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model)); |
|
|
|
|
glCheckError(); |
|
|
|
|
|
|
|
|
|
loc = modelShader->get_uniform("view"); |
|
|
|
|
loc = shader->get_uniform("view"); |
|
|
|
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(view)); |
|
|
|
|
glCheckError(); |
|
|
|
|
|
|
|
|
|
loc = modelShader->get_uniform("projection"); |
|
|
|
|
loc = shader->get_uniform("projection"); |
|
|
|
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection)); |
|
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); |
|
|
|
|
|
|
|
|
|
bp_model->draw(*shader); |
|
|
|
|
//objects->draw(view, projection);
|
|
|
|
|
glCheckError(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//*** Draw random cubes ****/
|
|
|
|
|
shader->use(); |
|
|
|
|
|
|
|
|
@ -871,6 +1042,9 @@ class SDLGLGLWindow {
@@ -871,6 +1042,9 @@ class SDLGLGLWindow {
|
|
|
|
|
printProgramLog(texShader->program); |
|
|
|
|
glCheckError(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -912,6 +1086,8 @@ int main(int argc, char **argv) {
@@ -912,6 +1086,8 @@ int main(int argc, char **argv) {
|
|
|
|
|
bool mouse_mode = true; |
|
|
|
|
|
|
|
|
|
std::cout << "Rendering now\n"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//While application is running
|
|
|
|
|
while( !quit ) |
|
|
|
|
{ |
|
|
|
|