diff --git a/assets/model/monitor_graphics.fbx b/assets/model/monitor_graphics.fbx new file mode 100644 index 0000000..02f60fa Binary files /dev/null and b/assets/model/monitor_graphics.fbx differ diff --git a/assets/model/monitor_graphics.glb b/assets/model/monitor_graphics.glb new file mode 100644 index 0000000..b47c924 --- /dev/null +++ b/assets/model/monitor_graphics.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17ea9c5be82c4fa4149bc9dd6819a54d71b36048bf737341831f0540c6975ee0 +size 29180 diff --git a/assets/model/pump_switch_1.fbx b/assets/model/pump_switch_1.fbx index e4437bd..6f50f7c 100644 Binary files a/assets/model/pump_switch_1.fbx and b/assets/model/pump_switch_1.fbx differ diff --git a/assets/model/pump_switch_1.glb b/assets/model/pump_switch_1.glb new file mode 100644 index 0000000..1870638 --- /dev/null +++ b/assets/model/pump_switch_1.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c86341ba7eb8148f5da3d9da6dc58114be8c4265dab43b5326f2ffa92f5d77eb +size 4860 diff --git a/assets/model/pump_switch_2.fbx b/assets/model/pump_switch_2.fbx index 78d74df..c05e9d2 100644 Binary files a/assets/model/pump_switch_2.fbx and b/assets/model/pump_switch_2.fbx differ diff --git a/assets/model/pump_switch_2.glb b/assets/model/pump_switch_2.glb new file mode 100644 index 0000000..450572a --- /dev/null +++ b/assets/model/pump_switch_2.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24296922fc7584933ba599a3d511814a5b9000894765c5d3ea7de902db20ea00 +size 4860 diff --git a/assets/model/pump_switch_3.fbx b/assets/model/pump_switch_3.fbx index 97db982..3830445 100644 Binary files a/assets/model/pump_switch_3.fbx and b/assets/model/pump_switch_3.fbx differ diff --git a/assets/model/pump_switch_3.glb b/assets/model/pump_switch_3.glb new file mode 100644 index 0000000..dfe211f --- /dev/null +++ b/assets/model/pump_switch_3.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d63d8dee5acdd5b1433e661cc2e4247cc0052766c27a1ee4598dabb71cedd8f +size 4848 diff --git a/assets/model/resistor_bank_switch.fbx b/assets/model/resistor_bank_switch.fbx index 542d94a..2120830 100644 Binary files a/assets/model/resistor_bank_switch.fbx and b/assets/model/resistor_bank_switch.fbx differ diff --git a/assets/model/resistor_bank_switch.glb b/assets/model/resistor_bank_switch.glb new file mode 100644 index 0000000..f8cc7e2 --- /dev/null +++ b/assets/model/resistor_bank_switch.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8bcefa99a81875e77073f3e5393b5362b059c59e4be45fa2c390358fc6920a96 +size 4868 diff --git a/assets/model/switch.png b/assets/model/switch.png deleted file mode 100644 index 474c73f..0000000 --- a/assets/model/switch.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:df6c4c042faa33b4a41641c2b8048d2d1484326c495156096eff32cfbaeb3cc1 -size 178 diff --git a/assets/model/synchroscope_dial.fbx b/assets/model/synchroscope_dial.fbx new file mode 100644 index 0000000..5ca4a9d Binary files /dev/null and b/assets/model/synchroscope_dial.fbx differ diff --git a/assets/model/synchroscope_dial.glb b/assets/model/synchroscope_dial.glb new file mode 100644 index 0000000..586cb88 --- /dev/null +++ b/assets/model/synchroscope_dial.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2e85c91f5cb6630191ff38473356b5e84704c1bd9dd3035d17c6c5e5216c3d5 +size 4760 diff --git a/assets/model/turbine_breaker_switch.fbx b/assets/model/turbine_breaker_switch.fbx index d879dd0..e21ae15 100644 Binary files a/assets/model/turbine_breaker_switch.fbx and b/assets/model/turbine_breaker_switch.fbx differ diff --git a/assets/model/turbine_breaker_switch.glb b/assets/model/turbine_breaker_switch.glb new file mode 100644 index 0000000..1598652 --- /dev/null +++ b/assets/model/turbine_breaker_switch.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2e01b9cd7d89b1bd389e24a7d816d6b1d9e388c12ea5ec8dc886c78e76ee92b +size 4868 diff --git a/assets/model/turbine_valve_bypass_switch.fbx b/assets/model/turbine_valve_bypass_switch.fbx index fe29286..0ae2dc9 100644 Binary files a/assets/model/turbine_valve_bypass_switch.fbx and b/assets/model/turbine_valve_bypass_switch.fbx differ diff --git a/assets/model/turbine_valve_bypass_switch.glb b/assets/model/turbine_valve_bypass_switch.glb new file mode 100644 index 0000000..9a35c0e --- /dev/null +++ b/assets/model/turbine_valve_bypass_switch.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4da300e244fb9e0291bbc16c1edb5317450797b4c4641b0619c02e263899625e +size 4880 diff --git a/assets/model/turbine_valve_inlet_switch.fbx b/assets/model/turbine_valve_inlet_switch.fbx index f9a898f..17e4251 100644 Binary files a/assets/model/turbine_valve_inlet_switch.fbx and b/assets/model/turbine_valve_inlet_switch.fbx differ diff --git a/assets/model/turbine_valve_inlet_switch.glb b/assets/model/turbine_valve_inlet_switch.glb new file mode 100644 index 0000000..e3f75a3 --- /dev/null +++ b/assets/model/turbine_valve_inlet_switch.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb6ac48fcd0f6f36942f3c67f98de06818680c45597b002254f33a1c4b798e72 +size 4876 diff --git a/assets/scene-baked.glb b/assets/scene-baked.glb deleted file mode 100644 index a024ae5..0000000 --- a/assets/scene-baked.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b94d3ddd33cd3c2d90c49ace14b13ccf5ab23381191128f0041c1a362b6080a4 -size 54335664 diff --git a/assets/scene.bin b/assets/scene.bin new file mode 100644 index 0000000..252c405 Binary files /dev/null and b/assets/scene.bin differ diff --git a/assets/scene.blend b/assets/scene.blend new file mode 100644 index 0000000..13a6246 --- /dev/null +++ b/assets/scene.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b79be16adc379edf30c10a71caa2e6a83346c735731607002ed652002af8f8a9 +size 12258429 diff --git a/assets/scene.fbx b/assets/scene.fbx new file mode 100644 index 0000000..461edc4 Binary files /dev/null and b/assets/scene.fbx differ diff --git a/assets/scene.glb b/assets/scene.glb new file mode 100644 index 0000000..3e9e29f --- /dev/null +++ b/assets/scene.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e141e8c0b5a6c0453ad78c2d08fc73800fde173a36bf7d3978d4cf50f7eb2878 +size 3369136 diff --git a/assets/shader/main.fsh b/assets/shader/main.fsh index 75f2d75..cde5a8f 100644 --- a/assets/shader/main.fsh +++ b/assets/shader/main.fsh @@ -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; } diff --git a/assets/shader/main.vsh b/assets/shader/main.vsh index 20bcc4e..9131902 100644 --- a/assets/shader/main.vsh +++ b/assets/shader/main.vsh @@ -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; } diff --git a/assets/test.bin b/assets/test.bin new file mode 100644 index 0000000..abd0636 Binary files /dev/null and b/assets/test.bin differ diff --git a/assets/test.fbx b/assets/test.fbx new file mode 100644 index 0000000..2075ae9 Binary files /dev/null and b/assets/test.fbx differ diff --git a/assets/test.glb b/assets/test.glb new file mode 100644 index 0000000..9a42769 --- /dev/null +++ b/assets/test.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f83c9f4a59566dcb497c60c7470a92979eb610d09171f8f4471d5b284230d19c +size 29164 diff --git a/assets/test.gltf b/assets/test.gltf new file mode 100644 index 0000000..09cb0bd --- /dev/null +++ b/assets/test.gltf @@ -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" + } + ] +} diff --git a/assets/unbaked/AllPlants/AllPlants.mtl b/assets/texture/AllPlants/AllPlants.mtl similarity index 100% rename from assets/unbaked/AllPlants/AllPlants.mtl rename to assets/texture/AllPlants/AllPlants.mtl diff --git a/assets/unbaked/AllPlants/AllPlants.obj b/assets/texture/AllPlants/AllPlants.obj similarity index 100% rename from assets/unbaked/AllPlants/AllPlants.obj rename to assets/texture/AllPlants/AllPlants.obj diff --git a/assets/unbaked/AllPlants/PlantsLargeUV.png b/assets/texture/AllPlants/PlantsLargeUV.png similarity index 100% rename from assets/unbaked/AllPlants/PlantsLargeUV.png rename to assets/texture/AllPlants/PlantsLargeUV.png diff --git a/assets/unbaked/AllPlants/PlantsSmallUV.png b/assets/texture/AllPlants/PlantsSmallUV.png similarity index 100% rename from assets/unbaked/AllPlants/PlantsSmallUV.png rename to assets/texture/AllPlants/PlantsSmallUV.png diff --git a/assets/unbaked/scene/Keys.001.png b/assets/texture/scene/Keys.001.png similarity index 100% rename from assets/unbaked/scene/Keys.001.png rename to assets/texture/scene/Keys.001.png diff --git a/assets/unbaked/scene/SCRAM.png b/assets/texture/scene/SCRAM.png similarity index 100% rename from assets/unbaked/scene/SCRAM.png rename to assets/texture/scene/SCRAM.png diff --git a/assets/unbaked/scene/labels.png b/assets/texture/scene/labels.png similarity index 100% rename from assets/unbaked/scene/labels.png rename to assets/texture/scene/labels.png diff --git a/assets/unbaked/scene/labels.xcf b/assets/texture/scene/labels.xcf similarity index 100% rename from assets/unbaked/scene/labels.xcf rename to assets/texture/scene/labels.xcf diff --git a/assets/unbaked/scene/labels_1.png b/assets/texture/scene/labels_1.png similarity index 100% rename from assets/unbaked/scene/labels_1.png rename to assets/texture/scene/labels_1.png diff --git a/assets/unbaked/scene/labels_2.png b/assets/texture/scene/labels_2.png similarity index 100% rename from assets/unbaked/scene/labels_2.png rename to assets/texture/scene/labels_2.png diff --git a/assets/unbaked/scene/smooth+white+tile-1024x1024.png b/assets/texture/scene/smooth+white+tile-1024x1024.png similarity index 100% rename from assets/unbaked/scene/smooth+white+tile-1024x1024.png rename to assets/texture/scene/smooth+white+tile-1024x1024.png diff --git a/assets/texture/smooth_white_tile.png b/assets/texture/smooth_white_tile.png new file mode 100644 index 0000000..bfb3b89 --- /dev/null +++ b/assets/texture/smooth_white_tile.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef3c028beb4a4900098eeec2f25f8967239b7d6d2430c2b76eedcacb1f47cdcd +size 312758 diff --git a/assets/unbaked/scene.blend b/assets/unbaked/scene.blend deleted file mode 100644 index 85ebd4e..0000000 --- a/assets/unbaked/scene.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3972f0ee75b7e5f852528459dc73b69d55f6edd778ce9c0a26a6f8c09241055f -size 12573092 diff --git a/src/graphics/mesh/arrays.cpp b/src/graphics/mesh/arrays.cpp index ce943de..7dc95bc 100644 --- a/src/graphics/mesh/arrays.cpp +++ b/src/graphics/mesh/arrays.cpp @@ -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) diff --git a/src/graphics/mesh/arrays.hpp b/src/graphics/mesh/arrays.hpp index 2f7014d..a9e3aa2 100644 --- a/src/graphics/mesh/arrays.hpp +++ b/src/graphics/mesh/arrays.hpp @@ -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); diff --git a/src/graphics/mesh/font.cpp b/src/graphics/mesh/font.cpp index 06be357..5679425 100644 --- a/src/graphics/mesh/font.cpp +++ b/src/graphics/mesh/font.cpp @@ -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; diff --git a/src/graphics/mesh/light.hpp b/src/graphics/mesh/light.hpp new file mode 100644 index 0000000..49e60aa --- /dev/null +++ b/src/graphics/mesh/light.hpp @@ -0,0 +1,25 @@ + +#pragma once + +#include + +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)); + +}; + diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/mesh/mesh.cpp index 8a4c031..43ea840 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/mesh/mesh.cpp @@ -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(); diff --git a/src/graphics/mesh/mesh.hpp b/src/graphics/mesh/mesh.hpp index e3f9d2e..513df1d 100644 --- a/src/graphics/mesh/mesh.hpp +++ b/src/graphics/mesh/mesh.hpp @@ -3,30 +3,34 @@ #include #include +#include +#include #include #include #include "arrays.hpp" - +#include "light.hpp" namespace Sim::Graphics { struct Mesh { + std::unordered_map mat_nodes; std::vector vertices; std::vector indices; + std::vector 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; diff --git a/src/graphics/mesh/model.cpp b/src/graphics/mesh/model.cpp index e0c6074..ae34442 100644 --- a/src/graphics/mesh/model.cpp +++ b/src/graphics/mesh/model.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -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 lights; std::vector vertices; std::vector indices; std::unordered_map handles; + std::unordered_map 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); } diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index 2c32b26..f2d88bc 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -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; diff --git a/src/graphics/monitor/primary_loop.cpp b/src/graphics/monitor/primary_loop.cpp index 59727e2..1dc7763 100644 --- a/src/graphics/monitor/primary_loop.cpp +++ b/src/graphics/monitor/primary_loop.cpp @@ -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); diff --git a/src/graphics/monitor/secondary_loop.cpp b/src/graphics/monitor/secondary_loop.cpp index 3d979e3..cd258c8 100644 --- a/src/graphics/monitor/secondary_loop.cpp +++ b/src/graphics/monitor/secondary_loop.cpp @@ -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); diff --git a/src/graphics/monitor/turbine.cpp b/src/graphics/monitor/turbine.cpp index 5de45d0..dde4c03 100644 --- a/src/graphics/monitor/turbine.cpp +++ b/src/graphics/monitor/turbine.cpp @@ -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); diff --git a/src/graphics/ui.cpp b/src/graphics/ui.cpp index 62aee5d..22885e1 100644 --- a/src/graphics/ui.cpp +++ b/src/graphics/ui.cpp @@ -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) diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 2b65def..1b3d11c 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -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);