Browse Source

billboard

master
alistair 2 years ago
parent
commit
9e0e6c778b
  1. 13
      data/levels/init.json
  2. 2
      src/drawing.cpp
  3. 6
      src/entity.h
  4. 46
      src/level.cpp
  5. 5
      src/level.h
  6. 151
      src/main.cpp
  7. 2
      src/mesh.h
  8. 38
      src/player.cpp
  9. 51
      src/player.h
  10. 2
      src/shaders.cpp

13
data/levels/init.json

@ -4,6 +4,9 @@ @@ -4,6 +4,9 @@
"room": {
"object": "room.obj"
},
"blob": {
"object": "blob.obj"
},
"backpack": {
"object": "backpack.obj",
"fliptextures": true,
@ -35,6 +38,13 @@ @@ -35,6 +38,13 @@
}
],
"entities": [
{
"draw": {"billboardmodel": "blob"},
"physics": {
"position": [0,0,0],
"orientation": [0,0,0]
}
},
{
"draw": {"model": "room"},
"physics": {
@ -49,5 +59,8 @@ @@ -49,5 +59,8 @@
"orientation": [0,0,0]
}
}
],
"particleemitters": [
]
}

2
src/drawing.cpp

@ -144,6 +144,8 @@ void simple_object_draw_system::draw(const glm::mat4 view, const glm::mat4 proj @@ -144,6 +144,8 @@ void simple_object_draw_system::draw(const glm::mat4 view, const glm::mat4 proj
}
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();

6
src/entity.h

@ -2,9 +2,15 @@ @@ -2,9 +2,15 @@
#include <glm/common.hpp>
#pragma once
enum class entity_type {
STATIC_MESH,
BILLBOARD
};
// entity slug
struct entity {
int id;
entity_type type;
int physics;
int model;
int light;

46
src/level.cpp

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
#include "level.h"
#include "player.h"
#include <glm/ext/vector_float3.hpp>
@ -18,17 +20,22 @@ void update_lights(Shader * shader, json &j) { @@ -18,17 +20,22 @@ void update_lights(Shader * shader, json &j) {
glCheckError();
shader->setInt(fmt::format("lights[{}].type", i), LIGHT_TYPES.at(l["type"]));
glCheckError();
shader->setVec3(fmt::format("lights[{}].position", i),glm::vec3(l["position"][0],l["position"][1], l["position"][2]));
shader->setVec3(fmt::format("lights[{}].position", i),
glm::vec3(l["position"][0],l["position"][1], l["position"][2]));
glCheckError();
shader->setVec3(fmt::format("lights[{}].ambient", i), glm::vec3(l["ambient"][0],l["ambient"][1], l["ambient"][2]));
shader->setVec3(fmt::format("lights[{}].ambient", i),
glm::vec3(l["ambient"][0],l["ambient"][1], l["ambient"][2]));
glCheckError();
shader->setVec3(fmt::format("lights[{}].diffuse", i), glm::vec3(l["diffuse"][0],l["diffuse"][1], l["diffuse"][2]));
shader->setVec3(fmt::format("lights[{}].diffuse", i),
glm::vec3(l["diffuse"][0],l["diffuse"][1], l["diffuse"][2]));
glCheckError();
shader->setVec3(fmt::format("lights[{}].specular", i), glm::vec3(l["specular"][0],l["specular"][1], l["specular"][2]));
shader->setVec3(fmt::format("lights[{}].specular", i),
glm::vec3(l["specular"][0],l["specular"][1], l["specular"][2]));
glCheckError();
shader->setBool(fmt::format("lights[{}].attenuate", i), l["attenuate"]);
glCheckError();
shader->setVec3(fmt::format("lights[{}].attenuation", i), glm::vec3(l["attenuation"][0],l["attenuation"][1], l["attenuation"][2]));
shader->setVec3(fmt::format("lights[{}].attenuation", i),
glm::vec3(l["attenuation"][0],l["attenuation"][1], l["attenuation"][2]));
glCheckError();
i++;
@ -42,7 +49,6 @@ void update_lights(Shader * shader, json &j) { @@ -42,7 +49,6 @@ void update_lights(Shader * shader, json &j) {
glCheckError();
}
void level::load_entities(json j) {
@ -57,6 +63,11 @@ void level::load_entities(json j) { @@ -57,6 +63,11 @@ void level::load_entities(json j) {
if (m["draw"].count("model")) {
model = true;
e.model = model_ids.at(m["draw"].at("model"));
e.type = entity_type::STATIC_MESH;
} else if (m["draw"].count("billboardmodel")) {
e.type = entity_type::BILLBOARD;
e.model = model_ids.at(m["draw"].at("billboardmodel"));
}
}
@ -80,7 +91,6 @@ void level::load_entities(json j) { @@ -80,7 +91,6 @@ void level::load_entities(json j) {
if (model && physics) {
auto phys = phys_meshes.at(e.physics);
auto model = models.at(e.model);
// draw_system->add(model, phys.pos, phys.orientation);
} else {
fmt::print("warn::level inivisible entity");
}
@ -119,7 +129,6 @@ level::level(const std::string &json_source) @@ -119,7 +129,6 @@ level::level(const std::string &json_source)
shader = &shaders[0];
shader->use();
// draw_system = simple_object_draw_system(&shaders[0]);
int mid = 0;
for (auto & [key, v] : l["staticmodels"].items()) {
@ -158,8 +167,24 @@ void level::draw(const glm::mat4 view, const glm::mat4 projection) { @@ -158,8 +167,24 @@ void level::draw(const glm::mat4 view, const glm::mat4 projection) {
order.insert({phys_meshes[e.physics].pos.z, e.id});
}
for (const auto &[k,v]: order) {
draw_objects(shader, {phys_meshes[entities[v].physics]}, models[entities[v].model], view, projection);
auto camera = player::get_camera();
auto camright = glm::vec3(view[0][0], view[1][0], view[2][0]);
auto camup = camera->up;
for (auto iter = order.rbegin(); iter != order.rend(); ++iter) {
auto k = iter->first;
auto v = iter->second;
glm::mat4 draw_view = view;
auto phys = phys_meshes[entities[v].physics];
if (entities[v].type == entity_type::BILLBOARD) {
// http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/
phys.orientation = glm::mat4(glm::mat3(glm::inverse(view)));
} else {
}
draw_objects(shader, {phys}, models[entities[v].model], draw_view, projection);
}
}
@ -188,7 +213,6 @@ void level::update() { @@ -188,7 +213,6 @@ void level::update() {
update_lights(shader, l);
entities.clear();
//draw_system->objects.clear();
load_entities(l);
}

5
src/level.h

@ -39,12 +39,11 @@ class level { @@ -39,12 +39,11 @@ class level {
Shader *shader;
std::string json_source_file;
std::vector<physics_model> phys_meshes;
std::vector<int> sounds;
std::vector<std::shared_ptr<Model>> models;
std::vector<Shader> shaders;
std::vector<int> lights;
std::optional<simple_object_draw_system> draw_system {};
std::vector<entity> entities;
std::vector<int> sounds;
std::vector<int> lights;
// level();

151
src/main.cpp

@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
#include "defaultobjects/cubemap.h"
#include "drawing.h"
#include "level.h"
#include "player.h"
@ -47,7 +48,6 @@ class SDLGLGLWindow { @@ -47,7 +48,6 @@ class SDLGLGLWindow {
unsigned int texture[2];
unsigned int cubemap;
glm::vec3 *translations = new glm::vec3[1000];
glm::vec3 cubePositions[10] = {
glm::vec3( 0.0f, 0.0f, 0.0f),
@ -64,15 +64,11 @@ class SDLGLGLWindow { @@ -64,15 +64,11 @@ class SDLGLGLWindow {
std::vector<glm::vec3> lightPositions = std::vector<glm::vec3>();
glm::mat4 projection;
glm::mat4 model = glm::mat3(1.0f);
glm::mat4 view = glm::mat4(1.0f);
private:
public:
level * running_level;
Shader *modelShader;
Shader *skyboxShader;
Shader *texShader;
@ -87,11 +83,7 @@ class SDLGLGLWindow { @@ -87,11 +83,7 @@ class SDLGLGLWindow {
unsigned int screenTexture;
SDL_Window *gWindow;
glm::vec3 camera_pos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 camera_direction = glm::vec3(0.f,0.f,0.f);
std::shared_ptr<player::camera> camera;
/* note:
*
* direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
@ -99,8 +91,6 @@ class SDLGLGLWindow { @@ -99,8 +91,6 @@ class SDLGLGLWindow {
* direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
*/
float cam_pitch = 0;
float cam_yaw = -90;
simple_object_draw_system *objects ;
@ -119,15 +109,7 @@ class SDLGLGLWindow { @@ -119,15 +109,7 @@ class SDLGLGLWindow {
}
void update_camera() {
if (cam_pitch > 89.0f)
cam_pitch = 89.0f;
if (cam_pitch < -89.0f)
cam_pitch = -89.0f;
camera_direction.x = cos(glm::radians(cam_yaw)) * cos(glm::radians(cam_pitch));
camera_direction.y = sin(glm::radians(cam_pitch));
camera_direction.z = sin(glm::radians(cam_yaw)) * cos(glm::radians(cam_pitch));
camera_front = glm::normalize(camera_direction);
camera->update();
}
int create_gl_window() {
@ -174,22 +156,21 @@ class SDLGLGLWindow { @@ -174,22 +156,21 @@ class SDLGLGLWindow {
fmt::print("loading level\n");
running_level = new level(("data/levels/init.json"));
//Initialize OpenGL
modelShader = new Shader("data/shaders/instanced.vert", "data/shaders/test.frag");
texShader = new Shader("data/shaders/screentexture.vert", "data/shaders/screentexture.frag");
skyboxShader = new Shader("data/shaders/sky.vert", "data/shaders/sky.frag");
glCheckError();
setup_msaa_framebuffers();
camera = player::get_camera();
initGL();
// init_level();
glEnable(GL_MULTISAMPLE);
glGetError();
// shader = &running_level->shaders[0];
return true;
@ -235,95 +216,11 @@ class SDLGLGLWindow { @@ -235,95 +216,11 @@ class SDLGLGLWindow {
std::cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
/* assumes level is loaded */
int init_level() {
/*
* Basic Shaders
*
*/
texShader = new Shader("data/shaders/screentexture.vert", "data/shaders/screentexture.frag");
skyboxShader = new Shader("data/shaders/sky.vert", "data/shaders/sky.frag");
bool success = true;
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);
/* MSAA FRAMEBUFFERS */
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// create a multisampled color attachment texture
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, textureColorBufferMultiSampledHDR, 0);
// create a (also multisampled) renderbuffer object for depth and stencil attachments
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, screen_width, screen_height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// configure second post-processing framebuffer
glGenFramebuffers(1, &intermediateFBO);
glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO);
// create a color attachment texture
glGenTextures(1, &screenTexture);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glEnable(GL_BLEND);
/********** CUBEMAPS ***************/
std::vector<std::string> faces {
fmt::format("{}/sky/right.png", SKYBOX_DIR),
fmt::format("{}/sky/left.png",SKYBOX_DIR),
fmt::format("{}/sky/up.png",SKYBOX_DIR),
fmt::format("{}/sky/down.png",SKYBOX_DIR),
fmt::format("{}/sky/front.png",SKYBOX_DIR),
fmt::format("{}/sky/back.png",SKYBOX_DIR),
};
Cubemap c (faces);
cubemap = c.id;
}
int initGL() {
bool success = true;
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);
float cubeVertices[] = {
// vertices normals textures tangent
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
@ -472,22 +369,10 @@ class SDLGLGLWindow { @@ -472,22 +369,10 @@ class SDLGLGLWindow {
glCheckError();
//Set vertex data
view = glm::lookAt(camera_pos, camera_pos + camera_front, camera_up);
glUniform3f(glGetUniformLocation(shader->program, "cameraPosition"), camera_pos.x, camera_pos.y, camera_pos.z);
glm::mat4 model = glm::mat4(1.0f);
camera->set_camera(shader);
unsigned int loc = shader->get_uniform("model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
glCheckError();
loc = shader->get_uniform("view");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(view));
glCheckError();
loc = shader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
glCheckError();
/** draw skybox cubemap */
@ -501,13 +386,14 @@ class SDLGLGLWindow { @@ -501,13 +386,14 @@ class SDLGLGLWindow {
glCheckError();
skyboxShader->setInt("skybox", 11);
loc = skyboxShader->get_uniform("view");
glm::mat4 skybox_view = glm::mat4(glm::mat3(view));
auto loc = skyboxShader->get_uniform("view");
glm::mat4 skybox_view = glm::mat4(glm::mat3(camera->view));
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(skybox_view));
glCheckError();
loc = skyboxShader->get_uniform("projection");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(camera->projection));
glCheckError();
glBindVertexArray(gVAO);
@ -520,7 +406,7 @@ class SDLGLGLWindow { @@ -520,7 +406,7 @@ class SDLGLGLWindow {
// draw the level objects
running_level->shader->setInt("skybox", 11);
running_level->draw(view, projection);
running_level->draw(camera->view, camera->projection);
// 2. now blit multisampled buffer(s) to normal colorbuffer of intermediate FBO. Image is stored in screenTexture
@ -566,6 +452,7 @@ class SDLGLGLWindow { @@ -566,6 +452,7 @@ class SDLGLGLWindow {
delete texShader;
delete skyboxShader;
delete running_level;
//Quit SDL subsystems
SDL_Quit();
@ -623,24 +510,22 @@ int main(int argc, char **argv) { @@ -623,24 +510,22 @@ int main(int argc, char **argv) {
quit = true;
break;
case SDL_SCANCODE_W:
cont.camera_pos += camera_speed * cont.camera_front;
cont.camera->pos += camera_speed * cont.camera->front;
break;
case SDL_SCANCODE_S:
cont.camera_pos -= camera_speed * cont.camera_front;
cont.camera->pos -= camera_speed * cont.camera->front;
break;
case SDL_SCANCODE_A:
cont.camera_pos -= camera_speed * glm::cross(cont.camera_front, cont.camera_up);
cont.camera->pos -= camera_speed * glm::cross(cont.camera->front, cont.camera->up);
break;
case SDL_SCANCODE_D:
cont.camera_pos += camera_speed * glm::cross(cont.camera_front, cont.camera_up);
cont.camera->pos += camera_speed * glm::cross(cont.camera->front, cont.camera->up);
break;
case SDL_SCANCODE_R:
glCheckError();
cont.running_level->update();
cont.initGL();
fmt::print("finished reloading level\n");
//cont.texShader->reload();
//cont.skyboxShader->reload();
break;
}
} if (e.type == SDL_MOUSEMOTION) {
@ -652,8 +537,8 @@ int main(int argc, char **argv) { @@ -652,8 +537,8 @@ int main(int argc, char **argv) {
}
if (mouse_mode) {
cont.cam_pitch -= e.motion.yrel * 0.1f;
cont.cam_yaw += e.motion.xrel * 0.1f;
cont.camera->pitch -= e.motion.yrel * 0.1f;
cont.camera->yaw += e.motion.xrel * 0.1f;
cont.update_camera();
}
}

2
src/mesh.h

@ -36,6 +36,7 @@ class Mesh { @@ -36,6 +36,7 @@ class Mesh {
std::vector<unsigned int> indices,
std::vector<struct texture> textures);
void draw(Shader *shader);
~Mesh() = default;
private:
unsigned int VAO, VBO, EBO;
void setupMesh();
@ -48,6 +49,7 @@ class Model { @@ -48,6 +49,7 @@ class Model {
load_model(path);
}
void draw(Shader *shader);
~Model() = default;
private:
Assimp::Importer importer;
std::vector<Mesh> meshes;

38
src/player.cpp

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
#include "player.h"
namespace player {
std::shared_ptr<camera> player_camera = std::shared_ptr<camera>(new camera {
glm::vec3(0.0f, 0.0f, 3.0f),
glm::vec3(0.0f, 0.0f, -1.0f),
glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3(0.f,0.f,0.f)
});
std::shared_ptr<camera> get_camera() {
return player_camera;
}
void camera::update() {
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
direction.y = sin(glm::radians(pitch));
direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
front = glm::normalize(direction);
view = glm::lookAt(pos, pos + front, up);
}
void camera::set_camera(Shader *shader) {
glUniform3f(glGetUniformLocation(shader->program, "cameraPosition"), pos.x, pos.y, pos.z);
}
};

51
src/player.h

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
#pragma once
#include <memory>
#include "shaders.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
namespace player {
enum class movement {
WALKING,
FLYING
};
class player {
movement move_mode = movement::WALKING;
};
class camera {
public:
glm::vec3 pos;
glm::vec3 front;
glm::vec3 up;
glm::vec3 direction;
float pitch = 0;
float yaw = -90;
glm::mat4 projection;
glm::mat4 model = glm::mat3(1.0f);
glm::mat4 view = glm::mat4(1.0f);
camera(glm::vec3 pos, glm::vec3 front, glm::vec3 up, glm::vec3 direction)
: pos(pos), front(front), up(up), direction(direction) {
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
};
void update();
void set_camera(Shader *shader);
};
std::shared_ptr<camera> get_camera();
}

2
src/shaders.cpp

@ -237,8 +237,6 @@ GLint Shader::get_uniform(std::string unif) @@ -237,8 +237,6 @@ GLint Shader::get_uniform(std::string unif)
Shader::~Shader() {
glDeleteShader(shader_vert);
glDeleteShader(shader_frag);
glDeleteProgram(program);
}

Loading…
Cancel
Save