improved lighting engine :)
This commit is contained in:
parent
86c01377e5
commit
7ae018aafc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/model/switch.png (Stored with Git LFS)
BIN
assets/model/switch.png (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/scene-baked.glb (Stored with Git LFS)
BIN
assets/scene-baked.glb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -2,20 +2,131 @@
|
|||
#version 460 core
|
||||
#extension GL_ARB_bindless_texture : require
|
||||
|
||||
in vec4 colour;
|
||||
in flat sampler2D tex;
|
||||
in vec2 texPos;
|
||||
const float PI = 3.141592;
|
||||
const float Epsilon = 0.00001;
|
||||
|
||||
out vec4 FragColour;
|
||||
// Constant normal incidence Fresnel factor for all dielectrics.
|
||||
const vec3 Fdielectric = vec3(0.04);
|
||||
|
||||
in VS_OUT {
|
||||
vec3 normal;
|
||||
vec4 colour;
|
||||
vec3 pos;
|
||||
vec2 tex_pos;
|
||||
vec3 material;
|
||||
} vin;
|
||||
|
||||
struct Light
|
||||
{
|
||||
vec4 pos;
|
||||
vec4 colour;
|
||||
};
|
||||
|
||||
layout(std140, binding = 1) buffer ssbo_lights
|
||||
{
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
in flat sampler2D frag_tex;
|
||||
out vec4 frag_colour;
|
||||
|
||||
uniform mat4 tex_mat;
|
||||
uniform vec3 brightness;
|
||||
uniform vec3 camera_pos;
|
||||
|
||||
uniform int lights_count;
|
||||
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
float a2 = a*a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH*NdotH;
|
||||
|
||||
float num = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
{
|
||||
float r = (roughness + 1.0);
|
||||
float k = (r*r) / 8.0;
|
||||
|
||||
float num = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
{
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texdata = texture2D(tex, texPos);
|
||||
FragColour = tex_mat * texdata * colour * vec4(brightness, 1);
|
||||
vec4 albedo = (tex_mat * texture2D(frag_tex, vin.tex_pos)) * vin.colour;
|
||||
|
||||
float roughness = vin.material[0];
|
||||
float metalness = vin.material[1];
|
||||
float luminance = min(vin.material[2], 1.f);
|
||||
|
||||
if(FragColour.a == 0) discard;
|
||||
vec3 N = normalize(vin.normal);
|
||||
vec3 V = normalize(camera_pos - vin.pos.xyz);
|
||||
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo.rgb, metalness);
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
for(int i = 0; i < lights_count; i++)
|
||||
{
|
||||
Light l = lights[i];
|
||||
|
||||
vec3 L = normalize(l.pos.xyz - vin.pos);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float d = length(vin.pos - l.pos.xyz);
|
||||
float atten = 1.f / (d*d);
|
||||
vec3 radiance = l.colour.rgb * atten;
|
||||
|
||||
// cook-torrance brdf
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = vec3(1.0) - kS;
|
||||
kD *= 1.0 - metalness;
|
||||
|
||||
vec3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;
|
||||
vec3 specular = numerator / denominator;
|
||||
|
||||
// add to outgoing radiance Lo
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo.rgb / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
vec3 ambient = vec3(0.03f) * albedo.rgb * brightness;
|
||||
vec3 light = ambient + Lo;
|
||||
|
||||
light = light / (light + vec3(1.f));
|
||||
light = pow(light, vec3(1.f/2.2f));
|
||||
light = light * (1 - luminance) + albedo.rgb * luminance;
|
||||
frag_colour = vec4(light, albedo.a);
|
||||
|
||||
if(frag_colour.a == 0.f) discard;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,25 +7,34 @@ layout (location = 1) in vec2 aTexPos;
|
|||
layout (location = 2) in vec4 aPos;
|
||||
layout (location = 3) in vec3 aNormal;
|
||||
layout (location = 4) in vec4 aColour;
|
||||
layout (location = 5) in vec3 aMaterial;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 camera;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec4 colour;
|
||||
out flat sampler2D tex;
|
||||
out vec2 texPos;
|
||||
out VS_OUT {
|
||||
vec3 normal;
|
||||
vec4 colour;
|
||||
vec3 pos;
|
||||
vec2 tex_pos;
|
||||
vec3 material;
|
||||
} vout;
|
||||
|
||||
out flat sampler2D frag_tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = camera * model * aPos;
|
||||
mat4 mvp = camera * model;
|
||||
vec4 pos = mvp * aPos;
|
||||
|
||||
// vec3 cNormal = vec3(0.f, 0.f, 1.f) * mat3(camera * model);
|
||||
// float brightness = dot(normalize(aNormal), normalize(cNormal)) * 0.25f + 0.75f;
|
||||
|
||||
colour = aColour;// * vec4(vec3(brightness), 1);
|
||||
vout.normal = mat3(model) * aNormal;
|
||||
vout.pos = (model * aPos).xyz;
|
||||
vout.colour = aColour;
|
||||
vout.tex_pos = aTexPos;
|
||||
vout.material = aMaterial;
|
||||
frag_tex = aTex;
|
||||
|
||||
gl_Position = projection * pos;
|
||||
texPos = aTexPos;
|
||||
tex = aTex;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,382 @@
|
|||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v4.0.44",
|
||||
"version":"2.0"
|
||||
},
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"extras":{
|
||||
"SimpleBake_Props":{},
|
||||
"bake_to_vertex_color_props":{}
|
||||
},
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"Cylinder",
|
||||
"translation":[
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh":1,
|
||||
"name":"Cylinder.001",
|
||||
"translation":[
|
||||
1,
|
||||
0,
|
||||
0.5
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh":2,
|
||||
"name":"Cylinder.002",
|
||||
"translation":[
|
||||
3,
|
||||
0,
|
||||
0.5
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh":3,
|
||||
"name":"Cylinder.003",
|
||||
"translation":[
|
||||
2,
|
||||
0,
|
||||
0.5
|
||||
]
|
||||
}
|
||||
],
|
||||
"materials":[
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Material.006",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.75
|
||||
}
|
||||
},
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Material.005",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Material.003",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.125
|
||||
}
|
||||
},
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Material.004",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.25
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"Cylinder",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"NORMAL":1,
|
||||
"TEXCOORD_0":2
|
||||
},
|
||||
"indices":3,
|
||||
"material":0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"Cylinder.001",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":4,
|
||||
"NORMAL":5,
|
||||
"TEXCOORD_0":6
|
||||
},
|
||||
"indices":3,
|
||||
"material":1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"Cylinder.002",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":7,
|
||||
"NORMAL":8,
|
||||
"TEXCOORD_0":9
|
||||
},
|
||||
"indices":3,
|
||||
"material":2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"Cylinder.003",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":10,
|
||||
"NORMAL":11,
|
||||
"TEXCOORD_0":12
|
||||
},
|
||||
"indices":3,
|
||||
"material":3
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"max":[
|
||||
0.20000000298023224,
|
||||
0.20000000298023224,
|
||||
0.5
|
||||
],
|
||||
"min":[
|
||||
-0.20000000298023224,
|
||||
-0.20000000298023224,
|
||||
-0.5
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"componentType":5123,
|
||||
"count":372,
|
||||
"type":"SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView":4,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"max":[
|
||||
0.20000000298023224,
|
||||
0.20000000298023224,
|
||||
0.5
|
||||
],
|
||||
"min":[
|
||||
-0.20000000298023224,
|
||||
-0.20000000298023224,
|
||||
-0.5
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":5,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":6,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":7,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"max":[
|
||||
0.20000000298023224,
|
||||
0.20000000298023224,
|
||||
0.5
|
||||
],
|
||||
"min":[
|
||||
-0.20000000298023224,
|
||||
-0.20000000298023224,
|
||||
-0.5
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":8,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":9,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":10,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"max":[
|
||||
0.20000000298023224,
|
||||
0.20000000298023224,
|
||||
0.5
|
||||
],
|
||||
"min":[
|
||||
-0.20000000298023224,
|
||||
-0.20000000298023224,
|
||||
-0.5
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":11,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":12,
|
||||
"componentType":5126,
|
||||
"count":192,
|
||||
"type":"VEC2"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":2304,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":1536,
|
||||
"byteOffset":4608,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":744,
|
||||
"byteOffset":6144,
|
||||
"target":34963
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":6888,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":9192,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":1536,
|
||||
"byteOffset":11496,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":13032,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":15336,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":1536,
|
||||
"byteOffset":17640,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":19176,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2304,
|
||||
"byteOffset":21480,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":1536,
|
||||
"byteOffset":23784,
|
||||
"target":34962
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":25320,
|
||||
"uri":"test.bin"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
BIN
assets/unbaked/scene.blend (Stored with Git LFS)
BIN
assets/unbaked/scene.blend (Stored with Git LFS)
Binary file not shown.
|
@ -30,9 +30,12 @@ void Arrays::vertex_attrib_pointers()
|
|||
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.normal, &v));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, false, sizeof(v), ptr_diff(&v.colour, &v));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glVertexAttribPointer(5, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.material, &v));
|
||||
glEnableVertexAttribArray(5);
|
||||
}
|
||||
|
||||
glm::mat4 Arrays::colour(glm::vec4 c)
|
||||
|
|
|
@ -13,7 +13,8 @@ struct Vertex
|
|||
glm::vec4 pos = {0, 0, 0, 1};
|
||||
glm::vec3 normal = {0, 0, 0};
|
||||
glm::vec4 colour = {1, 1, 1, 1};
|
||||
};
|
||||
glm::vec3 material = {0, 0, 0};
|
||||
} __attribute__((packed));
|
||||
|
||||
void vertex_attrib_pointers();
|
||||
glm::mat4 colour(glm::vec4 code);
|
||||
|
|
|
@ -136,10 +136,10 @@ void 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(ch.handle, {0, 0}, {sx, sy, 0, 1}, {0, 0, -1}));
|
||||
vertices.push_back(Arrays::Vertex(ch.handle, {0, 1}, {sx, ey, 0, 1}, {0, 0, -1}));
|
||||
vertices.push_back(Arrays::Vertex(ch.handle, {1, 0}, {ex, sy, 0, 1}, {0, 0, -1}));
|
||||
vertices.push_back(Arrays::Vertex(ch.handle, {1, 1}, {ex, ey, 0, 1}, {0, 0, -1}));
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 0}, .pos={sx, sy, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 1}, .pos={sx, ey, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 0}, .pos={ex, sy, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 1}, .pos={ex, ey, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}});
|
||||
indices.insert(indices.end(), &index[0], &index[6]);
|
||||
|
||||
at += 4;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <glm/matrix.hpp>
|
||||
|
||||
namespace Sim::Graphics
|
||||
{
|
||||
|
||||
struct Light
|
||||
{
|
||||
constexpr Light(glm::vec3 pos, glm::vec3 colour) :
|
||||
pos(pos), colour(colour)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
glm::vec3 pos;
|
||||
float padding1;
|
||||
glm::vec3 colour;
|
||||
float padding2;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
};
|
||||
|
|
@ -10,6 +10,11 @@
|
|||
|
||||
using namespace Sim::Graphics;
|
||||
|
||||
Mesh::Mesh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Mesh::add(const Mesh& o, glm::mat4 mat)
|
||||
{
|
||||
unsigned int off = vertices.size();
|
||||
|
@ -32,6 +37,11 @@ void Mesh::add(const Mesh& o, glm::mat4 mat)
|
|||
}
|
||||
}
|
||||
|
||||
void Mesh::add(const Mesh& o)
|
||||
{
|
||||
add(o, glm::mat4(1));
|
||||
}
|
||||
|
||||
void Mesh::set_vertices(const Arrays::Vertex* data, size_t size)
|
||||
{
|
||||
vertices.clear();
|
||||
|
|
|
@ -3,30 +3,34 @@
|
|||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/matrix.hpp>
|
||||
|
||||
#include "arrays.hpp"
|
||||
|
||||
#include "light.hpp"
|
||||
|
||||
namespace Sim::Graphics
|
||||
{
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
std::unordered_map<std::string, glm::mat4> mat_nodes;
|
||||
std::vector<Arrays::Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<Light> lights;
|
||||
|
||||
constexpr Mesh() { }
|
||||
Mesh();
|
||||
|
||||
void set_vertices(const Arrays::Vertex* data, size_t size);
|
||||
void set_indices(const unsigned int* data, size_t size);
|
||||
void load_model(std::string base, std::string path);
|
||||
void load_model(std::string path) { load_model(".", path); }
|
||||
void load_model(std::string path);
|
||||
void load_text(const char* text, double size);
|
||||
void add(const Mesh& o, glm::mat4 mat);
|
||||
void add(const Mesh& o) { add(o, glm::mat4(1)); }
|
||||
void add(const Mesh& o);
|
||||
|
||||
Mesh to_lines() const;
|
||||
bool check_focus() const;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <assimp/material.h>
|
||||
#include <glm/matrix.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
@ -14,6 +15,7 @@
|
|||
#include "mesh.hpp"
|
||||
#include "arrays.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "../../util/streams.hpp"
|
||||
|
||||
using namespace Sim::Graphics;
|
||||
|
||||
|
@ -22,49 +24,114 @@ struct ProcState
|
|||
unsigned int offset = 0;
|
||||
|
||||
std::string base;
|
||||
std::vector<Light> lights;
|
||||
std::vector<Arrays::Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::unordered_map<const aiTexture*, unsigned int> handles;
|
||||
std::unordered_map<std::string, glm::mat4> mat_nodes;
|
||||
};
|
||||
|
||||
static unsigned int proc_texture(const ProcState& state, aiMaterial* mat, const aiScene* scene)
|
||||
static unsigned int proc_texture(const ProcState& state, aiMaterial* mat, const aiScene* scene, aiTextureType type, int index)
|
||||
{
|
||||
for(int i = 0; i < 0x0d; i++)
|
||||
aiString str;
|
||||
mat->GetTexture(type, index, &str);
|
||||
|
||||
if(str.C_Str()[0] == '\0')
|
||||
{
|
||||
aiTextureType type = (aiTextureType)i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const aiTexture* tex = scene->GetEmbeddedTexture(str.C_Str());
|
||||
|
||||
if(mat->GetTextureCount(type) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aiString str;
|
||||
mat->GetTexture(type, 0, &str);
|
||||
|
||||
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);
|
||||
if(tex != nullptr)
|
||||
{
|
||||
unsigned int handle = state.handles.find(tex)->second;
|
||||
std::cout << "Using preloaded texture: " << tex->mFilename.C_Str() << "\n";
|
||||
return handle;
|
||||
}
|
||||
|
||||
return Texture::handle_white;
|
||||
std::string filename(str.C_Str());
|
||||
std::replace(filename.begin(), filename.end(), '\\', '/');
|
||||
|
||||
return Texture::load(state.base + "/" + filename);
|
||||
}
|
||||
|
||||
static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiScene* scene)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
unsigned int handle = proc_texture(state, material, scene);
|
||||
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;
|
||||
}
|
||||
|
||||
std::cout << "Material: " << matv << "\n";
|
||||
|
||||
unsigned int handle = proc_texture(state, material, scene, aiTextureType_BASE_COLOR, 0);
|
||||
unsigned int offset = state.offset;
|
||||
glm::mat3 mat3(mat);
|
||||
|
||||
if(!handle)
|
||||
{
|
||||
handle = proc_texture(state, material, scene, aiTextureType_DIFFUSE, 0);
|
||||
}
|
||||
|
||||
if(!handle)
|
||||
{
|
||||
handle = Texture::handle_white;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
|
@ -72,13 +139,23 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce
|
|||
|
||||
auto [x, y, z] = mesh->mVertices[i];
|
||||
vertex.pos = glm::vec4(x, y, z, 1) * mat;
|
||||
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) * mat3;
|
||||
}
|
||||
|
||||
/*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])
|
||||
{
|
||||
|
@ -102,15 +179,21 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce
|
|||
state.offset += mesh->mNumVertices;
|
||||
}
|
||||
|
||||
static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiScene* scene)
|
||||
glm::mat4 get_mat(aiMatrix4x4 m)
|
||||
{
|
||||
auto m = node->mTransformation;
|
||||
mat = glm::mat4(
|
||||
return {
|
||||
m.a1, m.a2, m.a3, m.a4,
|
||||
m.b1, m.b2, m.b3, m.b4,
|
||||
m.c1, m.c2, m.c3, m.c4,
|
||||
m.d1, m.d2, m.d3, m.d4
|
||||
) * mat;
|
||||
};
|
||||
}
|
||||
|
||||
static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiScene* scene)
|
||||
{
|
||||
mat = get_mat(node->mTransformation) * mat;
|
||||
std::string name(node->mName.C_Str());
|
||||
state.mat_nodes[name] = mat;
|
||||
|
||||
for(size_t i = 0; i < node->mNumMeshes; i++)
|
||||
{
|
||||
|
@ -143,6 +226,24 @@ static unsigned int proc_embedded_texture(aiTexture* tex)
|
|||
return Texture::load_mem((unsigned char*)tex->pcData, tex->mWidth, tex->mHeight, 4);
|
||||
}
|
||||
|
||||
glm::mat4 get_transforms(aiNode* node)
|
||||
{
|
||||
glm::mat4 mat(1);
|
||||
|
||||
while(node->mParent != nullptr)
|
||||
{
|
||||
mat *= get_mat(node->mTransformation);
|
||||
node = node->mParent;
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
void Mesh::load_model(std::string path)
|
||||
{
|
||||
load_model(".", path);
|
||||
}
|
||||
|
||||
void Mesh::load_model(std::string base, std::string filename)
|
||||
{
|
||||
ProcState state {.base = base};
|
||||
|
@ -164,9 +265,27 @@ void Mesh::load_model(std::string base, std::string filename)
|
|||
state.handles[tex] = handle;
|
||||
}
|
||||
|
||||
for(int i = 0; i < scene->mNumLights; i++)
|
||||
{
|
||||
aiLight* light = scene->mLights[i];
|
||||
glm::mat4 mat = get_transforms(scene->mRootNode->FindNode(light->mName));
|
||||
|
||||
auto [x, y, z] = light->mPosition;
|
||||
auto [r, g, b] = light->mColorDiffuse;
|
||||
|
||||
glm::vec4 pos = glm::vec4(x, y, z, 1) * mat;
|
||||
|
||||
state.lights.push_back({
|
||||
glm::vec3(pos),
|
||||
{r, g, b},
|
||||
});
|
||||
}
|
||||
|
||||
proc_node(state, glm::mat4(1), scene->mRootNode, scene);
|
||||
|
||||
set_vertices(&state.vertices[0], state.vertices.size());
|
||||
set_indices(&state.indices[0], state.indices.size());
|
||||
mat_nodes = std::move(state.mat_nodes);
|
||||
vertices = std::move(state.vertices);
|
||||
indices = std::move(state.indices);
|
||||
lights = std::move(state.lights);
|
||||
}
|
||||
|
||||
|
|
|
@ -152,10 +152,10 @@ static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour)
|
|||
{
|
||||
unsigned int indices[] = {0, 1, 3, 0, 3, 2};
|
||||
Arrays::Vertex vertices[] = {
|
||||
{Texture::handle_white, {0, 0}, model_mat * glm::vec4(-0.75, -0.75, 0, 1), {0, 0, -1}, colour},
|
||||
{Texture::handle_white, {0, 1}, model_mat * glm::vec4(-0.75, 0.75, 0, 1), {0, 0, -1}, colour},
|
||||
{Texture::handle_white, {1, 0}, model_mat * glm::vec4( 0.75, -0.75, 0, 1), {0, 0, -1}, colour},
|
||||
{Texture::handle_white, {1, 1}, model_mat * glm::vec4( 0.75, 0.75, 0, 1), {0, 0, -1}, colour},
|
||||
{.texid=Texture::handle_white, .texpos={0, 0}, .pos=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=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=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=model_mat * glm::vec4( 0.75, 0.75, 0, 1), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}},
|
||||
};
|
||||
|
||||
Mesh mesh;
|
||||
|
|
|
@ -86,15 +86,15 @@ void PrimaryLoop::init()
|
|||
mesh1.bind();
|
||||
mesh1.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "pump_switch_1.fbx");
|
||||
rmesh.load_model("../assets/model", "pump_switch_1.glb");
|
||||
gm_switch_pump.bind();
|
||||
gm_switch_pump.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "turbine_valve_bypass_switch.fbx");
|
||||
rmesh.load_model("../assets/model", "turbine_valve_bypass_switch.glb");
|
||||
gm_switch_bypass.bind();
|
||||
gm_switch_bypass.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "turbine_valve_inlet_switch.fbx");
|
||||
rmesh.load_model("../assets/model", "turbine_valve_inlet_switch.glb");
|
||||
gm_switch_inlet.bind();
|
||||
gm_switch_inlet.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
|
|
|
@ -47,11 +47,11 @@ void SecondaryLoop::init()
|
|||
mesh1.bind();
|
||||
mesh1.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "pump_switch_2.fbx");
|
||||
rmesh.load_model("../assets/model", "pump_switch_2.glb");
|
||||
gm_switch_2.bind();
|
||||
gm_switch_2.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "pump_switch_3.fbx");
|
||||
rmesh.load_model("../assets/model", "pump_switch_3.glb");
|
||||
gm_switch_3.bind();
|
||||
gm_switch_3.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ void Turbine::init()
|
|||
gm_synchroscope_dial.bind();
|
||||
gm_synchroscope_dial.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
rmesh.load_model("../assets/model", "turbine_breaker_switch.fbx");
|
||||
rmesh.load_model("../assets/model", "turbine_breaker_switch.glb");
|
||||
gm_switch_breaker.bind();
|
||||
gm_switch_breaker.set(rmesh, GL_STATIC_DRAW);
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ void UI::init()
|
|||
unsigned int handle = Texture::handle_white;
|
||||
const unsigned int indices[] = {0, 1, 3, 0, 3, 2};
|
||||
const Arrays::Vertex vertices[] = {
|
||||
Arrays::Vertex(handle, {0, 0}, {-1, -1, 0, 1}, {0, 0, -1}),
|
||||
Arrays::Vertex(handle, {0, 1}, {-1, 1, 0, 1}, {0, 0, -1}),
|
||||
Arrays::Vertex(handle, {1, 0}, { 1, -1, 0, 1}, {0, 0, -1}),
|
||||
Arrays::Vertex(handle, {1, 1}, { 1, 1, 0, 1}, {0, 0, -1}),
|
||||
{.texid=handle, .texpos={0, 0}, .pos={-1, -1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
{.texid=handle, .texpos={0, 1}, .pos={-1, 1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
{.texid=handle, .texpos={1, 0}, .pos={ 1, -1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
{.texid=handle, .texpos={1, 1}, .pos={ 1, 1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
|
||||
};
|
||||
|
||||
m.set_indices(indices, 6);
|
||||
|
@ -39,7 +39,6 @@ void UI::init()
|
|||
|
||||
s_mesh.bind();
|
||||
s_mesh.set(m, GL_STATIC_DRAW);
|
||||
s_mesh.colour_matrix = glm::scale(glm::mat4(1), glm::vec3(1) * 0.75f);
|
||||
}
|
||||
|
||||
void UI::update(double dt)
|
||||
|
|
|
@ -26,12 +26,14 @@
|
|||
#include "monitor/turbine.hpp"
|
||||
#include "mesh/texture.hpp"
|
||||
#include "../system.hpp"
|
||||
#include "../util/streams.hpp"
|
||||
#include "ui.hpp"
|
||||
|
||||
using namespace Sim::Graphics;
|
||||
|
||||
static GLFWwindow* win;
|
||||
static bool win_should_close = false;
|
||||
static unsigned int ssbo_lights;
|
||||
|
||||
static GLMesh mesh_scene;
|
||||
|
||||
|
@ -110,14 +112,13 @@ void Window::create()
|
|||
Font::init();
|
||||
UI::init();
|
||||
|
||||
Shader::BLUR.load("../assets/shader", "blur.vsh", "blur.fsh");
|
||||
Shader::MAIN.load("../assets/shader", "main.vsh", "main.fsh");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
Sim::System& sys = *System::active;
|
||||
Mesh m, m2;
|
||||
|
||||
m.load_model("../assets", "scene-baked.glb");
|
||||
m.load_model("../assets", "scene.glb");
|
||||
|
||||
// find the floor parts of the model and set them slightly transparent
|
||||
for(int i = 0; i < m.indices.size(); i += 3)
|
||||
|
@ -134,8 +135,21 @@ void Window::create()
|
|||
}
|
||||
}
|
||||
|
||||
m2.load_model("../assets/model", "monitor_graphics.stl");
|
||||
m.add(m2, glm::mat4(1));
|
||||
for(Light& light : m.lights)
|
||||
{
|
||||
std::cout << "Sent light: " << light.pos << " with " << light.colour << "\n";
|
||||
}
|
||||
|
||||
std::cout << "Light struct is " << sizeof(m.lights[0]) << " bytes\n";
|
||||
|
||||
// send all the light data
|
||||
glGenBuffers(1, &ssbo_lights);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_lights);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, m.lights.size() * sizeof(m.lights[0]), &m.lights[0], GL_STATIC_DRAW);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo_lights);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||
|
||||
glUniform1i(Shader::MAIN["lights_count"], m.lights.size());
|
||||
|
||||
mesh_scene.bind();
|
||||
mesh_scene.set(m, GL_STATIC_DRAW);
|
||||
|
@ -180,14 +194,17 @@ void render_scene()
|
|||
|
||||
void Window::render()
|
||||
{
|
||||
glm::vec3 camera_pos = Camera::get_pos();
|
||||
glm::mat4 mat_camera = Camera::get_matrix();
|
||||
mat_camera = glm::scale(mat_camera, {1, 1, -1});
|
||||
camera_pos.z *= -1;
|
||||
|
||||
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, 20.f);
|
||||
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]);
|
||||
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]);
|
||||
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
|
||||
glUniform3fv(Shader::MAIN["camera_pos"], 1, &camera_pos[0]);
|
||||
projection_matrix = mat_projection;
|
||||
|
||||
glClearColor(0, 0, 0, 1.0f);
|
||||
|
@ -196,8 +213,10 @@ void Window::render()
|
|||
|
||||
render_scene();
|
||||
|
||||
camera_pos.z *= -1;
|
||||
mat_camera = Camera::get_matrix();
|
||||
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]);
|
||||
glUniform3fv(Shader::MAIN["camera_pos"], 1, &camera_pos[0]);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
|
|
Loading…
Reference in New Issue