diff --git a/assets/scene.blend b/assets/scene.blend index e7c4615..b618e75 100644 --- a/assets/scene.blend +++ b/assets/scene.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b85c7237e37ff2b9ba6b0d3407f27989c1173b3e4c0eee5776fe52effd26ad69 -size 16317033 +oid sha256:a0cb597b1f61b1eb72ef1177aa55082c7ffa5bfaf8af87cbc6e1f04510e840e8 +size 16472105 diff --git a/assets/scene.glb b/assets/scene.glb index e41dd76..a59a67a 100644 --- a/assets/scene.glb +++ b/assets/scene.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:588b2c0d24f195a86b22f5d45aec1008a8b8c35164797c4d74f1631de926d8d7 -size 1932828 +oid sha256:cc51cad04148d0f57916c3d7041776998fc93e50dca0ba4fc5fb47e6b4eadc46 +size 2044764 diff --git a/assets/shader/light.gsh b/assets/shader/light.gsh index c234248..950f2c5 100644 --- a/assets/shader/light.gsh +++ b/assets/shader/light.gsh @@ -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++) { diff --git a/assets/shader/light.vsh b/assets/shader/light.vsh index a351367..e0eabc8 100644 --- a/assets/shader/light.vsh +++ b/assets/shader/light.vsh @@ -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); } diff --git a/assets/shader/main.fsh b/assets/shader/main.fsh index 086b51d..e693221 100644 --- a/assets/shader/main.fsh +++ b/assets/shader/main.fsh @@ -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,21 +107,22 @@ 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; - + float roughness = vin.material[0]; 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) { diff --git a/assets/shader/main.vsh b/assets/shader/main.vsh index abccc2a..f976320 100644 --- a/assets/shader/main.vsh +++ b/assets/shader/main.vsh @@ -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; } diff --git a/assets/texture/scene/Reactor_Vessel.png b/assets/texture/scene/Reactor_Vessel.png new file mode 100644 index 0000000..cb2e933 Binary files /dev/null and b/assets/texture/scene/Reactor_Vessel.png differ diff --git a/assets/texture/scene/Reactor_Vessel_Normal.png b/assets/texture/scene/Reactor_Vessel_Normal.png new file mode 100644 index 0000000..e813cee Binary files /dev/null and b/assets/texture/scene/Reactor_Vessel_Normal.png differ diff --git a/src/graphics/data/arrays.cpp b/src/graphics/data/arrays.cpp index aaaba0c..3b7dba8 100644 --- a/src/graphics/data/arrays.cpp +++ b/src/graphics/data/arrays.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "../shader.hpp" @@ -19,39 +20,49 @@ static void* ptr_diff(void* a, void* b) 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; } diff --git a/src/graphics/data/arrays.hpp b/src/graphics/data/arrays.hpp index 734ad33..3f93e19 100644 --- a/src/graphics/data/arrays.hpp +++ b/src/graphics/data/arrays.hpp @@ -1,6 +1,8 @@ #pragma once +#include "texture.hpp" + #include #include @@ -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(); diff --git a/src/graphics/data/font.cpp b/src/graphics/data/font.cpp index d3f9a68..cb78c28 100644 --- a/src/graphics/data/font.cpp +++ b/src/graphics/data/font.cpp @@ -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; diff --git a/src/graphics/data/gllight.cpp b/src/graphics/data/gllight.cpp deleted file mode 100644 index 5def4a8..0000000 --- a/src/graphics/data/gllight.cpp +++ /dev/null @@ -1,94 +0,0 @@ - -#include -#include - -#include "gllight.hpp" -#include "../shader.hpp" -#include "../window.hpp" -#include "texture.hpp" - -#include -#include - -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(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]); -} - diff --git a/src/graphics/data/gllight.hpp b/src/graphics/data/gllight.hpp deleted file mode 100644 index 44c4c25..0000000 --- a/src/graphics/data/gllight.hpp +++ /dev/null @@ -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(); -}; - -}; - diff --git a/src/graphics/data/gllights.cpp b/src/graphics/data/gllights.cpp new file mode 100644 index 0000000..4d037ae --- /dev/null +++ b/src/graphics/data/gllights.cpp @@ -0,0 +1,88 @@ + +#include +#include + +#include "gllights.hpp" +#include "../shader.hpp" +#include "../window.hpp" +#include "texture.hpp" + +#include +#include + +using namespace Sim::Graphics::Data; + +static glm::mat4 shadow_mats[6]; + +GLLights::GLLights(std::vector&& _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(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]); +} + diff --git a/src/graphics/data/gllights.hpp b/src/graphics/data/gllights.hpp new file mode 100644 index 0000000..9fc3e44 --- /dev/null +++ b/src/graphics/data/gllights.hpp @@ -0,0 +1,30 @@ + +#pragma once + +#include + +#include "light.hpp" + +namespace Sim::Graphics::Data +{ + +struct GLLights +{ + const int size; + + unsigned int texid, fbo, ssbo; + + std::vector lights; + + GLLights(std::vector&& lights); + GLLights(GLLights&& o); + GLLights(const GLLights& o) = delete; + ~GLLights(); + + static void init(); + + void render(); +}; + +}; + diff --git a/src/graphics/data/material.hpp b/src/graphics/data/material.hpp new file mode 100644 index 0000000..e4bc3ab --- /dev/null +++ b/src/graphics/data/material.hpp @@ -0,0 +1,27 @@ + +#pragma once + +#include + +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();*/ +}; + +}; + diff --git a/src/graphics/data/mesh.cpp b/src/graphics/data/mesh.cpp index e503629..ff20192 100644 --- a/src/graphics/data/mesh.cpp +++ b/src/graphics/data/mesh.cpp @@ -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)); diff --git a/src/graphics/data/mesh.hpp b/src/graphics/data/mesh.hpp index 69ba390..3ffbd8e 100644 --- a/src/graphics/data/mesh.hpp +++ b/src/graphics/data/mesh.hpp @@ -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); diff --git a/src/graphics/data/model.cpp b/src/graphics/data/model.cpp index ec00973..057f493 100644 --- a/src/graphics/data/model.cpp +++ b/src/graphics/data/model.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "mesh.hpp" @@ -24,106 +25,17 @@ struct ProcState std::vector vertices; std::vector indices; std::vector transforms; - std::unordered_map handles; + const std::vector& 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,31 +43,42 @@ 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); - } + 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->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]) { auto [x, y, z] = mesh->mTextureCoords[0][i]; 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); diff --git a/src/graphics/data/model.hpp b/src/graphics/data/model.hpp index e849f75..b7b056f 100644 --- a/src/graphics/data/model.hpp +++ b/src/graphics/data/model.hpp @@ -4,6 +4,7 @@ #include "mesh.hpp" #include "light.hpp" #include "camera.hpp" +#include "material.hpp" #include #include @@ -26,7 +27,8 @@ class Model public: - std::vector textures; + std::vector textures; + std::vector materials; std::vector cameras; std::vector lights; diff --git a/src/graphics/data/texture.cpp b/src/graphics/data/texture.cpp index 0e6266c..7c82836 100644 --- a/src/graphics/data/texture.cpp +++ b/src/graphics/data/texture.cpp @@ -10,23 +10,28 @@ using namespace Sim::Graphics::Data; -static std::unordered_map loaded; -unsigned int Texture::handle_white; +static std::unordered_map 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,8 +50,10 @@ 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; glCreateTextures(GL_TEXTURE_2D, 1, &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) diff --git a/src/graphics/data/texture.hpp b/src/graphics/data/texture.hpp index 223a135..3a3af33 100644 --- a/src/graphics/data/texture.hpp +++ b/src/graphics/data/texture.hpp @@ -1,17 +1,20 @@ #pragma once +#include + #include 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); }; diff --git a/src/graphics/monitor/cctv.cpp b/src/graphics/monitor/cctv.cpp index 0884820..12f1244 100644 --- a/src/graphics/monitor/cctv.cpp +++ b/src/graphics/monitor/cctv.cpp @@ -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(); } diff --git a/src/graphics/monitor/cctv.hpp b/src/graphics/monitor/cctv.hpp index c39bde4..678698f 100644 --- a/src/graphics/monitor/cctv.hpp +++ b/src/graphics/monitor/cctv.hpp @@ -25,7 +25,6 @@ class CCTV : public Data::MeshGen const int width; const int height; - public: std::vector cameras; diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index e4de59f..54494c4 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -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; diff --git a/src/graphics/ui.cpp b/src/graphics/ui.cpp index 66f80d2..8c2eb01 100644 --- a/src/graphics/ui.cpp +++ b/src/graphics/ui.cpp @@ -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; } @@ -71,9 +65,6 @@ void UI::render() glm::mat4 mat_camera = glm::scale(glm::mat4(1), glm::vec3(1.0f / wsize * glm::vec2(1, -1), -1)); 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(); diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index daec62e..2c9a403 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -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 lights; +static std::unique_ptr lights; static std::vector monitors; static std::vector 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,28 +211,14 @@ void Window::create() // setup lighting and prerender shadows Shader::LIGHT.use(); glUniform1f(Shader::LIGHT["far_plane"], 100.0f); - GLLight::init(); + GLLights::init(); - std::vector 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(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 @@ -344,31 +320,38 @@ 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(); glm::mat4 mat_camera = Camera::get_matrix(); 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); @@ -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() diff --git a/src/graphics/window.hpp b/src/graphics/window.hpp index 0baf471..8e90e53 100644 --- a/src/graphics/window.hpp +++ b/src/graphics/window.hpp @@ -1,11 +1,12 @@ #pragma once -#include #include #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(); diff --git a/src/reactor/rod.hpp b/src/reactor/rod.hpp index 48e19f0..2396cfa 100644 --- a/src/reactor/rod.hpp +++ b/src/reactor/rod.hpp @@ -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