improvements to renderer
This commit is contained in:
parent
c85984fc7f
commit
e2b16e0591
BIN
assets/scene.blend (Stored with Git LFS)
BIN
assets/scene.blend (Stored with Git LFS)
Binary file not shown.
BIN
assets/scene.glb (Stored with Git LFS)
BIN
assets/scene.glb (Stored with Git LFS)
Binary file not shown.
|
@ -5,6 +5,7 @@ layout (triangles) in;
|
|||
layout (triangle_strip, max_vertices=18) out;
|
||||
|
||||
uniform mat4 shadow_mats[6];
|
||||
uniform int light_pass;
|
||||
|
||||
in flat int should_ignore[];
|
||||
out vec3 frag_pos;
|
||||
|
@ -13,9 +14,11 @@ void main()
|
|||
{
|
||||
if(should_ignore[0] != 0) return;
|
||||
|
||||
int pass_offset = light_pass * 6;
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
gl_Layer = i;
|
||||
gl_Layer = i + pass_offset;
|
||||
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
|
||||
#version 460 core
|
||||
|
||||
layout (location = 2) in vec3 aPos;
|
||||
layout (location = 4) in vec4 aColour;
|
||||
layout (location = 5) in vec3 aMaterial;
|
||||
layout (location = 6) in float aTransformIndex;
|
||||
#define MAX_LIGHTS 6
|
||||
|
||||
layout (location = 1) in vec3 aPos;
|
||||
layout (location = 2) in vec4 aColour;
|
||||
layout (location = 6) in int aTransformIndex;
|
||||
|
||||
layout (binding = 3) readonly buffer TransformBuffer
|
||||
{
|
||||
mat4 transforms[];
|
||||
};
|
||||
|
||||
uniform mat4 camera;
|
||||
|
||||
out flat int should_ignore;
|
||||
|
||||
uniform vec3 light_pos;
|
||||
uniform int light_pass;
|
||||
|
||||
mat4 load_model_mat(int index)
|
||||
{
|
||||
return index < 0 ? mat4(1.f) : transforms[index];
|
||||
|
@ -23,10 +25,9 @@ mat4 load_model_mat(int index)
|
|||
void main()
|
||||
{
|
||||
vec4 pos = vec4(aPos, 1.f);
|
||||
mat4 model = load_model_mat(int(aTransformIndex));
|
||||
mat4 mv = camera * model;
|
||||
mat4 model = load_model_mat(aTransformIndex);
|
||||
|
||||
gl_Position = mv * pos;
|
||||
should_ignore = int(aMaterial[2] > 0.f || aColour.a < 1.f);
|
||||
gl_Position = model * pos - vec4(light_pos, 0.f);
|
||||
should_ignore = int(aColour.a < 1.f);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
const float PI = 3.141592f;
|
||||
|
||||
in VS_OUT {
|
||||
vec3 normal;
|
||||
vec4 colour;
|
||||
mat3 tbn;
|
||||
vec3 pos;
|
||||
vec2 tex_pos;
|
||||
vec3 material;
|
||||
float ambient;
|
||||
flat vec4 colour;
|
||||
flat vec3 material;
|
||||
} vin;
|
||||
|
||||
struct Light
|
||||
|
@ -19,17 +18,14 @@ struct Light
|
|||
vec4 colour;
|
||||
};
|
||||
|
||||
layout(std140, binding = 1) readonly buffer LightBuffer
|
||||
layout(std140, binding = 2) readonly buffer LightBuffer
|
||||
{
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) readonly buffer ShadowMapBuffer
|
||||
{
|
||||
samplerCube shadow_maps[];
|
||||
};
|
||||
in flat sampler2D frag_tex_diffuse;
|
||||
in flat sampler2D frag_tex_normal;
|
||||
|
||||
in flat sampler2D frag_tex;
|
||||
out vec4 frag_colour;
|
||||
|
||||
uniform vec3 brightness;
|
||||
|
@ -38,6 +34,8 @@ uniform float far_plane;
|
|||
uniform bool shadows_enabled;
|
||||
uniform int lights_count;
|
||||
|
||||
uniform samplerCubeArrayShadow shadow_maps;
|
||||
|
||||
float Map(float v, float i_min, float i_max, float o_min, float o_max)
|
||||
{
|
||||
return o_min + (o_max - o_min) * (v - i_min) / (i_max - i_min);
|
||||
|
@ -109,9 +107,10 @@ vec3 sRGB_To_LinRGB(vec3 c)
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo = texture2D(frag_tex, vin.tex_pos);
|
||||
vec4 albedo = texture2D(frag_tex_diffuse, vin.tex_pos);
|
||||
if(albedo.a == 0.f) discard;
|
||||
|
||||
vec3 tangent = texture2D(frag_tex_normal, vin.tex_pos).rgb * 2.f - 1.f;
|
||||
vec3 albedo_lin = sRGB_To_LinRGB(albedo.rgb) * vin.colour.rgb;
|
||||
albedo *= vin.colour;
|
||||
|
||||
|
@ -119,11 +118,11 @@ void main()
|
|||
float metalness = vin.material[1];
|
||||
float luminance = min(vin.material[2], 1.f);
|
||||
|
||||
vec3 N = normalize(vin.normal);
|
||||
vec3 N = normalize(vin.tbn * tangent);
|
||||
vec3 V = normalize(camera_pos - vin.pos.xyz);
|
||||
|
||||
vec3 F0 = mix(vec3(0.04f), albedo_lin, metalness);
|
||||
vec3 ambient = vec3(vin.ambient) * albedo_lin * brightness;
|
||||
vec3 ambient = vec3(Map(dot(N, vec3(0.f, 0.f, 1.f)), -1.f, 1.f, 0.2f, 0.25f)) * albedo_lin * brightness;
|
||||
vec3 Lo = vec3(0.f);
|
||||
|
||||
for(int i = 0; i < lights_count; i++)
|
||||
|
@ -135,8 +134,12 @@ void main()
|
|||
|
||||
if(shadows_enabled)
|
||||
{
|
||||
float max_d = texture(shadow_maps[i], -L).r * far_plane;
|
||||
light_m = Ramp(d - max_d, 0.f, 2.5e-2f, 1.f, 0.f);
|
||||
if(dot(vin.tbn[2], L) < 0.f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
light_m = texture(shadow_maps, vec4(-L, i), d / far_plane);
|
||||
|
||||
if(light_m <= 0.f)
|
||||
{
|
||||
|
|
|
@ -2,32 +2,35 @@
|
|||
#version 460 core
|
||||
#extension GL_ARB_bindless_texture : require
|
||||
|
||||
layout (location = 0) in sampler2D aTex;
|
||||
layout (location = 1) in vec2 aTexPos;
|
||||
layout (location = 2) in vec3 aPos;
|
||||
layout (location = 3) in vec3 aNormal;
|
||||
layout (location = 4) in vec4 aColour;
|
||||
layout (location = 5) in vec3 aMaterial;
|
||||
layout (location = 6) in float aTransformIndex;
|
||||
layout (location = 0) in vec2 aTexPos;
|
||||
layout (location = 1) in vec3 aPos;
|
||||
layout (location = 2) in vec4 aColour;
|
||||
layout (location = 3) in vec3 aTangent;
|
||||
layout (location = 4) in vec3 aBitangent;
|
||||
layout (location = 5) in vec3 aNormal;
|
||||
layout (location = 6) in int aTransformIndex;
|
||||
layout (location = 7) in sampler2D aTexDiffuse;
|
||||
layout (location = 8) in sampler2D aTexNormal;
|
||||
layout (location = 9) in vec3 aMaterial;
|
||||
|
||||
uniform mat4 camera;
|
||||
uniform mat4 projection;
|
||||
|
||||
layout (binding = 3) readonly buffer TransformBuffer1
|
||||
layout (std430, binding = 3) readonly buffer TransformBuffer
|
||||
{
|
||||
mat4 transforms[];
|
||||
};
|
||||
|
||||
out VS_OUT {
|
||||
vec3 normal;
|
||||
vec4 colour;
|
||||
mat3 tbn;
|
||||
vec3 pos;
|
||||
vec2 tex_pos;
|
||||
vec3 material;
|
||||
float ambient;
|
||||
flat vec4 colour;
|
||||
flat vec3 material;
|
||||
} vout;
|
||||
|
||||
out flat sampler2D frag_tex;
|
||||
out flat sampler2D frag_tex_diffuse;
|
||||
out flat sampler2D frag_tex_normal;
|
||||
|
||||
mat4 load_model_mat(int index)
|
||||
{
|
||||
|
@ -42,17 +45,17 @@ float Map(float v, float i_min, float i_max, float o_min, float o_max)
|
|||
void main()
|
||||
{
|
||||
vec4 pos = vec4(aPos, 1.f);
|
||||
mat4 model = load_model_mat(int(aTransformIndex));
|
||||
mat4 model = load_model_mat(aTransformIndex);
|
||||
mat4 mv = camera * model;
|
||||
mat4 mvp = projection * mv;
|
||||
|
||||
vout.normal = normalize(mat3(model) * aNormal);
|
||||
vout.ambient = Map(dot(vout.normal, vec3(0.f, 0.f, 1.f)), -1.f, 1.f, 0.2f, 0.25f);
|
||||
vout.tbn = mat3(model) * mat3(aTangent, aBitangent, aNormal);
|
||||
vout.pos = (model * pos).xyz;
|
||||
vout.colour = aColour;
|
||||
vout.tex_pos = aTexPos;
|
||||
vout.material = aMaterial;
|
||||
frag_tex = aTex;
|
||||
vout.colour = aColour;
|
||||
vout.material = aMaterial.xyz;
|
||||
frag_tex_diffuse = aTexDiffuse;
|
||||
frag_tex_normal = aTexNormal;
|
||||
|
||||
gl_Position = mvp * pos;
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 270 KiB |
Binary file not shown.
After Width: | Height: | Size: 560 KiB |
|
@ -2,6 +2,7 @@
|
|||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <assimp/Importer.hpp>
|
||||
|
||||
#include "../shader.hpp"
|
||||
|
@ -20,38 +21,48 @@ void Arrays::vertex_attrib_pointers()
|
|||
{
|
||||
Vertex v;
|
||||
|
||||
glVertexAttribLPointer(0, 1, GL_UNSIGNED_INT64_ARB, sizeof(v), ptr_diff(&v.texid, &v));
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(v), ptr_diff(&v.texpos, &v));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(v), ptr_diff(&v.texpos, &v));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.pos, &v));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.pos, &v));
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, false, sizeof(v), ptr_diff(&v.colour, &v));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.normal, &v));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, true, sizeof(v), ptr_diff(&v.tbn[0], &v));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, false, sizeof(v), ptr_diff(&v.colour, &v));
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, true, sizeof(v), ptr_diff(&v.tbn[1], &v));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glVertexAttribPointer(5, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.material, &v));
|
||||
glVertexAttribPointer(5, 3, GL_FLOAT, true, sizeof(v), ptr_diff(&v.tbn[2], &v));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
glVertexAttribPointer(6, 1, GL_FLOAT, false, sizeof(v), ptr_diff(&v.transform_id, &v));
|
||||
glVertexAttribIPointer(6, 1, GL_INT, sizeof(v), ptr_diff(&v.transform_id, &v));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
glVertexAttribIPointer(7, 1, GL_UNSIGNED_INT, sizeof(v), ptr_diff(&v.tex_diffuse, &v));
|
||||
glEnableVertexAttribArray(7);
|
||||
|
||||
glVertexAttribIPointer(8, 1, GL_UNSIGNED_INT, sizeof(v), ptr_diff(&v.tex_normal, &v));
|
||||
glEnableVertexAttribArray(8);
|
||||
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.material, &v));
|
||||
glEnableVertexAttribArray(9);
|
||||
}
|
||||
|
||||
std::ostream& Arrays::operator<<(std::ostream& os, const Vertex& v)
|
||||
{
|
||||
os << "Vertex{";
|
||||
os << "texid=" << v.texid << ", ";
|
||||
os << "texpos=" << v.texpos << ", ";
|
||||
os << "pos=" << v.pos << ", ";
|
||||
os << "normal=" << v.normal << ", ";
|
||||
os << "colour=" << v.colour << ", ";
|
||||
os << "material=" << v.material << ", ";
|
||||
os << "transform_id=" << v.transform_id;
|
||||
os << "tbn=" << v.tbn << ", ";
|
||||
os << "transform_id=" << v.transform_id << ", ";
|
||||
os << "tex_diffuse=" << v.tex_diffuse << ", ";
|
||||
os << "tex_normal=" << v.tex_normal << ", ";
|
||||
os << "material=" << v.material;
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "texture.hpp"
|
||||
|
||||
#include <glm/matrix.hpp>
|
||||
#include <ostream>
|
||||
|
||||
|
@ -9,19 +11,20 @@ namespace Sim::Graphics::Data::Arrays
|
|||
|
||||
struct Vertex
|
||||
{
|
||||
unsigned long texid = 0;
|
||||
glm::vec2 texpos = {0, 0};
|
||||
glm::vec3 pos = {0, 0, 0};
|
||||
glm::vec3 normal = {0, 0, 0};
|
||||
glm::vec4 colour = {1, 1, 1, 1};
|
||||
glm::vec3 material = {0, 0, 0};
|
||||
float transform_id = -1;
|
||||
glm::mat3 tbn = glm::mat3(1);
|
||||
int transform_id = -1;
|
||||
unsigned int tex_diffuse = Texture::handle_white;
|
||||
unsigned int tex_normal = Texture::handle_normal;
|
||||
glm::vec3 material = {0.5, 0, 0};
|
||||
|
||||
constexpr bool operator==(const Vertex&) const = default;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Vertex& v);
|
||||
|
||||
} __attribute__((packed));
|
||||
};
|
||||
|
||||
void vertex_attrib_pointers();
|
||||
|
||||
|
|
|
@ -11,13 +11,14 @@
|
|||
|
||||
#include "mesh.hpp"
|
||||
#include "arrays.hpp"
|
||||
#include "material.hpp"
|
||||
#include "font.hpp"
|
||||
|
||||
using namespace Sim::Graphics::Data;
|
||||
|
||||
struct Character
|
||||
{
|
||||
unsigned long handle;
|
||||
uint32_t handle;
|
||||
float advance;
|
||||
glm::vec2 size;
|
||||
glm::vec2 bearing;
|
||||
|
@ -94,7 +95,6 @@ void Font::init()
|
|||
|
||||
c.handle = glGetTextureHandleARB(texids[i]);
|
||||
glMakeTextureHandleResidentARB(c.handle);
|
||||
|
||||
chars[i] = c;
|
||||
}
|
||||
|
||||
|
@ -144,10 +144,10 @@ Mesh& Mesh::load_text(const char* text, double size)
|
|||
float ex = sx + ch.size.x * size;
|
||||
float ey = sy + ch.size.y * size;
|
||||
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 0}, .pos={sx, sy, 0}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 1}, .pos={sx, ey, 0}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 0}, .pos={ex, sy, 0}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 1}, .pos={ex, ey, 0}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texpos={0, 0}, .pos={sx, sy, 0}, .tex_diffuse=ch.handle, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texpos={0, 1}, .pos={sx, ey, 0}, .tex_diffuse=ch.handle, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texpos={1, 0}, .pos={ex, sy, 0}, .tex_diffuse=ch.handle, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texpos={1, 1}, .pos={ex, ey, 0}, .tex_diffuse=ch.handle, .material={0, 0, 1}});
|
||||
indices.insert(indices.end(), &index[0], &index[6]);
|
||||
|
||||
at += 4;
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "gllight.hpp"
|
||||
#include "../shader.hpp"
|
||||
#include "../window.hpp"
|
||||
#include "texture.hpp"
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
|
||||
using namespace Sim::Graphics::Data;
|
||||
|
||||
static glm::mat4 shadow_mats[6];
|
||||
|
||||
GLLight::GLLight(Light light) : light(light), size(1024)
|
||||
{
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, id, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
handle = glGetTextureHandleARB(id);
|
||||
glMakeTextureHandleResidentARB(handle);
|
||||
}
|
||||
|
||||
GLLight::GLLight(GLLight&& o) : light(o.light), size(o.size)
|
||||
{
|
||||
id = o.id;
|
||||
handle = o.handle;
|
||||
fbo = o.fbo;
|
||||
|
||||
o.id = 0;
|
||||
o.handle = 0;
|
||||
o.fbo = 0;
|
||||
}
|
||||
|
||||
GLLight::~GLLight()
|
||||
{
|
||||
if(fbo)
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
if(id)
|
||||
glDeleteTextures(1, &id);
|
||||
}
|
||||
|
||||
void GLLight::render()
|
||||
{
|
||||
glm::mat4 camera_mat = glm::translate(glm::mat4(1), -light.pos);
|
||||
glUniformMatrix4fv(Shader::LIGHT["camera"], 1, false, &camera_mat[0][0]);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, size, size);
|
||||
Window::render_scene();
|
||||
}
|
||||
|
||||
void GLLight::render_player()
|
||||
{
|
||||
glm::mat4 camera_mat = glm::translate(glm::mat4(1), -light.pos);
|
||||
glUniformMatrix4fv(Shader::LIGHT["camera"], 1, false, &camera_mat[0][0]);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, size, size);
|
||||
Window::render_player();
|
||||
}
|
||||
|
||||
void GLLight::init()
|
||||
{
|
||||
glm::mat4 shadow_proj = glm::perspective<float>(M_PI * 0.5f, 1.0f, 0.01f, 100.f);
|
||||
|
||||
shadow_mats[0] = shadow_proj * glm::lookAt(glm::vec3(0), { 1, 0, 0}, {0,-1, 0});
|
||||
shadow_mats[1] = shadow_proj * glm::lookAt(glm::vec3(0), {-1, 0, 0}, {0,-1, 0});
|
||||
shadow_mats[2] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 1, 0}, {0, 0, 1});
|
||||
shadow_mats[3] = shadow_proj * glm::lookAt(glm::vec3(0), { 0,-1, 0}, {0, 0,-1});
|
||||
shadow_mats[4] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 0, 1}, {0,-1, 0});
|
||||
shadow_mats[5] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 0,-1}, {0,-1, 0});
|
||||
|
||||
glUniformMatrix4fv(Shader::LIGHT["shadow_mats"], 6, false, &shadow_mats[0][0][0]);
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "light.hpp"
|
||||
|
||||
namespace Sim::Graphics::Data
|
||||
{
|
||||
|
||||
struct GLLight
|
||||
{
|
||||
const int size;
|
||||
|
||||
unsigned int id, fbo;
|
||||
unsigned long handle;
|
||||
Light light;
|
||||
|
||||
GLLight(Light light);
|
||||
GLLight(GLLight&& o);
|
||||
GLLight(const GLLight& o) = delete;
|
||||
~GLLight();
|
||||
|
||||
static void init();
|
||||
|
||||
void render();
|
||||
void render_player();
|
||||
};
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "gllights.hpp"
|
||||
#include "../shader.hpp"
|
||||
#include "../window.hpp"
|
||||
#include "texture.hpp"
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
|
||||
using namespace Sim::Graphics::Data;
|
||||
|
||||
static glm::mat4 shadow_mats[6];
|
||||
|
||||
GLLights::GLLights(std::vector<Light>&& _lights) : lights(_lights), size(1024)
|
||||
{
|
||||
glGenTextures(1, &texid);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texid);
|
||||
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT, size, size, 6 * lights.size(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texid, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
glGenBuffers(1, &ssbo);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Light) * lights.size(), lights.data(), GL_STATIC_COPY);
|
||||
}
|
||||
|
||||
GLLights::GLLights(GLLights&& o) : lights(o.lights), size(o.size)
|
||||
{
|
||||
texid = o.texid;
|
||||
fbo = o.fbo;
|
||||
|
||||
o.texid = 0;
|
||||
o.fbo = 0;
|
||||
}
|
||||
|
||||
GLLights::~GLLights()
|
||||
{
|
||||
if(fbo)
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
if(texid)
|
||||
glDeleteTextures(1, &texid);
|
||||
}
|
||||
|
||||
void GLLights::render()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, size, size);
|
||||
|
||||
Window::bind_scene_ssbo();
|
||||
|
||||
for(int i = 0; i < lights.size(); i++)
|
||||
{
|
||||
glUniform3fv(Shader::LIGHT["light_pos"], 1, &lights[i].pos[0]);
|
||||
glUniform1i(Shader::LIGHT["light_pass"], i);
|
||||
Window::render_scene();
|
||||
}
|
||||
}
|
||||
|
||||
void GLLights::init()
|
||||
{
|
||||
glm::mat4 shadow_proj = glm::perspective<float>(M_PI * 0.5f, 1.0f, 0.01f, 100.f);
|
||||
|
||||
shadow_mats[0] = shadow_proj * glm::lookAt(glm::vec3(0), { 1, 0, 0}, {0,-1, 0});
|
||||
shadow_mats[1] = shadow_proj * glm::lookAt(glm::vec3(0), {-1, 0, 0}, {0,-1, 0});
|
||||
shadow_mats[2] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 1, 0}, {0, 0, 1});
|
||||
shadow_mats[3] = shadow_proj * glm::lookAt(glm::vec3(0), { 0,-1, 0}, {0, 0,-1});
|
||||
shadow_mats[4] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 0, 1}, {0,-1, 0});
|
||||
shadow_mats[5] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 0,-1}, {0,-1, 0});
|
||||
|
||||
glUniformMatrix4fv(Shader::LIGHT["shadow_mats"], 6, false, &shadow_mats[0][0][0]);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "light.hpp"
|
||||
|
||||
namespace Sim::Graphics::Data
|
||||
{
|
||||
|
||||
struct GLLights
|
||||
{
|
||||
const int size;
|
||||
|
||||
unsigned int texid, fbo, ssbo;
|
||||
|
||||
std::vector<Light> lights;
|
||||
|
||||
GLLights(std::vector<Light>&& lights);
|
||||
GLLights(GLLights&& o);
|
||||
GLLights(const GLLights& o) = delete;
|
||||
~GLLights();
|
||||
|
||||
static void init();
|
||||
|
||||
void render();
|
||||
};
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
namespace Sim::Graphics::Data
|
||||
{
|
||||
|
||||
struct Material
|
||||
{
|
||||
uint32_t diffuse = Texture::handle_white;
|
||||
uint32_t normal = Texture::handle_normal;
|
||||
glm::vec4 colour = {1, 1, 1, 1};
|
||||
float roughness = 0.5;
|
||||
float metalness = 0;
|
||||
float luminance = 0;
|
||||
// float padding = 0;
|
||||
|
||||
/* static void init();
|
||||
static int create(Material m);
|
||||
static void destroy(int id);
|
||||
static Material get(int id);
|
||||
static void sync();*/
|
||||
};
|
||||
|
||||
};
|
||||
|
|
@ -16,11 +16,21 @@ Mesh::Mesh()
|
|||
|
||||
}
|
||||
|
||||
Mesh& Mesh::set_texture_id(unsigned int id)
|
||||
Mesh& Mesh::set_diffuse_id(unsigned int id)
|
||||
{
|
||||
for(unsigned int i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
vertices[i].texid = id;
|
||||
vertices[i].tex_diffuse = id;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mesh& Mesh::set_normal_id(unsigned int id)
|
||||
{
|
||||
for(unsigned int i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
vertices[i].tex_normal = id;
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -50,12 +60,12 @@ Mesh& Mesh::add(const Mesh& o, glm::mat4 mat, bool bake)
|
|||
for(int i = 0; i < o.vertices.size(); i++)
|
||||
{
|
||||
Arrays::Vertex v = o.vertices[i];
|
||||
int t_id = (int)v.transform_id;
|
||||
int t_id = v.transform_id;
|
||||
glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1);
|
||||
t_mat = mat * t_mat;
|
||||
|
||||
v.pos = t_mat * glm::vec4(v.pos, 1);
|
||||
v.normal = glm::normalize(glm::mat3(t_mat) * v.normal);
|
||||
v.tbn = glm::mat3(t_mat) * v.tbn;
|
||||
v.transform_id = -1;
|
||||
vertices.push_back(v);
|
||||
}
|
||||
|
@ -69,8 +79,8 @@ Mesh& Mesh::add(const Mesh& o, glm::mat4 mat, bool bake)
|
|||
}
|
||||
|
||||
glm::mat3 mat3(mat);
|
||||
float t_off = transforms.size();
|
||||
float t_new = -1;
|
||||
int t_off = transforms.size();
|
||||
int t_new = -1;
|
||||
|
||||
if(mat != glm::mat4(1))
|
||||
{
|
||||
|
@ -118,13 +128,13 @@ Mesh& Mesh::bake_transforms()
|
|||
{
|
||||
for(unsigned int i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
int id = (int)vertices[i].transform_id;
|
||||
int id = vertices[i].transform_id;
|
||||
|
||||
if(id >= 0)
|
||||
{
|
||||
glm::mat4 transform = transforms[id];
|
||||
vertices[i].pos = glm::vec3(transform * glm::vec4(vertices[i].pos, 1));
|
||||
vertices[i].normal = glm::normalize(glm::mat3(transform) * vertices[i].normal);
|
||||
vertices[i].tbn = glm::mat3(transform) * vertices[i].tbn;
|
||||
vertices[i].transform_id = -1;
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +235,7 @@ bool Mesh::check_intersect(vec3 pos, vec3 path) const
|
|||
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
int t_id = (int)verts[j].transform_id;
|
||||
int t_id = verts[j].transform_id;
|
||||
glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1);
|
||||
|
||||
v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 1));
|
||||
|
@ -303,7 +313,7 @@ vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const
|
|||
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
int t_id = (int)verts[j].transform_id;
|
||||
int t_id = verts[j].transform_id;
|
||||
glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1);
|
||||
|
||||
v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 1));
|
||||
|
|
|
@ -26,7 +26,8 @@ struct Mesh
|
|||
|
||||
Mesh& bake_transforms();
|
||||
Mesh& set_blank_transform();
|
||||
Mesh& set_texture_id(unsigned int id);
|
||||
Mesh& set_normal_id(unsigned int id);
|
||||
Mesh& set_diffuse_id(unsigned int id);
|
||||
Mesh& load_text(const char* text, double size);
|
||||
Mesh& load_text(const char* text, double size, glm::vec2 align);
|
||||
Mesh& add(const Mesh& o, glm::mat4 mat = glm::mat4(1), bool bake = false);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <unordered_map>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "mesh.hpp"
|
||||
|
@ -24,106 +25,17 @@ struct ProcState
|
|||
std::vector<Arrays::Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<glm::mat4> transforms;
|
||||
std::unordered_map<const aiTexture*, unsigned int> handles;
|
||||
const std::vector<Material>& materials;
|
||||
};
|
||||
|
||||
static unsigned int proc_texture(const ProcState& state, aiMaterial* mat, const aiScene* scene, aiTextureType type, int index)
|
||||
{
|
||||
aiString str;
|
||||
mat->GetTexture(type, index, &str);
|
||||
|
||||
if(str.C_Str()[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const aiTexture* tex = scene->GetEmbeddedTexture(str.C_Str());
|
||||
|
||||
if(tex != nullptr)
|
||||
{
|
||||
unsigned int handle = state.handles.find(tex)->second;
|
||||
std::cout << "Using preloaded texture: " << tex->mFilename.C_Str() << "\n";
|
||||
return handle;
|
||||
}
|
||||
|
||||
std::string filename(str.C_Str());
|
||||
std::replace(filename.begin(), filename.end(), '\\', '/');
|
||||
|
||||
return Texture::load(state.base + "/" + filename);
|
||||
}
|
||||
|
||||
static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
aiString name;
|
||||
|
||||
material->Get(AI_MATKEY_NAME, name);
|
||||
/*
|
||||
std::cout << "Material " << name.C_Str() << " has " << material->mNumProperties << " properties\n";
|
||||
|
||||
for(int i = 0; i < material->mNumProperties; i++)
|
||||
{
|
||||
aiMaterialProperty* prop = material->mProperties[i];
|
||||
|
||||
std::cout << " " << prop->mKey.C_Str() << ": type=" << prop->mType << " index=" << prop->mIndex << " length=" << prop->mDataLength;
|
||||
|
||||
if(prop->mType == 1)
|
||||
{
|
||||
float* v = (float*)prop->mData;
|
||||
|
||||
std::cout << " value=";
|
||||
|
||||
switch(prop->mDataLength)
|
||||
{
|
||||
case 4:
|
||||
std::cout << v[0];
|
||||
break;
|
||||
case 8:
|
||||
std::cout << "{" << v[0] << ", " << v[1] << "}";
|
||||
break;
|
||||
case 12:
|
||||
std::cout << "{" << v[0] << ", " << v[1] << ", " << v[2] << "}";
|
||||
break;
|
||||
case 16:
|
||||
std::cout << "{" << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "}";
|
||||
break;
|
||||
default:
|
||||
std::cout << "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}*/
|
||||
|
||||
glm::vec3 matv(0);
|
||||
aiColor4D ai_cb;
|
||||
aiColor4D ai_em;
|
||||
|
||||
material->Get(AI_MATKEY_ROUGHNESS_FACTOR, matv[0]);
|
||||
material->Get(AI_MATKEY_METALLIC_FACTOR, matv[1]);
|
||||
material->Get(AI_MATKEY_EMISSIVE_INTENSITY, matv[2]);
|
||||
material->Get(AI_MATKEY_COLOR_EMISSIVE, ai_em);
|
||||
material->Get(AI_MATKEY_BASE_COLOR, ai_cb);
|
||||
|
||||
glm::vec4 cb = {ai_cb[0], ai_cb[1], ai_cb[2], ai_cb[3]};
|
||||
glm::vec4 em = {ai_em[0], ai_em[1], ai_em[2], ai_em[3]};
|
||||
|
||||
if(em.x > 0 || em.y > 0 || em.z > 0)
|
||||
{
|
||||
cb = em;
|
||||
}
|
||||
|
||||
unsigned int handle = proc_texture(state, material, scene, aiTextureType_BASE_COLOR, 0);
|
||||
Material mat = state.materials[mesh->mMaterialIndex];
|
||||
unsigned int offset = state.offset;
|
||||
|
||||
if(!handle)
|
||||
if(!mesh->HasNormals())
|
||||
{
|
||||
handle = proc_texture(state, material, scene, aiTextureType_DIFFUSE, 0);
|
||||
}
|
||||
|
||||
if(!handle)
|
||||
{
|
||||
handle = Texture::handle_white;
|
||||
throw std::runtime_error("Mesh has no normals");
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
|
@ -131,25 +43,12 @@ static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene)
|
|||
Arrays::Vertex vertex;
|
||||
|
||||
auto [x, y, z] = mesh->mVertices[i];
|
||||
vertex.pos = glm::vec3(x, y, z);
|
||||
vertex.transform_id = state.transforms.size();
|
||||
vertex.material = matv;
|
||||
vertex.texid = handle;
|
||||
vertex.colour = cb;
|
||||
|
||||
if(mesh->HasNormals())
|
||||
{
|
||||
auto [x, y, z] = mesh->mNormals[i];
|
||||
vertex.normal = glm::vec3(x, y, z);
|
||||
}
|
||||
|
||||
/*if(mesh->HasTangentsAndBitangents())
|
||||
{
|
||||
auto [x1, y1, z1] = mesh->mTangents[i];
|
||||
auto [x2, y2, z2] = mesh->mBitangents[i];
|
||||
vertex.tangent = {x1, y1, z1};
|
||||
vertex.bitangent = {x2, y2, z2};
|
||||
}*/
|
||||
vertex.pos = glm::vec3(x, y, z);
|
||||
vertex.colour = mat.colour;
|
||||
vertex.tex_diffuse = mat.diffuse;
|
||||
vertex.tex_normal = mat.normal;
|
||||
vertex.material = {mat.roughness, mat.metalness, mat.luminance};
|
||||
|
||||
if(mesh->mTextureCoords[0])
|
||||
{
|
||||
|
@ -157,6 +56,30 @@ static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene)
|
|||
vertex.texpos = {x, y};
|
||||
}
|
||||
|
||||
if(mesh->HasTangentsAndBitangents())
|
||||
{
|
||||
auto [x1, y1, z1] = mesh->mTangents[i];
|
||||
auto [x2, y2, z2] = mesh->mBitangents[i];
|
||||
auto [x3, y3, z3] = mesh->mNormals[i];
|
||||
|
||||
vertex.tbn = {
|
||||
{x1, y1, z1},
|
||||
{x2, y2, z2},
|
||||
{x3, y3, z3},
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
auto [x, y, z] = mesh->mNormals[i];
|
||||
|
||||
glm::vec3 normal = {x, y, z};
|
||||
glm::vec3 tangent = glm::normalize(glm::cross(normal, {-y, z, x}));
|
||||
glm::vec3 bitangent = glm::normalize(glm::cross(normal, tangent));
|
||||
|
||||
vertex.tbn = {tangent, bitangent, normal};
|
||||
}
|
||||
|
||||
state.vertices.push_back(vertex);
|
||||
}
|
||||
|
||||
|
@ -223,7 +146,7 @@ static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiSce
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned int proc_embedded_texture(aiTexture* tex)
|
||||
static uint64_t proc_embedded_texture(aiTexture* tex)
|
||||
{
|
||||
std::cout << "Loading embedded data: " << tex->mFilename.C_Str() << "\n";
|
||||
|
||||
|
@ -263,17 +186,40 @@ glm::mat4 Model::load_matrix(const char* name) const
|
|||
return get_transforms(scene->mRootNode->FindNode(name));
|
||||
}
|
||||
|
||||
static uint32_t proc_texture(
|
||||
const std::string& path_base,
|
||||
aiMaterial* mat,
|
||||
const aiScene* scene,
|
||||
aiTextureType type,
|
||||
int index,
|
||||
uint64_t handle_fail=0)
|
||||
{
|
||||
aiString str;
|
||||
mat->GetTexture(type, index, &str);
|
||||
|
||||
if(str.C_Str()[0] == '\0')
|
||||
{
|
||||
return handle_fail;
|
||||
}
|
||||
|
||||
std::string filename(str.C_Str());
|
||||
std::replace(filename.begin(), filename.end(), '\\', '/');
|
||||
|
||||
return Texture::load(path_base + "/" + filename);
|
||||
}
|
||||
|
||||
Model::Model(std::string base, std::string filename) : base(base)
|
||||
{
|
||||
std::string path = base + "/" + filename;
|
||||
scene = importer.ReadFile(path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||
scene = importer.ReadFile(path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace);
|
||||
|
||||
textures.reserve(scene->mNumTextures);
|
||||
materials.reserve(scene->mNumMaterials);
|
||||
|
||||
for(int i = 0; i < scene->mNumTextures; i++)
|
||||
{
|
||||
aiTexture* tex = scene->mTextures[i];
|
||||
unsigned int handle = proc_embedded_texture(tex);
|
||||
uint64_t handle = proc_embedded_texture(tex);
|
||||
textures.push_back(handle);
|
||||
}
|
||||
|
||||
|
@ -308,12 +254,54 @@ Model::Model(std::string base, std::string filename) : base(base)
|
|||
|
||||
cameras.push_back({.pos=glm::vec3(pos), .look=look, .up=up, .fov=camera->mHorizontalFOV});
|
||||
}
|
||||
|
||||
for(int i = 0; i < scene->mNumMaterials; i++)
|
||||
{
|
||||
aiMaterial* ai_mat = scene->mMaterials[i];
|
||||
|
||||
glm::vec3 matv(0);
|
||||
aiColor4D ai_cb;
|
||||
aiColor4D ai_em;
|
||||
|
||||
ai_mat->Get(AI_MATKEY_COLOR_EMISSIVE, ai_em);
|
||||
ai_mat->Get(AI_MATKEY_BASE_COLOR, ai_cb);
|
||||
|
||||
glm::vec4 cb = {ai_cb[0], ai_cb[1], ai_cb[2], ai_cb[3]};
|
||||
glm::vec4 em = {ai_em[0], ai_em[1], ai_em[2], ai_em[3]};
|
||||
|
||||
if(em.x > 0 || em.y > 0 || em.z > 0)
|
||||
{
|
||||
cb = em;
|
||||
}
|
||||
|
||||
ai_mat->Get(AI_MATKEY_ROUGHNESS_FACTOR, matv[0]);
|
||||
ai_mat->Get(AI_MATKEY_METALLIC_FACTOR, matv[1]);
|
||||
ai_mat->Get(AI_MATKEY_EMISSIVE_INTENSITY, matv[2]);
|
||||
|
||||
uint32_t handle_diffuse = proc_texture(base, ai_mat, scene, aiTextureType_BASE_COLOR, 0, Texture::handle_white);
|
||||
uint32_t handle_normal = proc_texture(base, ai_mat, scene, aiTextureType_NORMALS, 0, Texture::handle_normal);
|
||||
|
||||
Material mat = {
|
||||
.diffuse = handle_diffuse,
|
||||
.normal = handle_normal,
|
||||
.colour = cb,
|
||||
.roughness = matv[0],
|
||||
.metalness = matv[1],
|
||||
.luminance = matv[2],
|
||||
};
|
||||
|
||||
materials.push_back(mat);
|
||||
}
|
||||
}
|
||||
|
||||
Mesh Model::load(const char* name, glm::mat4 mat) const
|
||||
{
|
||||
Mesh mesh;
|
||||
ProcState state {.base = base};
|
||||
ProcState state {
|
||||
.base = base,
|
||||
.materials = materials,
|
||||
};
|
||||
|
||||
proc_node(state, mat, scene->mRootNode, scene, name);
|
||||
|
||||
mesh.vertices = std::move(state.vertices);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "mesh.hpp"
|
||||
#include "light.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "material.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -26,7 +27,8 @@ class Model
|
|||
|
||||
public:
|
||||
|
||||
std::vector<uint64_t> textures;
|
||||
std::vector<uint32_t> textures;
|
||||
std::vector<Material> materials;
|
||||
std::vector<Camera> cameras;
|
||||
std::vector<Light> lights;
|
||||
|
||||
|
|
|
@ -10,23 +10,28 @@
|
|||
|
||||
using namespace Sim::Graphics::Data;
|
||||
|
||||
static std::unordered_map<std::string, unsigned int> loaded;
|
||||
unsigned int Texture::handle_white;
|
||||
static std::unordered_map<std::string, uint64_t> loaded;
|
||||
uint64_t Texture::handle_white;
|
||||
uint64_t Texture::handle_normal;
|
||||
|
||||
void Texture::init()
|
||||
{
|
||||
unsigned char pixels[] = {255, 255, 255, 255};
|
||||
handle_white = load_mem(pixels, 1, 1, 4);
|
||||
unsigned char pixels_white[] = {255, 255, 255};
|
||||
unsigned char pixels_normal[] = {128, 128, 255};
|
||||
handle_white = load_mem(pixels_white, 1, 1, 3);
|
||||
handle_normal = load_mem(pixels_normal, 1, 1, 3);
|
||||
}
|
||||
|
||||
unsigned int Texture::load_mem(const unsigned char* data, int width, int height, int channels)
|
||||
uint64_t Texture::load_mem(const void* data, int width, int height, int channels)
|
||||
{
|
||||
if(!data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLenum format, format_in;
|
||||
GLenum format;
|
||||
GLenum format_in;
|
||||
|
||||
switch(channels)
|
||||
{
|
||||
case 1:
|
||||
|
@ -45,6 +50,8 @@ unsigned int Texture::load_mem(const unsigned char* data, int width, int height,
|
|||
format = GL_RGBA;
|
||||
format_in = GL_RGBA8;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Invalid number of channels: " + std::to_string(channels));
|
||||
}
|
||||
|
||||
unsigned int texid;
|
||||
|
@ -59,21 +66,21 @@ unsigned int Texture::load_mem(const unsigned char* data, int width, int height,
|
|||
glTextureParameteri(texid, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glGenerateTextureMipmap(texid);
|
||||
|
||||
unsigned int handle = glGetTextureHandleARB(texid);
|
||||
uint64_t handle = glGetTextureHandleARB(texid);
|
||||
glMakeTextureHandleResidentARB(handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
unsigned int Texture::load_mem(const unsigned char* filedata, size_t len)
|
||||
uint64_t Texture::load_mem(const unsigned char* filedata, size_t len)
|
||||
{
|
||||
int width, height, channels;
|
||||
unsigned char* data = stbi_load_from_memory(filedata, len, &width, &height, &channels, 0);
|
||||
unsigned int handle = load_mem(data, width, height, channels);
|
||||
uint64_t handle = load_mem(data, width, height, channels);
|
||||
stbi_image_free(data);
|
||||
return handle;
|
||||
}
|
||||
|
||||
unsigned int Texture::load(std::string path)
|
||||
uint64_t Texture::load(std::string path)
|
||||
{
|
||||
const auto it = loaded.find(path);
|
||||
|
||||
|
@ -84,7 +91,7 @@ unsigned int Texture::load(std::string path)
|
|||
|
||||
int width, height, channels;
|
||||
unsigned char* data = stbi_load(path.c_str(), &width, &height, &channels, 0);
|
||||
unsigned int handle = load_mem(data, width, height, channels);
|
||||
uint64_t handle = load_mem(data, width, height, channels);
|
||||
stbi_image_free(data);
|
||||
|
||||
if(handle == 0)
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Sim::Graphics::Data::Texture
|
||||
{
|
||||
|
||||
extern unsigned int handle_white;
|
||||
extern uint64_t handle_white;
|
||||
extern uint64_t handle_normal;
|
||||
|
||||
void init();
|
||||
unsigned int load(std::string path);
|
||||
unsigned int load_mem(const unsigned char* data, int width, int height, int channels);
|
||||
unsigned int load_mem(const unsigned char* data, size_t len);
|
||||
uint64_t load(std::string path);
|
||||
uint64_t load_mem(const void* data, int width, int height, int channels);
|
||||
uint64_t load_mem(const unsigned char* data, size_t len);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../window.hpp"
|
||||
#include "../camera.hpp"
|
||||
#include "../input/focus.hpp"
|
||||
#include "../data/texture.hpp"
|
||||
#include "../../system.hpp"
|
||||
#include "../../util/math.hpp"
|
||||
#include "../../util/streams.hpp"
|
||||
|
@ -150,10 +151,10 @@ CCTV::CCTV(Model& model)
|
|||
glMakeTextureHandleResidentARB(handle);
|
||||
|
||||
m_screen.vertices = {
|
||||
{.texid=handle, .texpos={0, 1}, .pos={0, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
|
||||
{.texid=handle, .texpos={0, 0}, .pos={0, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
|
||||
{.texid=handle, .texpos={1, 1}, .pos={1, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
|
||||
{.texid=handle, .texpos={1, 0}, .pos={1, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
|
||||
{.texpos={0, 1}, .pos={0, 0, 0}, .transform_id=0, .tex_diffuse=handle, .material={0, 0, 1}},
|
||||
{.texpos={0, 0}, .pos={0, 1, 0}, .transform_id=0, .tex_diffuse=handle, .material={0, 0, 1}},
|
||||
{.texpos={1, 1}, .pos={1, 0, 0}, .transform_id=0, .tex_diffuse=handle, .material={0, 0, 1}},
|
||||
{.texpos={1, 0}, .pos={1, 1, 0}, .transform_id=0, .tex_diffuse=handle, .material={0, 0, 1}},
|
||||
};
|
||||
m_screen.indices = {0, 1, 3, 0, 3, 2};
|
||||
m_screen.transforms = {model.load_matrix("translation_monitor_1")};
|
||||
|
@ -250,7 +251,9 @@ void CCTV::render_view()
|
|||
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &view[0][0]);
|
||||
glUniform3fv(Shader::MAIN["camera_pos"], 1, &active.pos[0]);
|
||||
|
||||
Window::bind_scene_ssbo();
|
||||
Window::render_scene();
|
||||
Window::render_dynamic();
|
||||
Window::render_player();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ class CCTV : public Data::MeshGen
|
|||
const int width;
|
||||
const int height;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
std::vector<Data::Camera> cameras;
|
||||
|
|
|
@ -146,10 +146,10 @@ static Data::Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour)
|
|||
|
||||
mesh.indices = {0, 1, 3, 0, 3, 2};
|
||||
mesh.vertices = {
|
||||
{.texid=Texture::handle_white, .texpos={0, 0}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, -0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}},
|
||||
{.texid=Texture::handle_white, .texpos={0, 1}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, 0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}},
|
||||
{.texid=Texture::handle_white, .texpos={1, 0}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, -0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}},
|
||||
{.texid=Texture::handle_white, .texpos={1, 1}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, 0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}},
|
||||
{.texpos={0, 0}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, -0.75, 0, 1)), .colour=colour, .material={0, 0, 1}},
|
||||
{.texpos={0, 1}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, 0.75, 0, 1)), .colour=colour, .material={0, 0, 1}},
|
||||
{.texpos={1, 0}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, -0.75, 0, 1)), .colour=colour, .material={0, 0, 1}},
|
||||
{.texpos={1, 1}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, 0.75, 0, 1)), .colour=colour, .material={0, 0, 1}},
|
||||
};
|
||||
|
||||
return mesh;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
using namespace Sim::Graphics;
|
||||
|
||||
static Data::GLMesh gm_ui;
|
||||
static Data::Mesh g_ui;
|
||||
static Data::GLMesh gm_dynamic_slow[2];
|
||||
static Widget::Clock w_clock;
|
||||
|
||||
|
@ -26,21 +26,14 @@ static int gm_dynamic_slow_at = 0;
|
|||
|
||||
void UI::init()
|
||||
{
|
||||
Data::Mesh m;
|
||||
|
||||
unsigned int handle = Data::Texture::handle_white;
|
||||
m.indices = {0, 1, 3, 0, 3, 2};
|
||||
m.vertices = {
|
||||
{.texid=handle, .texpos={0, 0}, .pos={-1, -1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
{.texid=handle, .texpos={0, 1}, .pos={-1, 1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
{.texid=handle, .texpos={1, 0}, .pos={ 1, -1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
{.texid=handle, .texpos={1, 1}, .pos={ 1, 1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
g_ui.indices = {0, 1, 3, 0, 3, 2};
|
||||
g_ui.vertices = {
|
||||
{.texpos={0, 0}, .pos={-1, -1, 0}, .material={0, 0, 1}},
|
||||
{.texpos={0, 1}, .pos={-1, 1, 0}, .material={0, 0, 1}},
|
||||
{.texpos={1, 0}, .pos={ 1, -1, 0}, .material={0, 0, 1}},
|
||||
{.texpos={1, 1}, .pos={ 1, 1, 0}, .material={0, 0, 1}},
|
||||
};
|
||||
|
||||
m.bake_transforms();
|
||||
|
||||
gm_ui.bind();
|
||||
gm_ui.set(m, GL_STATIC_DRAW);
|
||||
g_ui.bake_transforms();
|
||||
}
|
||||
|
||||
void UI::update(double dt)
|
||||
|
@ -54,10 +47,11 @@ void UI::update_slow()
|
|||
|
||||
w_clock.remesh_slow(mesh);
|
||||
|
||||
mesh.add(g_ui);
|
||||
mesh.bake_transforms();
|
||||
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].bind();
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].set(mesh, GL_DYNAMIC_DRAW);
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].set(mesh, GL_STREAM_DRAW);
|
||||
gm_dynamic_slow_at = (gm_dynamic_slow_at + 1) % 2;
|
||||
}
|
||||
|
||||
|
@ -72,9 +66,6 @@ void UI::render()
|
|||
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]);
|
||||
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]);
|
||||
|
||||
gm_ui.bind();
|
||||
gm_ui.render();
|
||||
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].bind();
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].render();
|
||||
}
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
#include "monitor/cctv.hpp"
|
||||
#include "data/texture.hpp"
|
||||
#include "data/model.hpp"
|
||||
#include "data/gllight.hpp"
|
||||
#include "data/gllights.hpp"
|
||||
#include "data/meshgen.hpp"
|
||||
#include "data/material.hpp"
|
||||
#include "equipment/reactor.hpp"
|
||||
#include "equipment/generator.hpp"
|
||||
#include "equipment/pool.hpp"
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include "../util/streams.hpp"
|
||||
#include "ui.hpp"
|
||||
|
||||
using namespace Sim;
|
||||
using namespace Sim::Graphics;
|
||||
using namespace Sim::Graphics::Data;
|
||||
|
||||
|
@ -44,8 +46,6 @@ constexpr int SSBO_TRANSFORMS_LEN = 2;
|
|||
|
||||
static GLFWwindow* win;
|
||||
static bool win_should_close = false;
|
||||
static unsigned int ssbo_lights;
|
||||
static unsigned int ssbo_shadow_maps;
|
||||
static unsigned int ssbo_transforms[SSBO_TRANSFORMS_LEN];
|
||||
static unsigned int wait_at = 0;
|
||||
|
||||
|
@ -59,7 +59,7 @@ static GLMesh gm_scene;
|
|||
static GLMesh gm_player;
|
||||
static GLMesh gm_dynamic_slow[2];
|
||||
|
||||
static std::vector<GLLight> lights;
|
||||
static std::unique_ptr<GLLights> lights;
|
||||
static std::vector<MeshGen*> monitors;
|
||||
static std::vector<MeshGen*> equipment;
|
||||
|
||||
|
@ -101,10 +101,6 @@ void remesh_static()
|
|||
std::cout << "Total triangle count: " << mesh.indices.size() / 3 << "\n";
|
||||
}
|
||||
|
||||
void render_shadow_map()
|
||||
{
|
||||
}
|
||||
|
||||
void Window::create()
|
||||
{
|
||||
glfwInit();
|
||||
|
@ -195,12 +191,6 @@ void Window::create()
|
|||
|
||||
Camera::init(model);
|
||||
|
||||
// send all the light data
|
||||
glGenBuffers(1, &ssbo_lights);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_lights);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, model.lights.size() * sizeof(model.lights[0]), &model.lights[0], GL_STATIC_DRAW);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo_lights);
|
||||
|
||||
glUniform1i(Shader::MAIN["lights_count"], model.lights.size());
|
||||
|
||||
monitors.push_back(new Monitor::Core(model));
|
||||
|
@ -221,29 +211,15 @@ void Window::create()
|
|||
// setup lighting and prerender shadows
|
||||
Shader::LIGHT.use();
|
||||
glUniform1f(Shader::LIGHT["far_plane"], 100.0f);
|
||||
GLLight::init();
|
||||
GLLights::init();
|
||||
|
||||
std::vector<unsigned long> light_handles;
|
||||
|
||||
for(int i = 0; i < model.lights.size(); i++)
|
||||
{
|
||||
GLLight light(model.lights[i]);
|
||||
light.render();
|
||||
|
||||
light_handles.push_back(light.handle);
|
||||
lights.push_back(std::move(light));
|
||||
}
|
||||
lights = std::make_unique<GLLights>(std::move(model.lights));
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, lights->ssbo);
|
||||
|
||||
Shader::MAIN.use();
|
||||
glUniform1f(Shader::MAIN["far_plane"], 100.0f);
|
||||
glUniform1i(Shader::MAIN["shadows_enabled"], 1);
|
||||
|
||||
// send all the light shadow map handles
|
||||
glGenBuffers(1, &ssbo_shadow_maps);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_shadow_maps);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, light_handles.size() * sizeof(light_handles[0]), &light_handles[0], GL_STATIC_DRAW);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo_shadow_maps);
|
||||
|
||||
// setup the transforms ssbos and their initial values
|
||||
|
||||
std::vector<glm::mat4> transforms;
|
||||
|
@ -344,25 +320,28 @@ void Window::render_player()
|
|||
gm_player.render();
|
||||
}
|
||||
|
||||
void Window::bind_scene_ssbo()
|
||||
{
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]);
|
||||
}
|
||||
|
||||
void Window::render_scene()
|
||||
{
|
||||
gm_scene.bind();
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]);
|
||||
gm_scene.render();
|
||||
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].bind();
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].render();
|
||||
|
||||
Focus::render();
|
||||
}
|
||||
|
||||
void Window::render_dynamic()
|
||||
{
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].bind();
|
||||
gm_dynamic_slow[gm_dynamic_slow_at].render();
|
||||
}
|
||||
|
||||
void Window::render()
|
||||
{
|
||||
Shader::LIGHT.use();
|
||||
for(auto& light : lights)
|
||||
{
|
||||
light.render();
|
||||
}
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
glm::vec<2, int> size = Resize::get_size();
|
||||
glm::vec3 camera_pos = Camera::get_pos();
|
||||
|
@ -370,6 +349,10 @@ void Window::render()
|
|||
|
||||
Shader::MAIN.use();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, lights->texid);
|
||||
glUniform1i(Shader::MAIN["shadow_maps"], 0);
|
||||
|
||||
glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity());
|
||||
glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 100.f);
|
||||
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
|
||||
|
@ -392,20 +375,23 @@ void Window::render()
|
|||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, size.x, size.y);
|
||||
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
bind_scene_ssbo();
|
||||
render_scene();
|
||||
render_dynamic();
|
||||
monitor_cctv->render_screen();
|
||||
|
||||
brightness = glm::vec3(1);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
UI::render();
|
||||
Focus::render_ui();
|
||||
|
||||
glfwSwapBuffers(win);
|
||||
|
||||
Shader::LIGHT.use();
|
||||
glFrontFace(GL_CW);
|
||||
lights->render();
|
||||
}
|
||||
|
||||
bool Window::should_close()
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/matrix.hpp>
|
||||
|
||||
#include "../system.hpp"
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace Sim::Graphics::Window
|
||||
{
|
||||
|
||||
|
@ -16,7 +17,9 @@ void create();
|
|||
void reload();
|
||||
void update(double dt);
|
||||
void render();
|
||||
void bind_scene_ssbo();
|
||||
void render_scene();
|
||||
void render_dynamic();
|
||||
void render_player();
|
||||
void destroy();
|
||||
void close();
|
||||
|
|
|
@ -10,12 +10,14 @@
|
|||
namespace Sim::Reactor
|
||||
{
|
||||
|
||||
struct Reactor;
|
||||
|
||||
class Rod
|
||||
{
|
||||
public:
|
||||
|
||||
bool selected = false;
|
||||
void* reactor = nullptr;
|
||||
Reactor* reactor = nullptr;
|
||||
static const int VAL_N = 3;
|
||||
|
||||
enum val_t
|
||||
|
|
Loading…
Reference in New Issue