improvements to renderer

This commit is contained in:
Jay Robson 2024-03-21 01:45:08 +11:00
parent c85984fc7f
commit e2b16e0591
29 changed files with 455 additions and 414 deletions

BIN
assets/scene.blend (Stored with Git LFS)

Binary file not shown.

BIN
assets/scene.glb (Stored with Git LFS)

Binary file not shown.

View File

@ -5,6 +5,7 @@ layout (triangles) in;
layout (triangle_strip, max_vertices=18) out; layout (triangle_strip, max_vertices=18) out;
uniform mat4 shadow_mats[6]; uniform mat4 shadow_mats[6];
uniform int light_pass;
in flat int should_ignore[]; in flat int should_ignore[];
out vec3 frag_pos; out vec3 frag_pos;
@ -13,9 +14,11 @@ void main()
{ {
if(should_ignore[0] != 0) return; if(should_ignore[0] != 0) return;
int pass_offset = light_pass * 6;
for(int i = 0; i < 6; i++) for(int i = 0; i < 6; i++)
{ {
gl_Layer = i; gl_Layer = i + pass_offset;
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
{ {

View File

@ -1,20 +1,22 @@
#version 460 core #version 460 core
layout (location = 2) in vec3 aPos; #define MAX_LIGHTS 6
layout (location = 4) in vec4 aColour;
layout (location = 5) in vec3 aMaterial; layout (location = 1) in vec3 aPos;
layout (location = 6) in float aTransformIndex; layout (location = 2) in vec4 aColour;
layout (location = 6) in int aTransformIndex;
layout (binding = 3) readonly buffer TransformBuffer layout (binding = 3) readonly buffer TransformBuffer
{ {
mat4 transforms[]; mat4 transforms[];
}; };
uniform mat4 camera;
out flat int should_ignore; out flat int should_ignore;
uniform vec3 light_pos;
uniform int light_pass;
mat4 load_model_mat(int index) mat4 load_model_mat(int index)
{ {
return index < 0 ? mat4(1.f) : transforms[index]; return index < 0 ? mat4(1.f) : transforms[index];
@ -23,10 +25,9 @@ mat4 load_model_mat(int index)
void main() void main()
{ {
vec4 pos = vec4(aPos, 1.f); vec4 pos = vec4(aPos, 1.f);
mat4 model = load_model_mat(int(aTransformIndex)); mat4 model = load_model_mat(aTransformIndex);
mat4 mv = camera * model;
gl_Position = mv * pos; gl_Position = model * pos - vec4(light_pos, 0.f);
should_ignore = int(aMaterial[2] > 0.f || aColour.a < 1.f); should_ignore = int(aColour.a < 1.f);
} }

View File

@ -5,12 +5,11 @@
const float PI = 3.141592f; const float PI = 3.141592f;
in VS_OUT { in VS_OUT {
vec3 normal; mat3 tbn;
vec4 colour;
vec3 pos; vec3 pos;
vec2 tex_pos; vec2 tex_pos;
vec3 material; flat vec4 colour;
float ambient; flat vec3 material;
} vin; } vin;
struct Light struct Light
@ -19,17 +18,14 @@ struct Light
vec4 colour; vec4 colour;
}; };
layout(std140, binding = 1) readonly buffer LightBuffer layout(std140, binding = 2) readonly buffer LightBuffer
{ {
Light lights[]; Light lights[];
}; };
layout(std430, binding = 2) readonly buffer ShadowMapBuffer in flat sampler2D frag_tex_diffuse;
{ in flat sampler2D frag_tex_normal;
samplerCube shadow_maps[];
};
in flat sampler2D frag_tex;
out vec4 frag_colour; out vec4 frag_colour;
uniform vec3 brightness; uniform vec3 brightness;
@ -38,6 +34,8 @@ uniform float far_plane;
uniform bool shadows_enabled; uniform bool shadows_enabled;
uniform int lights_count; uniform int lights_count;
uniform samplerCubeArrayShadow shadow_maps;
float Map(float v, float i_min, float i_max, float o_min, float o_max) 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); 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() 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; 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; vec3 albedo_lin = sRGB_To_LinRGB(albedo.rgb) * vin.colour.rgb;
albedo *= vin.colour; albedo *= vin.colour;
@ -119,11 +118,11 @@ void main()
float metalness = vin.material[1]; float metalness = vin.material[1];
float luminance = min(vin.material[2], 1.f); 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 V = normalize(camera_pos - vin.pos.xyz);
vec3 F0 = mix(vec3(0.04f), albedo_lin, metalness); 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); vec3 Lo = vec3(0.f);
for(int i = 0; i < lights_count; i++) for(int i = 0; i < lights_count; i++)
@ -135,8 +134,12 @@ void main()
if(shadows_enabled) if(shadows_enabled)
{ {
float max_d = texture(shadow_maps[i], -L).r * far_plane; if(dot(vin.tbn[2], L) < 0.f)
light_m = Ramp(d - max_d, 0.f, 2.5e-2f, 1.f, 0.f); {
continue;
}
light_m = texture(shadow_maps, vec4(-L, i), d / far_plane);
if(light_m <= 0.f) if(light_m <= 0.f)
{ {

View File

@ -2,32 +2,35 @@
#version 460 core #version 460 core
#extension GL_ARB_bindless_texture : require #extension GL_ARB_bindless_texture : require
layout (location = 0) in sampler2D aTex; layout (location = 0) in vec2 aTexPos;
layout (location = 1) in vec2 aTexPos; layout (location = 1) in vec3 aPos;
layout (location = 2) in vec3 aPos; layout (location = 2) in vec4 aColour;
layout (location = 3) in vec3 aNormal; layout (location = 3) in vec3 aTangent;
layout (location = 4) in vec4 aColour; layout (location = 4) in vec3 aBitangent;
layout (location = 5) in vec3 aMaterial; layout (location = 5) in vec3 aNormal;
layout (location = 6) in float aTransformIndex; 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 camera;
uniform mat4 projection; uniform mat4 projection;
layout (binding = 3) readonly buffer TransformBuffer1 layout (std430, binding = 3) readonly buffer TransformBuffer
{ {
mat4 transforms[]; mat4 transforms[];
}; };
out VS_OUT { out VS_OUT {
vec3 normal; mat3 tbn;
vec4 colour;
vec3 pos; vec3 pos;
vec2 tex_pos; vec2 tex_pos;
vec3 material; flat vec4 colour;
float ambient; flat vec3 material;
} vout; } vout;
out flat sampler2D frag_tex; out flat sampler2D frag_tex_diffuse;
out flat sampler2D frag_tex_normal;
mat4 load_model_mat(int index) 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() void main()
{ {
vec4 pos = vec4(aPos, 1.f); vec4 pos = vec4(aPos, 1.f);
mat4 model = load_model_mat(int(aTransformIndex)); mat4 model = load_model_mat(aTransformIndex);
mat4 mv = camera * model; mat4 mv = camera * model;
mat4 mvp = projection * mv; mat4 mvp = projection * mv;
vout.normal = normalize(mat3(model) * aNormal); vout.tbn = mat3(model) * mat3(aTangent, aBitangent, aNormal);
vout.ambient = Map(dot(vout.normal, vec3(0.f, 0.f, 1.f)), -1.f, 1.f, 0.2f, 0.25f);
vout.pos = (model * pos).xyz; vout.pos = (model * pos).xyz;
vout.colour = aColour;
vout.tex_pos = aTexPos; vout.tex_pos = aTexPos;
vout.material = aMaterial; vout.colour = aColour;
frag_tex = aTex; vout.material = aMaterial.xyz;
frag_tex_diffuse = aTexDiffuse;
frag_tex_normal = aTexNormal;
gl_Position = mvp * pos; gl_Position = mvp * pos;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

View File

@ -2,6 +2,7 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <iostream>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include "../shader.hpp" #include "../shader.hpp"
@ -20,38 +21,48 @@ void Arrays::vertex_attrib_pointers()
{ {
Vertex v; 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); 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); 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); 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); 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); 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); 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); 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) std::ostream& Arrays::operator<<(std::ostream& os, const Vertex& v)
{ {
os << "Vertex{"; os << "Vertex{";
os << "texid=" << v.texid << ", ";
os << "texpos=" << v.texpos << ", "; os << "texpos=" << v.texpos << ", ";
os << "pos=" << v.pos << ", "; os << "pos=" << v.pos << ", ";
os << "normal=" << v.normal << ", ";
os << "colour=" << v.colour << ", "; os << "colour=" << v.colour << ", ";
os << "material=" << v.material << ", "; os << "tbn=" << v.tbn << ", ";
os << "transform_id=" << v.transform_id; os << "transform_id=" << v.transform_id << ", ";
os << "tex_diffuse=" << v.tex_diffuse << ", ";
os << "tex_normal=" << v.tex_normal << ", ";
os << "material=" << v.material;
os << "}"; os << "}";
return os; return os;
} }

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include "texture.hpp"
#include <glm/matrix.hpp> #include <glm/matrix.hpp>
#include <ostream> #include <ostream>
@ -9,19 +11,20 @@ namespace Sim::Graphics::Data::Arrays
struct Vertex struct Vertex
{ {
unsigned long texid = 0;
glm::vec2 texpos = {0, 0}; glm::vec2 texpos = {0, 0};
glm::vec3 pos = {0, 0, 0}; glm::vec3 pos = {0, 0, 0};
glm::vec3 normal = {0, 0, 0};
glm::vec4 colour = {1, 1, 1, 1}; glm::vec4 colour = {1, 1, 1, 1};
glm::vec3 material = {0, 0, 0}; glm::mat3 tbn = glm::mat3(1);
float transform_id = -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; constexpr bool operator==(const Vertex&) const = default;
friend std::ostream& operator<<(std::ostream& os, const Vertex& v); friend std::ostream& operator<<(std::ostream& os, const Vertex& v);
} __attribute__((packed)); };
void vertex_attrib_pointers(); void vertex_attrib_pointers();

View File

@ -11,13 +11,14 @@
#include "mesh.hpp" #include "mesh.hpp"
#include "arrays.hpp" #include "arrays.hpp"
#include "material.hpp"
#include "font.hpp" #include "font.hpp"
using namespace Sim::Graphics::Data; using namespace Sim::Graphics::Data;
struct Character struct Character
{ {
unsigned long handle; uint32_t handle;
float advance; float advance;
glm::vec2 size; glm::vec2 size;
glm::vec2 bearing; glm::vec2 bearing;
@ -94,7 +95,6 @@ void Font::init()
c.handle = glGetTextureHandleARB(texids[i]); c.handle = glGetTextureHandleARB(texids[i]);
glMakeTextureHandleResidentARB(c.handle); glMakeTextureHandleResidentARB(c.handle);
chars[i] = c; chars[i] = c;
} }
@ -144,10 +144,10 @@ Mesh& Mesh::load_text(const char* text, double size)
float ex = sx + ch.size.x * size; float ex = sx + ch.size.x * size;
float ey = sy + ch.size.y * 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{.texpos={0, 0}, .pos={sx, sy, 0}, .tex_diffuse=ch.handle, .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{.texpos={0, 1}, .pos={sx, ey, 0}, .tex_diffuse=ch.handle, .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{.texpos={1, 0}, .pos={ex, sy, 0}, .tex_diffuse=ch.handle, .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={1, 1}, .pos={ex, ey, 0}, .tex_diffuse=ch.handle, .material={0, 0, 1}});
indices.insert(indices.end(), &index[0], &index[6]); indices.insert(indices.end(), &index[0], &index[6]);
at += 4; at += 4;

View File

@ -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]);
}

View File

@ -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();
};
};

View File

@ -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]);
}

View File

@ -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();
};
};

View File

@ -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();*/
};
};

View File

@ -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++) 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; 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++) for(int i = 0; i < o.vertices.size(); i++)
{ {
Arrays::Vertex v = o.vertices[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); glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1);
t_mat = mat * t_mat; t_mat = mat * t_mat;
v.pos = t_mat * glm::vec4(v.pos, 1); 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; v.transform_id = -1;
vertices.push_back(v); vertices.push_back(v);
} }
@ -69,8 +79,8 @@ Mesh& Mesh::add(const Mesh& o, glm::mat4 mat, bool bake)
} }
glm::mat3 mat3(mat); glm::mat3 mat3(mat);
float t_off = transforms.size(); int t_off = transforms.size();
float t_new = -1; int t_new = -1;
if(mat != glm::mat4(1)) if(mat != glm::mat4(1))
{ {
@ -118,13 +128,13 @@ Mesh& Mesh::bake_transforms()
{ {
for(unsigned int i = 0; i < vertices.size(); i++) 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) if(id >= 0)
{ {
glm::mat4 transform = transforms[id]; glm::mat4 transform = transforms[id];
vertices[i].pos = glm::vec3(transform * glm::vec4(vertices[i].pos, 1)); 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; 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++) 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); glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1);
v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 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++) 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); glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1);
v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 1)); v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 1));

View File

@ -26,7 +26,8 @@ struct Mesh
Mesh& bake_transforms(); Mesh& bake_transforms();
Mesh& set_blank_transform(); 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);
Mesh& load_text(const char* text, double size, glm::vec2 align); 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); Mesh& add(const Mesh& o, glm::mat4 mat = glm::mat4(1), bool bake = false);

View File

@ -6,6 +6,7 @@
#include <unordered_map> #include <unordered_map>
#include <iostream> #include <iostream>
#include <sstream>
#include <vector> #include <vector>
#include "mesh.hpp" #include "mesh.hpp"
@ -24,106 +25,17 @@ struct ProcState
std::vector<Arrays::Vertex> vertices; std::vector<Arrays::Vertex> vertices;
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
std::vector<glm::mat4> transforms; 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) static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene)
{ {
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; Material mat = state.materials[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);
unsigned int offset = state.offset; unsigned int offset = state.offset;
if(!handle) if(!mesh->HasNormals())
{ {
handle = proc_texture(state, material, scene, aiTextureType_DIFFUSE, 0); throw std::runtime_error("Mesh has no normals");
}
if(!handle)
{
handle = Texture::handle_white;
} }
for(unsigned int i = 0; i < mesh->mNumVertices; i++) 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; Arrays::Vertex vertex;
auto [x, y, z] = mesh->mVertices[i]; auto [x, y, z] = mesh->mVertices[i];
vertex.pos = glm::vec3(x, y, z);
vertex.transform_id = state.transforms.size(); vertex.transform_id = state.transforms.size();
vertex.material = matv; vertex.pos = glm::vec3(x, y, z);
vertex.texid = handle; vertex.colour = mat.colour;
vertex.colour = cb; vertex.tex_diffuse = mat.diffuse;
vertex.tex_normal = mat.normal;
if(mesh->HasNormals()) vertex.material = {mat.roughness, mat.metalness, mat.luminance};
{
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};
}*/
if(mesh->mTextureCoords[0]) if(mesh->mTextureCoords[0])
{ {
@ -157,6 +56,30 @@ static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene)
vertex.texpos = {x, y}; 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); 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"; 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)); 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) Model::Model(std::string base, std::string filename) : base(base)
{ {
std::string path = base + "/" + filename; 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); textures.reserve(scene->mNumTextures);
materials.reserve(scene->mNumMaterials);
for(int i = 0; i < scene->mNumTextures; i++) for(int i = 0; i < scene->mNumTextures; i++)
{ {
aiTexture* tex = scene->mTextures[i]; aiTexture* tex = scene->mTextures[i];
unsigned int handle = proc_embedded_texture(tex); uint64_t handle = proc_embedded_texture(tex);
textures.push_back(handle); 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}); 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 Model::load(const char* name, glm::mat4 mat) const
{ {
Mesh mesh; Mesh mesh;
ProcState state {.base = base}; ProcState state {
.base = base,
.materials = materials,
};
proc_node(state, mat, scene->mRootNode, scene, name); proc_node(state, mat, scene->mRootNode, scene, name);
mesh.vertices = std::move(state.vertices); mesh.vertices = std::move(state.vertices);

View File

@ -4,6 +4,7 @@
#include "mesh.hpp" #include "mesh.hpp"
#include "light.hpp" #include "light.hpp"
#include "camera.hpp" #include "camera.hpp"
#include "material.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
@ -26,7 +27,8 @@ class Model
public: public:
std::vector<uint64_t> textures; std::vector<uint32_t> textures;
std::vector<Material> materials;
std::vector<Camera> cameras; std::vector<Camera> cameras;
std::vector<Light> lights; std::vector<Light> lights;

View File

@ -10,23 +10,28 @@
using namespace Sim::Graphics::Data; using namespace Sim::Graphics::Data;
static std::unordered_map<std::string, unsigned int> loaded; static std::unordered_map<std::string, uint64_t> loaded;
unsigned int Texture::handle_white; uint64_t Texture::handle_white;
uint64_t Texture::handle_normal;
void Texture::init() void Texture::init()
{ {
unsigned char pixels[] = {255, 255, 255, 255}; unsigned char pixels_white[] = {255, 255, 255};
handle_white = load_mem(pixels, 1, 1, 4); 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) if(!data)
{ {
return 0; return 0;
} }
GLenum format, format_in; GLenum format;
GLenum format_in;
switch(channels) switch(channels)
{ {
case 1: case 1:
@ -45,6 +50,8 @@ unsigned int Texture::load_mem(const unsigned char* data, int width, int height,
format = GL_RGBA; format = GL_RGBA;
format_in = GL_RGBA8; format_in = GL_RGBA8;
break; break;
default:
throw std::runtime_error("Invalid number of channels: " + std::to_string(channels));
} }
unsigned int texid; 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); glTextureParameteri(texid, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateTextureMipmap(texid); glGenerateTextureMipmap(texid);
unsigned int handle = glGetTextureHandleARB(texid); uint64_t handle = glGetTextureHandleARB(texid);
glMakeTextureHandleResidentARB(handle); glMakeTextureHandleResidentARB(handle);
return 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; int width, height, channels;
unsigned char* data = stbi_load_from_memory(filedata, len, &width, &height, &channels, 0); 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); stbi_image_free(data);
return handle; return handle;
} }
unsigned int Texture::load(std::string path) uint64_t Texture::load(std::string path)
{ {
const auto it = loaded.find(path); const auto it = loaded.find(path);
@ -84,7 +91,7 @@ unsigned int Texture::load(std::string path)
int width, height, channels; int width, height, channels;
unsigned char* data = stbi_load(path.c_str(), &width, &height, &channels, 0); 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); stbi_image_free(data);
if(handle == 0) if(handle == 0)

View File

@ -1,17 +1,20 @@
#pragma once #pragma once
#include <GL/glew.h>
#include <string> #include <string>
namespace Sim::Graphics::Data::Texture namespace Sim::Graphics::Data::Texture
{ {
extern unsigned int handle_white; extern uint64_t handle_white;
extern uint64_t handle_normal;
void init(); void init();
unsigned int load(std::string path); uint64_t load(std::string path);
unsigned int load_mem(const unsigned char* data, int width, int height, int channels); uint64_t load_mem(const void* data, int width, int height, int channels);
unsigned int load_mem(const unsigned char* data, size_t len); uint64_t load_mem(const unsigned char* data, size_t len);
}; };

View File

@ -12,6 +12,7 @@
#include "../window.hpp" #include "../window.hpp"
#include "../camera.hpp" #include "../camera.hpp"
#include "../input/focus.hpp" #include "../input/focus.hpp"
#include "../data/texture.hpp"
#include "../../system.hpp" #include "../../system.hpp"
#include "../../util/math.hpp" #include "../../util/math.hpp"
#include "../../util/streams.hpp" #include "../../util/streams.hpp"
@ -150,10 +151,10 @@ CCTV::CCTV(Model& model)
glMakeTextureHandleResidentARB(handle); glMakeTextureHandleResidentARB(handle);
m_screen.vertices = { m_screen.vertices = {
{.texid=handle, .texpos={0, 1}, .pos={0, 0, 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}},
{.texid=handle, .texpos={0, 0}, .pos={0, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, {.texpos={0, 0}, .pos={0, 1, 0}, .transform_id=0, .tex_diffuse=handle, .material={0, 0, 1}},
{.texid=handle, .texpos={1, 1}, .pos={1, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, {.texpos={1, 1}, .pos={1, 0, 0}, .transform_id=0, .tex_diffuse=handle, .material={0, 0, 1}},
{.texid=handle, .texpos={1, 0}, .pos={1, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, {.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.indices = {0, 1, 3, 0, 3, 2};
m_screen.transforms = {model.load_matrix("translation_monitor_1")}; 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]); glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &view[0][0]);
glUniform3fv(Shader::MAIN["camera_pos"], 1, &active.pos[0]); glUniform3fv(Shader::MAIN["camera_pos"], 1, &active.pos[0]);
Window::bind_scene_ssbo();
Window::render_scene(); Window::render_scene();
Window::render_dynamic();
Window::render_player(); Window::render_player();
} }

View File

@ -25,7 +25,6 @@ class CCTV : public Data::MeshGen
const int width; const int width;
const int height; const int height;
public: public:
std::vector<Data::Camera> cameras; std::vector<Data::Camera> cameras;

View File

@ -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.indices = {0, 1, 3, 0, 3, 2};
mesh.vertices = { 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}}, {.texpos={0, 0}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, -0.75, 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}}, {.texpos={0, 1}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, 0.75, 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}}, {.texpos={1, 0}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, -0.75, 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={1, 1}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, 0.75, 0, 1)), .colour=colour, .material={0, 0, 1}},
}; };
return mesh; return mesh;

View File

@ -18,7 +18,7 @@
using namespace Sim::Graphics; using namespace Sim::Graphics;
static Data::GLMesh gm_ui; static Data::Mesh g_ui;
static Data::GLMesh gm_dynamic_slow[2]; static Data::GLMesh gm_dynamic_slow[2];
static Widget::Clock w_clock; static Widget::Clock w_clock;
@ -26,21 +26,14 @@ static int gm_dynamic_slow_at = 0;
void UI::init() void UI::init()
{ {
Data::Mesh m; g_ui.indices = {0, 1, 3, 0, 3, 2};
g_ui.vertices = {
unsigned int handle = Data::Texture::handle_white; {.texpos={0, 0}, .pos={-1, -1, 0}, .material={0, 0, 1}},
m.indices = {0, 1, 3, 0, 3, 2}; {.texpos={0, 1}, .pos={-1, 1, 0}, .material={0, 0, 1}},
m.vertices = { {.texpos={1, 0}, .pos={ 1, -1, 0}, .material={0, 0, 1}},
{.texid=handle, .texpos={0, 0}, .pos={-1, -1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, {.texpos={1, 1}, .pos={ 1, 1, 0}, .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.bake_transforms();
m.bake_transforms();
gm_ui.bind();
gm_ui.set(m, GL_STATIC_DRAW);
} }
void UI::update(double dt) void UI::update(double dt)
@ -54,10 +47,11 @@ void UI::update_slow()
w_clock.remesh_slow(mesh); w_clock.remesh_slow(mesh);
mesh.add(g_ui);
mesh.bake_transforms(); mesh.bake_transforms();
gm_dynamic_slow[gm_dynamic_slow_at].bind(); 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; 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["projection"], 1, false, &mat_projection[0][0]);
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[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].bind();
gm_dynamic_slow[gm_dynamic_slow_at].render(); gm_dynamic_slow[gm_dynamic_slow_at].render();
} }

View File

@ -28,8 +28,9 @@
#include "monitor/cctv.hpp" #include "monitor/cctv.hpp"
#include "data/texture.hpp" #include "data/texture.hpp"
#include "data/model.hpp" #include "data/model.hpp"
#include "data/gllight.hpp" #include "data/gllights.hpp"
#include "data/meshgen.hpp" #include "data/meshgen.hpp"
#include "data/material.hpp"
#include "equipment/reactor.hpp" #include "equipment/reactor.hpp"
#include "equipment/generator.hpp" #include "equipment/generator.hpp"
#include "equipment/pool.hpp" #include "equipment/pool.hpp"
@ -37,6 +38,7 @@
#include "../util/streams.hpp" #include "../util/streams.hpp"
#include "ui.hpp" #include "ui.hpp"
using namespace Sim;
using namespace Sim::Graphics; using namespace Sim::Graphics;
using namespace Sim::Graphics::Data; using namespace Sim::Graphics::Data;
@ -44,8 +46,6 @@ constexpr int SSBO_TRANSFORMS_LEN = 2;
static GLFWwindow* win; static GLFWwindow* win;
static bool win_should_close = false; 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 ssbo_transforms[SSBO_TRANSFORMS_LEN];
static unsigned int wait_at = 0; static unsigned int wait_at = 0;
@ -59,7 +59,7 @@ static GLMesh gm_scene;
static GLMesh gm_player; static GLMesh gm_player;
static GLMesh gm_dynamic_slow[2]; 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*> monitors;
static std::vector<MeshGen*> equipment; static std::vector<MeshGen*> equipment;
@ -101,10 +101,6 @@ void remesh_static()
std::cout << "Total triangle count: " << mesh.indices.size() / 3 << "\n"; std::cout << "Total triangle count: " << mesh.indices.size() / 3 << "\n";
} }
void render_shadow_map()
{
}
void Window::create() void Window::create()
{ {
glfwInit(); glfwInit();
@ -195,12 +191,6 @@ void Window::create()
Camera::init(model); 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()); glUniform1i(Shader::MAIN["lights_count"], model.lights.size());
monitors.push_back(new Monitor::Core(model)); monitors.push_back(new Monitor::Core(model));
@ -221,29 +211,15 @@ void Window::create()
// setup lighting and prerender shadows // setup lighting and prerender shadows
Shader::LIGHT.use(); Shader::LIGHT.use();
glUniform1f(Shader::LIGHT["far_plane"], 100.0f); glUniform1f(Shader::LIGHT["far_plane"], 100.0f);
GLLight::init(); GLLights::init();
std::vector<unsigned long> light_handles; lights = std::make_unique<GLLights>(std::move(model.lights));
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, lights->ssbo);
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));
}
Shader::MAIN.use(); Shader::MAIN.use();
glUniform1f(Shader::MAIN["far_plane"], 100.0f); glUniform1f(Shader::MAIN["far_plane"], 100.0f);
glUniform1i(Shader::MAIN["shadows_enabled"], 1); 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 // setup the transforms ssbos and their initial values
std::vector<glm::mat4> transforms; std::vector<glm::mat4> transforms;
@ -344,25 +320,28 @@ void Window::render_player()
gm_player.render(); gm_player.render();
} }
void Window::bind_scene_ssbo()
{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]);
}
void Window::render_scene() void Window::render_scene()
{ {
gm_scene.bind(); gm_scene.bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]);
gm_scene.render(); gm_scene.render();
gm_dynamic_slow[gm_dynamic_slow_at].bind();
gm_dynamic_slow[gm_dynamic_slow_at].render();
Focus::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() void Window::render()
{ {
Shader::LIGHT.use(); glFrontFace(GL_CCW);
for(auto& light : lights)
{
light.render();
}
glm::vec<2, int> size = Resize::get_size(); glm::vec<2, int> size = Resize::get_size();
glm::vec3 camera_pos = Camera::get_pos(); glm::vec3 camera_pos = Camera::get_pos();
@ -370,6 +349,10 @@ void Window::render()
Shader::MAIN.use(); 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::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); glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 100.f);
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]); glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
@ -392,20 +375,23 @@ void Window::render()
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glViewport(0, 0, size.x, size.y); glViewport(0, 0, size.x, size.y);
glFrontFace(GL_CCW); bind_scene_ssbo();
render_scene(); render_scene();
render_dynamic();
monitor_cctv->render_screen(); monitor_cctv->render_screen();
brightness = glm::vec3(1); brightness = glm::vec3(1);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]); glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
glClear(GL_DEPTH_BUFFER_BIT);
UI::render(); UI::render();
Focus::render_ui(); Focus::render_ui();
glfwSwapBuffers(win); glfwSwapBuffers(win);
Shader::LIGHT.use();
glFrontFace(GL_CW);
lights->render();
} }
bool Window::should_close() bool Window::should_close()

View File

@ -1,11 +1,12 @@
#pragma once #pragma once
#include <GLFW/glfw3.h>
#include <glm/matrix.hpp> #include <glm/matrix.hpp>
#include "../system.hpp" #include "../system.hpp"
struct GLFWwindow;
namespace Sim::Graphics::Window namespace Sim::Graphics::Window
{ {
@ -16,7 +17,9 @@ void create();
void reload(); void reload();
void update(double dt); void update(double dt);
void render(); void render();
void bind_scene_ssbo();
void render_scene(); void render_scene();
void render_dynamic();
void render_player(); void render_player();
void destroy(); void destroy();
void close(); void close();

View File

@ -10,12 +10,14 @@
namespace Sim::Reactor namespace Sim::Reactor
{ {
struct Reactor;
class Rod class Rod
{ {
public: public:
bool selected = false; bool selected = false;
void* reactor = nullptr; Reactor* reactor = nullptr;
static const int VAL_N = 3; static const int VAL_N = 3;
enum val_t enum val_t