Compare commits

..

No commits in common. "1a3c72685b1c1571648c6d019ca6b79e099432d5" and "95dd2cc2f91eeb7b85d5752f0465d226c78c9b89" have entirely different histories.

97 changed files with 1227 additions and 1122 deletions

2
.gitattributes vendored
View File

@ -1,2 +1,4 @@
*.png filter=lfs diff=lfs merge=lfs -text
*.stl filter=lfs diff=lfs merge=lfs -text
*.glb filter=lfs diff=lfs merge=lfs -text *.glb filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text *.blend filter=lfs diff=lfs merge=lfs -text

Binary file not shown.

BIN
assets/model/monitor_graphics.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/monitor_graphics.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/monitor_turbine.stl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/pump_switch_1.glb (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/pump_switch_2.glb (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/pump_switch_3.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/pump_switch_click_1.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/pump_switch_click_2.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/pump_switch_click_3.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button1.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button2.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button3.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button4.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button5.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button6.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button7.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button8.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_button9.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_input.stl (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
linear_extrude(0.0001)
square([1, 1], center = true);

BIN
assets/model/reactor_core_interface_cell.stl (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,10 @@
$fn = 256;
linear_extrude(0.0001)
translate([0.5, 0.5])
difference()
{
circle(d = 0.81);
circle(d = 0.8);
}

BIN
assets/model/reactor_core_interface_circle.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_joystick.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/reactor_core_scram.stl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/resistor_bank_switch.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/resistor_bank_switch_click.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/scene_collisions.stl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/synchroscope_dial.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/synchroscope_dial.stl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/turbine_breaker_switch.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/turbine_breaker_switch_click.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/turbine_valve_bypass_joystick.stl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/turbine_valve_bypass_switch.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/turbine_valve_bypass_switch_click.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/turbine_valve_inlet_joystick.stl (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/model/turbine_valve_inlet_switch.glb (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/model/turbine_valve_inlet_switch_click.stl (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/scene.bin Normal file

Binary file not shown.

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

Binary file not shown.

BIN
assets/scene.fbx Normal file

Binary file not shown.

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

Binary file not shown.

View File

@ -1,13 +0,0 @@
#version 460 core
in vec3 frag_pos;
uniform float far_plane;
void main()
{
float distance = length(frag_pos);
gl_FragDepth = distance / far_plane;
}

View File

@ -1,33 +0,0 @@
#version 460 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;
uniform mat4 shadow_mats[6];
in float emissive[];
in float base_transparency[];
out vec3 frag_pos;
void main()
{
if(emissive[0] > 0 || base_transparency[0] > 0) return;
for(int i = 0; i < 6; i++)
{
gl_Layer = i;
for(int j = 0; j < 3; j++)
{
vec4 fp = gl_in[j].gl_Position;
gl_Position = shadow_mats[i] * fp;
frag_pos = fp.xyz;
EmitVertex();
}
EndPrimitive();
}
}

View File

@ -1,20 +0,0 @@
#version 460 core
layout (location = 2) in vec4 aPos;
layout (location = 4) in vec4 aColour;
layout (location = 5) in vec3 aMaterial;
uniform mat4 model;
uniform mat4 camera;
out float emissive;
out float base_transparency;
void main()
{
gl_Position = camera * model * aPos;
base_transparency = 1.f - aColour.a;
emissive = aMaterial[2];
}

View File

@ -2,7 +2,11 @@
#version 460 core #version 460 core
#extension GL_ARB_bindless_texture : require #extension GL_ARB_bindless_texture : require
const float PI = 3.141592f; const float PI = 3.141592;
const float Epsilon = 0.00001;
// Constant normal incidence Fresnel factor for all dielectrics.
const vec3 Fdielectric = vec3(0.04);
in VS_OUT { in VS_OUT {
vec3 normal; vec3 normal;
@ -23,84 +27,57 @@ layout(std140, binding = 1) buffer ssbo_lights
Light lights[]; Light lights[];
}; };
layout(std430, binding = 2) buffer ssbo_shadow_maps
{
samplerCube shadow_maps[];
};
in flat sampler2D frag_tex; in flat sampler2D frag_tex;
out vec4 frag_colour; out vec4 frag_colour;
uniform mat4 tex_mat;
uniform vec3 brightness; uniform vec3 brightness;
uniform vec3 camera_pos; uniform vec3 camera_pos;
uniform int lights_count;
uniform float far_plane;
uniform bool shadows_enabled;
vec3 FresnelSchlick(float cosTheta, vec3 F0) uniform int lights_count;
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{ {
return F0 + (1.f - F0) * pow(clamp(1.f - cosTheta, 0.f, 1.f), 5.f); 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 DistributionGGX(vec3 N, vec3 H, float roughness)
{ {
float a = roughness*roughness; float a = roughness*roughness;
float a2 = a*a; float a2 = a*a;
float NdotH = max(dot(N, H), 0.f); float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH; float NdotH2 = NdotH*NdotH;
float num = a2; float num = a2;
float denom = (NdotH2 * (a2 - 1.f) + 1.f); float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom; denom = PI * denom * denom;
return num / denom; return num / denom;
} }
float GeometrySchlickGGX(float NdotV, float roughness) float GeometrySchlickGGX(float NdotV, float roughness)
{ {
float r = (roughness + 1.f); float r = (roughness + 1.0);
float k = (r*r) / 8.f; float k = (r*r) / 8.0;
float num = NdotV; float num = NdotV;
float denom = NdotV * (1.f - k) + k; float denom = NdotV * (1.0 - k) + k;
return num / denom; return num / denom;
} }
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{ {
float NdotV = max(dot(N, V), 0.f); float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.f); float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness); float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness); float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1 * ggx2; return ggx1 * ggx2;
}
vec3 LinRGB_To_sRGB(vec3 c)
{
bvec3 th = lessThan(c, vec3(0.0031308f));
vec3 high = pow(c, vec3(1.0f / 2.4f)) * vec3(1.055f) - vec3(0.055f);
vec3 low = c * vec3(12.92f);
return mix(high, low, th);
}
vec3 sRGB_To_LinRGB(vec3 c)
{
bvec3 th = lessThan(c, vec3(0.04045f));
vec3 high = pow((c + vec3(0.055f)) * vec3(1.0f / 1.055f), vec3(2.4f));
vec3 low = c * vec3(1.0f / 12.92f);
return mix(high, low, th);
} }
void main() void main()
{ {
vec4 albedo = texture2D(frag_tex, vin.tex_pos) * vin.colour; vec4 albedo = (tex_mat * texture2D(frag_tex, vin.tex_pos)) * vin.colour;
if(albedo.a == 0.f) discard;
vec3 albedo_lin = sRGB_To_LinRGB(albedo.rgb);
float roughness = vin.material[0]; float roughness = vin.material[0];
float metalness = vin.material[1]; float metalness = vin.material[1];
@ -109,10 +86,10 @@ void main()
vec3 N = normalize(vin.normal); vec3 N = normalize(vin.normal);
vec3 V = normalize(camera_pos - vin.pos.xyz); vec3 V = normalize(camera_pos - vin.pos.xyz);
vec3 F0 = vec3(0.04f); vec3 F0 = vec3(0.04);
F0 = mix(F0, albedo_lin, metalness); F0 = mix(F0, albedo.rgb, metalness);
vec3 Lo = vec3(0.0f); vec3 Lo = vec3(0.0);
for(int i = 0; i < lights_count; i++) for(int i = 0; i < lights_count; i++)
{ {
Light l = lights[i]; Light l = lights[i];
@ -125,44 +102,31 @@ void main()
vec3 radiance = l.colour.rgb * atten; vec3 radiance = l.colour.rgb * atten;
// cook-torrance brdf // cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness); float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness); float G = GeometrySmith(N, V, L, roughness);
vec3 F = FresnelSchlick(max(dot(H, V), 0.f), F0); vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
vec3 kS = F; vec3 kS = F;
vec3 kD = vec3(1.f) - kS; vec3 kD = vec3(1.0) - kS;
kD *= 1.f - metalness; kD *= 1.0 - metalness;
vec3 numerator = NDF * G * F; vec3 numerator = NDF * G * F;
float denominator = 4.f * max(dot(N, V), 0.f) * max(dot(N, L), 0.f) + 1e-4f; float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;
vec3 specular = numerator / denominator; vec3 specular = numerator / denominator;
float light_m; // add to outgoing radiance Lo
float spec_m; float NdotL = max(dot(N, L), 0.0);
Lo += (kD * albedo.rgb / PI + specular) * radiance * NdotL;
if(shadows_enabled)
{
float max_d = texture(shadow_maps[i], -L).r * far_plane + 1e-2f;
spec_m = max_d > d ? 1.f : 0.f;
light_m = spec_m * 0.25f + 0.75f;
}
else
{
light_m = 1.f;
spec_m = 1.f;
}
// add to outgoing radiance Lo
float NdotL = max(dot(N, L), 0.f);
Lo += (kD * albedo_lin / PI + specular * spec_m) * radiance * NdotL * light_m;
} }
vec3 ambient = vec3(0.03f) * albedo_lin * brightness; vec3 ambient = vec3(0.03f) * albedo.rgb * brightness;
vec3 light = LinRGB_To_sRGB(ambient + Lo); vec3 light = ambient + Lo;
light = mix(light, albedo.rgb, luminance); 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); frag_colour = vec4(light, albedo.a);
if(frag_colour.a == 0.f) discard;
} }

BIN
assets/test.bin Normal file

Binary file not shown.

BIN
assets/test.fbx Normal file

Binary file not shown.

BIN
assets/test.glb (Stored with Git LFS) Normal file

Binary file not shown.

382
assets/test.gltf Normal file
View File

@ -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"
}
]
}

View File

@ -79,9 +79,9 @@ glm::vec<3, double> Camera::get_pos()
return pos; return pos;
} }
void Camera::init(const Model& model) void Camera::init()
{ {
collision_scene = model.load("collision"); collision_scene.load_model("../assets/model", "scene_collisions.stl");
} }
void Camera::update(double dt) void Camera::update(double dt)
@ -123,10 +123,11 @@ void Camera::update(double dt)
velocity.z += 3.5; velocity.z += 3.5;
} }
glm::vec<3, double> normal_last(0);
glm::vec<3, double> velocity2; glm::vec<3, double> velocity2;
velocity2 = collision_scene.calc_intersect(pos, velocity * dt); velocity2 = collision_scene.calc_intersect(pos, velocity * dt, normal_last);
velocity2 = collision_scene.calc_intersect(pos + glm::vec<3, double>(0, 0, -1.5), velocity2) / dt; velocity2 = collision_scene.calc_intersect(pos + glm::vec<3, double>(0, 0, -1.5), velocity2, normal_last) / dt;
pos += velocity2 * dt; pos += velocity2 * dt;
on_ground = ((velocity * dt / dt).z != velocity2.z); on_ground = ((velocity * dt / dt).z != velocity2.z);

View File

@ -5,7 +5,6 @@
#include <json/json.h> #include <json/json.h>
#include "../system.hpp" #include "../system.hpp"
#include "mesh/model.hpp"
namespace Sim::Graphics::Camera namespace Sim::Graphics::Camera
{ {
@ -19,7 +18,7 @@ double get_yaw();
Json::Value serialize(); Json::Value serialize();
void load(const Json::Value& node); void load(const Json::Value& node);
void init(const Model& model); void init();
void rotate(double pitch, double yaw); void rotate(double pitch, double yaw);
void move(double x, double y, double z); void move(double x, double y, double z);
void update(double dt); void update(double dt);

View File

@ -1,58 +0,0 @@
#include "reactor.hpp"
#include "../../system.hpp"
#include "../../reactor/rod.hpp"
#include "../../reactor/coolant/vessel.hpp"
#include <glm/matrix.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace Sim::Graphics::Equipment;
Reactor::Reactor(const Model& model, Mesh& rmesh)
{
g_control_rod = model.load("visual_control_rod");
}
void Reactor::update(double dt)
{
}
void Reactor::remesh_slow(Mesh& rmesh)
{
Sim::System& sys = *Sim::System::active;
double t_step = sys.reactor.cell_width;
double t_sx = -(sys.reactor.width - 1) * t_step / 2.0;
double t_sy = -(sys.reactor.height - 1) * t_step / 2.0;
for(int i = 0; i < sys.reactor.size; i++)
{
int x = i % sys.reactor.width;
int y = i / sys.reactor.width;
double ox = t_sx + x * t_step;
double oy = t_sy + y * t_step;
Sim::Reactor::Rod* r = sys.reactor.rods[i].get();
if(!r->should_display())
{
continue;
}
if(r->get_colour()[3] != 0)
{
rmesh.add(g_control_rod, glm::translate(glm::mat4(1), glm::vec3(ox, oy, (1 - r->get_colour().r) * sys.reactor.cell_height)));
}
}
}
void Reactor::remesh_fast(Mesh& rmesh)
{
}
void Reactor::render()
{
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "../mesh/meshgen.hpp"
namespace Sim::Graphics::Equipment
{
class Reactor : public MeshGen
{
Mesh g_control_rod;
public:
Reactor(const Model& model, Mesh& rmesh);
virtual void update(double dt);
virtual void remesh_slow(Mesh& rmesh);
virtual void remesh_fast(Mesh& rmesh);
virtual void render();
};
};

View File

@ -6,39 +6,39 @@ using namespace Sim::Graphics;
const glm::mat4 Locations::monitors[7] = { const glm::mat4 Locations::monitors[7] = {
( (
glm::translate(glm::mat4(1), glm::vec3(-2.9475, -1.7778 + 0.05, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(-2.949, -1.7778 + 0.05, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(0, 1, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(0, 1, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
), ),
( (
glm::translate(glm::mat4(1), glm::vec3(-1.5 + 0.05, 3.9475, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(-1.5 + 0.05, 3.949, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
), ),
( (
glm::translate(glm::mat4(1), glm::vec3(1 + 0.05, 3.9475, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(1 + 0.05, 3.949, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
), ),
( (
glm::translate(glm::mat4(1), glm::vec3(3.5 + 0.05, 3.9475, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(3.5 + 0.05, 3.949, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
), ),
( (
glm::translate(glm::mat4(1), glm::vec3(6 + 0.05, 3.9475, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(6 + 0.05, 3.949, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
), ),
( (
glm::translate(glm::mat4(1), glm::vec3(8.9475, 7.0/3.0 - 0.05, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(8.949, 7.0/3.0 - 0.05, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::rotate(glm::mat4(1), glm::radians<float>(90), glm::vec3(0, 1, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(90), glm::vec3(0, 1, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
), ),
( (
glm::translate(glm::mat4(1), glm::vec3(8.9475, -1.0/3.0 - 0.05, 3 - 0.05)) * glm::translate(glm::mat4(1), glm::vec3(8.949, -1.0/3.0 - 0.05, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::rotate(glm::mat4(1), glm::radians<float>(90), glm::vec3(0, 1, 0)) * glm::rotate(glm::mat4(1), glm::radians<float>(90), glm::vec3(0, 1, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))

View File

@ -38,3 +38,13 @@ void Arrays::vertex_attrib_pointers()
glEnableVertexAttribArray(5); glEnableVertexAttribArray(5);
} }
glm::mat4 Arrays::colour(glm::vec4 c)
{
return glm::mat4({
c.r, c.g, c.b, c.a,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
});
}

View File

@ -14,12 +14,10 @@ struct Vertex
glm::vec3 normal = {0, 0, 0}; glm::vec3 normal = {0, 0, 0};
glm::vec4 colour = {1, 1, 1, 1}; glm::vec4 colour = {1, 1, 1, 1};
glm::vec3 material = {0, 0, 0}; glm::vec3 material = {0, 0, 0};
constexpr bool operator==(const Vertex&) const = default;
} __attribute__((packed)); } __attribute__((packed));
void vertex_attrib_pointers(); void vertex_attrib_pointers();
glm::mat4 colour(glm::vec4 code);
}; };

View File

@ -48,7 +48,6 @@ void Font::init()
FT_Set_Pixel_Sizes(face, 0, size); FT_Set_Pixel_Sizes(face, 0, size);
GLuint texids[128]; GLuint texids[128];
std::vector<glm::vec<4, unsigned char>> pixels;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -75,17 +74,10 @@ void Font::init()
continue; continue;
} }
pixels.resize(width * height);
for(int i = 0; i < width * height; i++)
{
pixels[i] = glm::vec<4, unsigned char>(face->glyph->bitmap.buffer[i]);
}
glCreateTextures(GL_TEXTURE_2D, 1, &texids[i]); glCreateTextures(GL_TEXTURE_2D, 1, &texids[i]);
glTextureStorage2D(texids[i], 1, GL_RGBA8, width, height); glTextureStorage2D(texids[i], 1, GL_R8, width, height);
glTextureSubImage2D(texids[i], 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); glTextureSubImage2D(texids[i], 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
glTextureParameteri(texids[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTextureParameteri(texids[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(texids[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTextureParameteri(texids[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@ -158,31 +150,3 @@ void Mesh::load_text(const char* text, double size)
this->indices = std::move(indices); this->indices = std::move(indices);
} }
void Mesh::load_text(const char* text, double size, glm::vec2 align)
{
glm::vec2 max;
load_text(text, size);
for(Arrays::Vertex& v : vertices)
{
if(v.pos.x > max.x)
{
max.x = v.pos.x;
}
if(v.pos.y > max.y)
{
max.y = v.pos.y;
}
}
align *= max;
for(Arrays::Vertex& v : vertices)
{
v.pos.x -= align.x;
v.pos.y -= align.y;
}
}

View File

@ -1,86 +0,0 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "gllight.hpp"
#include "../shader.hpp"
#include "../window.hpp"
#include "texture.hpp"
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
using namespace Sim::Graphics;
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::init()
{
glm::mat4 shadow_proj = glm::perspective<float>(M_PI * 0.5f, 1.0f, 0.01f, 100.f);
shadow_mats[0] = shadow_proj * glm::lookAt(glm::vec3(0), { 1, 0, 0}, {0,-1, 0});
shadow_mats[1] = shadow_proj * glm::lookAt(glm::vec3(0), {-1, 0, 0}, {0,-1, 0});
shadow_mats[2] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 1, 0}, {0, 0, 1});
shadow_mats[3] = shadow_proj * glm::lookAt(glm::vec3(0), { 0,-1, 0}, {0, 0,-1});
shadow_mats[4] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 0, 1}, {0,-1, 0});
shadow_mats[5] = shadow_proj * glm::lookAt(glm::vec3(0), { 0, 0,-1}, {0,-1, 0});
glUniformMatrix4fv(Shader::LIGHT["shadow_mats"], 6, false, &shadow_mats[0][0][0]);
}

View File

@ -1,28 +0,0 @@
#pragma once
#include "light.hpp"
namespace Sim::Graphics
{
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();
};
};

View File

@ -33,6 +33,7 @@ GLMesh::GLMesh(GLMesh&& o)
ebo = o.ebo; ebo = o.ebo;
vao = o.vao; vao = o.vao;
size = o.size; size = o.size;
colour_matrix = o.colour_matrix;
model_matrix = o.model_matrix; model_matrix = o.model_matrix;
o.vbo = 0; o.vbo = 0;
@ -52,17 +53,18 @@ void GLMesh::bind()
init(this); init(this);
glBindVertexArray(vao); glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
} }
void GLMesh::uniform() void GLMesh::uniform()
{ {
glUniformMatrix4fv(Shader::ACTIVE->get("model"), 1, false, &model_matrix[0][0]); glUniformMatrix4fv(Shader::MAIN["model"], 1, false, &model_matrix[0][0]);
glUniformMatrix4fv(Shader::MAIN["tex_mat"], 1, false, &colour_matrix[0][0]);
} }
void GLMesh::set(const Mesh& m, int mode) void GLMesh::set(const Mesh& m, int mode)
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ARRAY_BUFFER, m.vertices.size() * sizeof(m.vertices[0]), &m.vertices[0], mode); glBufferData(GL_ARRAY_BUFFER, m.vertices.size() * sizeof(m.vertices[0]), &m.vertices[0], mode);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m.indices.size() * sizeof(m.indices[0]), &m.indices[0], mode); glBufferData(GL_ELEMENT_ARRAY_BUFFER, m.indices.size() * sizeof(m.indices[0]), &m.indices[0], mode);
this->size = m.indices.size(); this->size = m.indices.size();

View File

@ -16,6 +16,7 @@ struct GLMesh
unsigned int vao = 0, vbo = 0, ebo = 0, size = 0; unsigned int vao = 0, vbo = 0, ebo = 0, size = 0;
glm::mat4 model_matrix {1.0f}; glm::mat4 model_matrix {1.0f};
glm::mat4 colour_matrix {1.0f};
constexpr GLMesh() { } constexpr GLMesh() { }

View File

@ -18,8 +18,6 @@ struct Light
float padding1; float padding1;
glm::vec3 colour; glm::vec3 colour;
float padding2; float padding2;
constexpr bool operator==(const Light&) const = default;
} __attribute__((packed)); } __attribute__((packed));

View File

@ -155,11 +155,17 @@ bool Mesh::check_intersect(vec3 pos, vec3 path) const
return false; return false;
} }
static bool calc_intercept_vert(vec3 v[3], vec3 pos, vec3& path, vec3& path_n, double& l) vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const
{
vec3 normal_last(0);
return calc_intersect(pos, path, normal_last);
}
static bool calc_intercept_vert(vec3 v[3], vec3 pos, vec3& path, vec3& path_n, vec3& normal_last, double& l)
{ {
vec3 ipoint; vec3 ipoint;
vec3 normal = glm::normalize(glm::cross(v[1] - v[0], v[2] - v[0])); vec3 normal = glm::normalize(glm::cross(v[1] - v[0], v[2] - v[0]));
double d = glm::dot(path, normal); double d = glm::dot(normal, path);
if(d >= 0) if(d >= 0)
return false; return false;
@ -168,11 +174,20 @@ static bool calc_intercept_vert(vec3 v[3], vec3 pos, vec3& path, vec3& path_n, d
if(l < glm::length(ipoint - pos)) if(l < glm::length(ipoint - pos))
return false; return false;
if(d < 0) if(normal_last != vec3(0))
{ {
path -= normal * d; vec3 n = glm::cross(normal_last, normal);
l = glm::length(path);
if(glm::length(n) > 0)
{
normal = glm::normalize(glm::cross(glm::cross(normal_last, normal), normal_last));
d = glm::dot(normal, path);
}
} }
path -= normal * d;
normal_last = normal;
l = glm::length(path);
if(l > 0) if(l > 0)
{ {
@ -182,7 +197,7 @@ static bool calc_intercept_vert(vec3 v[3], vec3 pos, vec3& path, vec3& path_n, d
return true; return true;
} }
vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const vec3 Mesh::calc_intersect(vec3 pos, vec3 path, vec3& normal_last) const
{ {
double l = glm::length(path); double l = glm::length(path);
@ -202,7 +217,7 @@ vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const
vec3(this->vertices[indices[i + 2]].pos) vec3(this->vertices[indices[i + 2]].pos)
}; };
if(calc_intercept_vert(v, pos, path, path_n, l)) if(calc_intercept_vert(v, pos, path, path_n, normal_last, l))
{ {
i_found = i; i_found = i;
} }
@ -221,7 +236,7 @@ vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const
vec3(this->vertices[indices[i + 2]].pos) vec3(this->vertices[indices[i + 2]].pos)
}; };
calc_intercept_vert(v, pos, path, path_n, l); calc_intercept_vert(v, pos, path, path_n, normal_last, l);
if(l == 0) if(l == 0)
{ {
@ -250,4 +265,3 @@ Mesh Mesh::to_lines() const
return m; return m;
} }

View File

@ -17,15 +17,18 @@ namespace Sim::Graphics
struct Mesh struct Mesh
{ {
std::unordered_map<std::string, glm::mat4> mat_nodes;
std::vector<Arrays::Vertex> vertices; std::vector<Arrays::Vertex> vertices;
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
std::vector<Light> lights;
Mesh(); Mesh();
void set_vertices(const Arrays::Vertex* data, size_t size); void set_vertices(const Arrays::Vertex* data, size_t size);
void set_indices(const unsigned int* 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);
void load_text(const char* text, double size); void load_text(const char* text, double size);
void load_text(const char* text, double size, glm::vec2 align);
void add(const Mesh& o, glm::mat4 mat); void add(const Mesh& o, glm::mat4 mat);
void add(const Mesh& o); void add(const Mesh& o);
@ -34,8 +37,7 @@ struct Mesh
bool check_focus(double len) const; bool check_focus(double len) const;
bool check_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; bool check_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const;
glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const;
glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path, glm::vec<3, double>& normal_last) const;
bool operator==(const Mesh&) const = default;
template <class T> template <class T>
void load_text(const char* header, T& item, double size) void load_text(const char* header, T& item, double size)

View File

@ -1,20 +0,0 @@
#pragma once
#include "../mesh/model.hpp"
namespace Sim::Graphics
{
class MeshGen
{
public:
virtual ~MeshGen() {}
virtual void update(double dt) = 0;
virtual void remesh_slow(Mesh& rmesh) = 0;
virtual void remesh_fast(Mesh& rmesh) = 0;
virtual void render() = 0;
};
};

View File

@ -2,6 +2,10 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/material.h>
#include <glm/matrix.hpp> #include <glm/matrix.hpp>
#include <unordered_map> #include <unordered_map>
@ -11,7 +15,6 @@
#include "mesh.hpp" #include "mesh.hpp"
#include "arrays.hpp" #include "arrays.hpp"
#include "texture.hpp" #include "texture.hpp"
#include "model.hpp"
#include "../../util/streams.hpp" #include "../../util/streams.hpp"
using namespace Sim::Graphics; using namespace Sim::Graphics;
@ -21,9 +24,11 @@ struct ProcState
unsigned int offset = 0; unsigned int offset = 0;
std::string base; std::string base;
std::vector<Light> lights;
std::vector<Arrays::Vertex> vertices; std::vector<Arrays::Vertex> vertices;
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
std::unordered_map<const aiTexture*, unsigned int> handles; 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, aiTextureType type, int index) static unsigned int proc_texture(const ProcState& state, aiMaterial* mat, const aiScene* scene, aiTextureType type, int index)
@ -57,7 +62,7 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce
aiString name; aiString name;
material->Get(AI_MATKEY_NAME, name); material->Get(AI_MATKEY_NAME, name);
/*
std::cout << "Material " << name.C_Str() << " has " << material->mNumProperties << " properties\n"; std::cout << "Material " << name.C_Str() << " has " << material->mNumProperties << " properties\n";
for(int i = 0; i < material->mNumProperties; i++) for(int i = 0; i < material->mNumProperties; i++)
@ -92,7 +97,7 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce
} }
std::cout << "\n"; std::cout << "\n";
}*/ }
glm::vec3 matv(0); glm::vec3 matv(0);
aiColor4D ai_cb; aiColor4D ai_cb;
@ -112,6 +117,8 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce
cb = em; cb = em;
} }
std::cout << "Material: " << matv << "\n";
unsigned int handle = proc_texture(state, material, scene, aiTextureType_BASE_COLOR, 0); unsigned int handle = proc_texture(state, material, scene, aiTextureType_BASE_COLOR, 0);
unsigned int offset = state.offset; unsigned int offset = state.offset;
glm::mat3 mat3(mat); glm::mat3 mat3(mat);
@ -172,7 +179,7 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce
state.offset += mesh->mNumVertices; state.offset += mesh->mNumVertices;
} }
glm::mat4 convert_mat(aiMatrix4x4 m) glm::mat4 get_mat(aiMatrix4x4 m)
{ {
return { return {
m.a1, m.a2, m.a3, m.a4, m.a1, m.a2, m.a3, m.a4,
@ -182,38 +189,21 @@ glm::mat4 convert_mat(aiMatrix4x4 m)
}; };
} }
bool starts_with(const char* base, const char* check) static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiScene* scene)
{ {
while(base[0] != '\0' && check[0] != '\0') mat = get_mat(node->mTransformation) * mat;
{ std::string name(node->mName.C_Str());
if(base[0] != check[0]) state.mat_nodes[name] = mat;
{
return false;
}
base++;
check++;
}
return (check[0] == '\0');
}
static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiScene* scene, const char* search)
{
mat = convert_mat(node->mTransformation) * mat;
if(starts_with(node->mName.C_Str(), search)) for(size_t i = 0; i < node->mNumMeshes; i++)
{ {
for(size_t i = 0; i < node->mNumMeshes; i++) aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
{ proc_mesh(state, mat, mesh, scene);
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
proc_mesh(state, mat, mesh, scene);
}
} }
for(size_t i = 0; i < node->mNumChildren; i++) for(size_t i = 0; i < node->mNumChildren; i++)
{ {
proc_node(state, mat, node->mChildren[i], scene, search); proc_node(state, mat, node->mChildren[i], scene);
} }
} }
@ -226,92 +216,76 @@ static unsigned int proc_embedded_texture(aiTexture* tex)
return Texture::load_mem((unsigned char*)tex->pcData, tex->mWidth); return Texture::load_mem((unsigned char*)tex->pcData, tex->mWidth);
} }
std::vector<glm::vec<4, unsigned char>> pixels; // swizzle each pixel to get RGBA
pixels.reserve(tex->mWidth * tex->mHeight);
// convert image to get RGBA
for(int i = 0; i < tex->mWidth * tex->mHeight; i++) for(int i = 0; i < tex->mWidth * tex->mHeight; i++)
{ {
aiTexel t = tex->pcData[i]; aiTexel t = tex->pcData[i];
pixels.push_back({t.r, t.g, t.b, t.a}); tex->pcData[i] = {t.r, t.g, t.b, t.a};
} }
return Texture::load_mem(&pixels[0][0], tex->mWidth, tex->mHeight, 4); return Texture::load_mem((unsigned char*)tex->pcData, tex->mWidth, tex->mHeight, 4);
} }
glm::mat4 get_transforms(const aiNode* node) glm::mat4 get_transforms(aiNode* node)
{ {
glm::mat4 mat(1); glm::mat4 mat(1);
while(node->mParent != nullptr) while(node->mParent != nullptr)
{ {
mat = mat * convert_mat(node->mTransformation); mat *= get_mat(node->mTransformation);
node = node->mParent; node = node->mParent;
} }
return mat; return mat;
} }
glm::mat4 Model::get_matrix(const char* name) const void Mesh::load_model(std::string path)
{ {
return get_transforms(scene->mRootNode->FindNode(name)); load_model(".", path);
} }
Model::Model(std::string base, std::string filename) : base(base) void Mesh::load_model(std::string base, std::string filename)
{ {
ProcState state {.base = base};
std::string path = base + "/" + filename; std::string path = base + "/" + filename;
scene = importer.ReadFile(path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs); Assimp::Importer importer;
textures.reserve(scene->mNumTextures); const aiScene *scene = importer.ReadFile(path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs);
if(scene == nullptr)
{
std::cerr << "AssImp: Error loading model\n";
return;
}
for(int i = 0; i < scene->mNumTextures; i++) for(int i = 0; i < scene->mNumTextures; i++)
{ {
aiTexture* tex = scene->mTextures[i]; aiTexture* tex = scene->mTextures[i];
unsigned int handle = proc_embedded_texture(tex); unsigned int handle = proc_embedded_texture(tex);
textures.push_back(handle); state.handles[tex] = handle;
} }
for(int i = 0; i < scene->mNumLights; i++) for(int i = 0; i < scene->mNumLights; i++)
{ {
aiLight* light = scene->mLights[i]; aiLight* light = scene->mLights[i];
glm::mat4 mat = get_matrix(light->mName.C_Str()); glm::mat4 mat = get_transforms(scene->mRootNode->FindNode(light->mName));
auto [x, y, z] = light->mPosition; auto [x, y, z] = light->mPosition;
auto [r, g, b] = light->mColorDiffuse; auto [r, g, b] = light->mColorDiffuse;
glm::vec4 pos = glm::vec4(x, y, z, 1) * mat; glm::vec4 pos = glm::vec4(x, y, z, 1) * mat;
lights.push_back({ state.lights.push_back({
glm::vec3(pos), glm::vec3(pos),
{r, g, b}, {r, g, b},
}); });
} }
}
proc_node(state, glm::mat4(1), scene->mRootNode, scene);
Mesh Model::load(const char* name, glm::mat4 mat) const
{ mat_nodes = std::move(state.mat_nodes);
Mesh mesh; vertices = std::move(state.vertices);
ProcState state {.base = base}; indices = std::move(state.indices);
proc_node(state, mat, scene->mRootNode, scene, name); lights = std::move(state.lights);
mesh.vertices = std::move(state.vertices);
mesh.indices = std::move(state.indices);
return mesh;
}
Mesh Model::load_root(glm::mat4 mat) const
{
return load("", mat);
}
Mesh Model::load(const char* name) const
{
return load(name, glm::mat4(1));
}
Mesh Model::load_root() const
{
return load("", glm::mat4(1));
} }

View File

@ -1,42 +0,0 @@
#pragma once
#include "mesh.hpp"
#include "light.hpp"
#include <string>
#include <vector>
#include <glm/matrix.hpp>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/material.h>
#include <assimp/postprocess.h>
namespace Sim::Graphics
{
class Model
{
std::string base;
Assimp::Importer importer;
const aiScene* scene;
public:
std::vector<uint64_t> textures;
std::vector<Light> lights;
Model(std::string base, std::string filename);
Model(const Model&) = delete;
Mesh load_root() const;
Mesh load_root(glm::mat4 mat) const;
Mesh load(const char* name) const;
Mesh load(const char* name, glm::mat4 mat) const;
glm::mat4 get_matrix(const char* name) const;
};
};

View File

@ -92,7 +92,7 @@ unsigned int Texture::load(std::string path)
throw std::runtime_error("Failed to load path: " + path); throw std::runtime_error("Failed to load path: " + path);
} }
std::cout << "Loaded image: " << path << "\n"; std::cout << "Loaded Image: " << path << "\n";
loaded[path] = handle; loaded[path] = handle;
return handle; return handle;

View File

@ -80,6 +80,8 @@ struct CoreMonitor : public Focus::FocusType
default: default:
return; return;
} }
parent->is_dirty = true;
} }
}; };
@ -95,6 +97,7 @@ struct CoreJoystick : public Focus::FocusType
virtual void on_cursor_pos(double x, double y) virtual void on_cursor_pos(double x, double y)
{ {
System::active->reactor.add_rod_speed(y * 1e-6); System::active->reactor.add_rod_speed(y * 1e-6);
parent->is_dirty = true;
} }
virtual ~CoreJoystick() virtual ~CoreJoystick()
@ -116,26 +119,33 @@ struct CoreJoystick : public Focus::FocusType
} }
}; };
Core::Core(const Model& model, Mesh& rmesh) Core::Core()
{ {
Mesh mesh = model.load("translation_monitor_3"); }
mat = Locations::monitors[2];
mesh.load_text("Reactor Core", 0.04); void Core::init()
rmesh.add(mesh, mat); {
mesh1.model_matrix = mesh2.model_matrix = Locations::monitors[2];
mesh1.colour_matrix = mesh2.colour_matrix = Arrays::colour({1, 1, 1, 1});
Sim::Graphics::Mesh rmesh;
rmesh.load_text("Reactor Core", 0.04);
mesh1.bind();
mesh1.set(rmesh, GL_STATIC_DRAW);
m_buttons[0] = model.load("click_numpad_1"); m_buttons[0].load_model("../assets/model/", "reactor_core_button1.stl");
m_buttons[1] = model.load("click_numpad_2"); m_buttons[1].load_model("../assets/model/", "reactor_core_button2.stl");
m_buttons[2] = model.load("click_numpad_3"); m_buttons[2].load_model("../assets/model/", "reactor_core_button3.stl");
m_buttons[3] = model.load("click_numpad_4"); m_buttons[3].load_model("../assets/model/", "reactor_core_button4.stl");
m_buttons[4] = model.load("click_numpad_5"); m_buttons[4].load_model("../assets/model/", "reactor_core_button5.stl");
m_buttons[5] = model.load("click_numpad_6"); m_buttons[5].load_model("../assets/model/", "reactor_core_button6.stl");
m_buttons[6] = model.load("click_numpad_7"); m_buttons[6].load_model("../assets/model/", "reactor_core_button7.stl");
m_buttons[7] = model.load("click_numpad_8"); m_buttons[7].load_model("../assets/model/", "reactor_core_button8.stl");
m_buttons[8] = model.load("click_numpad_9"); m_buttons[8].load_model("../assets/model/", "reactor_core_button9.stl");
m_joystick = model.load("click_reactor_joystick"); m_joystick.load_model("../assets/model/", "reactor_core_joystick.stl");
m_monitor = model.load("translation_monitor_3"); m_monitor.load_model("../assets/model/", "reactor_core_input.stl");
m_scram = model.load("click_scram"); m_scram.load_model("../assets/model/", "reactor_core_scram.stl");
} }
static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour) static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour)
@ -158,49 +168,71 @@ void Core::update(double dt)
{ {
Sim::System& sys = *System::active; Sim::System& sys = *System::active;
if(m_monitor.check_focus()) if(m_monitor.check_focus()) {
Focus::set(std::make_unique<CoreMonitor>(this)); Focus::set(std::make_unique<CoreMonitor>(this));
if(m_joystick.check_focus()) }
if(m_joystick.check_focus()) {
Focus::set(std::make_unique<CoreJoystick>(this)); Focus::set(std::make_unique<CoreJoystick>(this));
if(m_scram.check_focus()) }
if(m_scram.check_focus()) {
sys.reactor.scram(); sys.reactor.scram();
if(m_buttons[0].check_focus()) is_dirty = true;
}
if(m_buttons[0].check_focus()) {
set_all(true); set_all(true);
if(m_buttons[1].check_focus()) is_dirty = true;
}
if(m_buttons[1].check_focus()) {
sys.reactor.move_cursor(-sys.reactor.height); sys.reactor.move_cursor(-sys.reactor.height);
if(m_buttons[2].check_focus()) is_dirty = true;
}
if(m_buttons[2].check_focus()) {
set_all(false); set_all(false);
if(m_buttons[3].check_focus()) is_dirty = true;
}
if(m_buttons[3].check_focus()) {
sys.reactor.move_cursor(-1); sys.reactor.move_cursor(-1);
if(m_buttons[4].check_focus()) is_dirty = true;
}
if(m_buttons[4].check_focus()) {
sys.reactor.toggle_selected(); sys.reactor.toggle_selected();
if(m_buttons[5].check_focus()) is_dirty = true;
}
if(m_buttons[5].check_focus()) {
sys.reactor.move_cursor(1); sys.reactor.move_cursor(1);
if(m_buttons[6].check_focus()) is_dirty = true;
}
if(m_buttons[6].check_focus()) {
sys.reactor.reset_rod_speed(); sys.reactor.reset_rod_speed();
if(m_buttons[7].check_focus()) is_dirty = true;
}
if(m_buttons[7].check_focus()) {
sys.reactor.move_cursor(sys.reactor.height); sys.reactor.move_cursor(sys.reactor.height);
} is_dirty = true;
}
void Core::remesh_slow(Mesh& rmesh) clock_now += dt;
{
remesh(rmesh, false);
}
void Core::remesh_fast(Mesh& rmesh) if(clock_at + 1.0/30.0 > clock_now)
{ {
remesh(rmesh, true); if(!is_dirty)
} {
return;
}
}
void Core::remesh(Mesh& rmesh, bool fast) else
{ {
Sim::System& sys = *System::active; clock_at += 1.0/30.0;
Sim::Graphics::Mesh mesh; }
Sim::Graphics::Mesh rmesh;
is_dirty = false;
double step = 1 / (sys.vessel.diameter / sys.reactor.cell_width * 0.8); double step = 1 / (sys.vessel.diameter / sys.reactor.cell_width * 0.8);
double sx = 0.5 - (sys.reactor.width - 1) * step / 2.0; double sx = 0.5 - (sys.reactor.width - 1) * step / 2.0;
double sy = 0.5 - (sys.reactor.height - 1) * step / 2.0; double sy = 0.5 - (sys.reactor.height - 1) * step / 2.0;
glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.4, step * 0.4, 1)); glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.4, step * 0.4, 1));
glm::mat4 mat_select = glm::translate(glm::mat4(1), glm::vec3(-0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1)); glm::mat4 mat_select = glm::translate(glm::mat4(1), glm::vec3(-0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1));
glm::mat4 mat_cursor = glm::translate(glm::mat4(1), glm::vec3(-0.8, 0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1)); glm::mat4 mat_cursor = glm::translate(glm::mat4(1), glm::vec3(-0.8, 0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1));
@ -220,44 +252,46 @@ void Core::remesh(Mesh& rmesh, bool fast)
continue; continue;
} }
glm::vec4 colour_heat = r->get_heat_colour() * glm::vec4(glm::vec3(1), 1);
glm::vec4 colour_spec = r->get_colour();
if(colour_heat[3] == 0)
{
continue;
}
glm::mat4 mat = glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale; glm::mat4 mat = glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale;
if(!fast) rmesh.add(add_dot(mat, colour_heat));
if(sys.reactor.cursor == i)
{ {
glm::vec4 colour_heat = r->get_heat_colour() * glm::vec4(glm::vec3(1), 1); rmesh.add(add_dot(mat * mat_cursor, {1, 0, 0, 1}));
glm::vec4 colour_spec = r->get_colour();
if(colour_heat[3] == 0)
{
continue;
}
mesh.add(add_dot(mat, colour_heat));
if(colour_spec[3] != 0)
{
mesh.add(add_dot(mat * mat_spec, colour_spec));
}
} }
else if(r->selected)
{ {
if(sys.reactor.cursor == i) rmesh.add(add_dot(mat * mat_select, {1, 1, 0, 1}));
{ }
mesh.add(add_dot(mat * mat_cursor, {1, 0, 0, 1}));
}
if(r->selected) if(colour_spec[3] != 0)
{ {
mesh.add(add_dot(mat * mat_select, {1, 1, 0, 1})); rmesh.add(add_dot(mat * mat_spec, colour_spec));
}
} }
} }
rmesh.add(mesh, mat); mesh2.bind();
mesh2.set(rmesh, GL_DYNAMIC_DRAW);
} }
void Core::render() void Core::render()
{ {
mesh1.bind();
mesh1.uniform();
mesh1.render();
mesh2.bind();
mesh2.uniform();
mesh2.render();
} }

View File

@ -1,29 +1,29 @@
#pragma once #pragma once
#include "../mesh/model.hpp" #include "../mesh/glmesh.hpp"
#include "../mesh/meshgen.hpp"
namespace Sim::Graphics::Monitor namespace Sim::Graphics::Monitor
{ {
class Core : public MeshGen class Core
{ {
glm::mat4 mat; Sim::Graphics::GLMesh mesh1, mesh2;
double clock_at = 0, clock_now = 0;
Mesh m_monitor; Sim::Graphics::Mesh m_monitor;
Mesh m_buttons[9]; Sim::Graphics::Mesh m_buttons[9];
Mesh m_joystick; Sim::Graphics::Mesh m_joystick;
Mesh m_scram; Sim::Graphics::Mesh m_scram;
public: public:
Core(const Model& model, Mesh& rmesh); bool is_dirty = false;
void remesh(Mesh& rmesh, bool fast);
virtual void update(double dt); Core();
virtual void remesh_slow(Mesh& rmesh); void init();
virtual void remesh_fast(Mesh& rmesh); void update(double dt);
virtual void render(); void render();
}; };
}; };

View File

@ -49,12 +49,26 @@ struct ValveJoystick : public Focus::FocusType
} }
}; };
PrimaryLoop::PrimaryLoop(const Model& model, Mesh& rmesh)
PrimaryLoop::PrimaryLoop()
{ {
mat = Locations::monitors[3];
}
void PrimaryLoop::init()
{
mesh1.model_matrix = Locations::monitors[3];
mesh2.model_matrix = glm::translate(mesh1.model_matrix, glm::vec3(0.5, 0, 0));
mesh1.colour_matrix = mesh2.colour_matrix = {
1, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
std::stringstream ss; std::stringstream ss;
Sim::Graphics::Mesh mesh; Sim::Graphics::Mesh rmesh;
ss << "Turbine Bypass Valve\n\n"; ss << "Turbine Bypass Valve\n\n";
ss << "Opened\nFlow\nSetpoint\n\n"; ss << "Opened\nFlow\nSetpoint\n\n";
@ -68,23 +82,82 @@ PrimaryLoop::PrimaryLoop(const Model& model, Mesh& rmesh)
ss << "Pressure\n"; ss << "Pressure\n";
ss << "Level\n"; ss << "Level\n";
mesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, mat); mesh1.bind();
mesh1.set(rmesh, GL_STATIC_DRAW);
g_switch_pump = model.load("visual_pump_switch_1"); rmesh.load_model("../assets/model", "pump_switch_1.glb");
g_switch_bypass = model.load("visual_bypass_switch"); gm_switch_pump.bind();
g_switch_inlet = model.load("visual_inlet_switch"); gm_switch_pump.set(rmesh, GL_STATIC_DRAW);
rmesh.load_model("../assets/model", "turbine_valve_bypass_switch.glb");
gm_switch_bypass.bind();
gm_switch_bypass.set(rmesh, GL_STATIC_DRAW);
m_joystick_turbine_bypass = model.load("click_bypass_joystick"); rmesh.load_model("../assets/model", "turbine_valve_inlet_switch.glb");
m_joystick_turbine_inlet = model.load("click_inlet_joystick"); gm_switch_inlet.bind();
m_switch_pump = model.load("click_pump_switch_1"); gm_switch_inlet.set(rmesh, GL_STATIC_DRAW);
m_switch_bypass = model.load("click_bypass_switch");
m_switch_inlet = model.load("click_inlet_switch"); m_joystick_turbine_bypass.load_model("../assets/model", "turbine_valve_bypass_joystick.stl");
m_joystick_turbine_inlet.load_model("../assets/model", "turbine_valve_inlet_joystick.stl");
m_switch_pump.load_model("../assets/model", "pump_switch_click_1.stl");
m_switch_bypass.load_model("../assets/model", "turbine_valve_bypass_switch_click.stl");
m_switch_inlet.load_model("../assets/model", "turbine_valve_inlet_switch_click.stl");
} }
void PrimaryLoop::update(double dt) void PrimaryLoop::update(double dt)
{ {
System& sys = *System::active; System& sys = *System::active;
clock_now += dt;
if(clock_at + 1.0/30.0 < clock_now)
{
std::stringstream ss;
Sim::Graphics::Mesh rmesh;
clock_at += 1.0/30.0;
ss << "\n\n";
ss << show( sys.loop.turbine_bypass_valve.get_state() * 100 ) << " %\n";
show_units( ss, sys.loop.turbine_bypass_valve.get_flow() ) << "g/s\n";
if(sys.loop.turbine_bypass_valve.get_auto())
{
ss << show( sys.loop.turbine_bypass_valve.get_setpoint() ) << " C\n";
}
else
{
ss << "-\n";
}
ss << "\n\n\n";
ss << show( sys.loop.turbine_inlet_valve.get_state() * 100 ) << " %\n";
show_units( ss, sys.loop.turbine_inlet_valve.get_flow() ) << "g/s\n";
if(sys.loop.turbine_inlet_valve.get_auto())
{
ss << show( sys.loop.turbine_inlet_valve.get_setpoint() ) << " C\n";
}
else
{
ss << "-\n";
}
ss << "\n\n\n";
ss << show( sys.loop.primary_pump.get_power() * 100 ) << " %\n";
ss << show( sys.loop.primary_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.loop.primary_pump.get_flow_mass() ) << "g/s\n";
ss << "\n\n\n";
ss << show( sys.loop.condenser.get_heat() ) << " C\n";
show_units( ss, sys.loop.condenser.get_steam() ) << "g\n";
show_units( ss, sys.loop.condenser.get_pressure() ) << "Pa\n";
ss << show( sys.loop.condenser.get_level() / 1000 ) << " / " << show( sys.loop.condenser.get_volume() / 1000 ) << " kL\n";
rmesh.load_text(ss.str().c_str(), 0.04);
mesh2.bind();
mesh2.set(rmesh, GL_DYNAMIC_DRAW);
}
if(m_joystick_turbine_bypass.check_focus()) if(m_joystick_turbine_bypass.check_focus())
Focus::set(std::make_unique<ValveJoystick>(&sys.loop.turbine_bypass_valve)); Focus::set(std::make_unique<ValveJoystick>(&sys.loop.turbine_bypass_valve));
@ -96,70 +169,32 @@ void PrimaryLoop::update(double dt)
sys.loop.turbine_inlet_valve.toggle_auto(); sys.loop.turbine_inlet_valve.toggle_auto();
if(m_switch_bypass.check_focus()) if(m_switch_bypass.check_focus())
sys.loop.turbine_bypass_valve.toggle_auto(); sys.loop.turbine_bypass_valve.toggle_auto();
}
gm_switch_inlet.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.turbine_inlet_valve.get_auto() ? 0.07 : 0, 0));
void PrimaryLoop::remesh_slow(Mesh& rmesh) gm_switch_bypass.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.turbine_bypass_valve.get_auto() ? 0.07 : 0, 0));
{ gm_switch_pump.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.primary_pump.powered ? 0.07 : 0, 0));
std::stringstream ss;
Sim::Graphics::Mesh mesh;
System& sys = *System::active;
ss << "\n\n";
ss << show( sys.loop.turbine_bypass_valve.get_state() * 100 ) << " %\n";
show_units( ss, sys.loop.turbine_bypass_valve.get_flow() ) << "g/s\n";
if(sys.loop.turbine_bypass_valve.get_auto())
{
ss << show( sys.loop.turbine_bypass_valve.get_setpoint() ) << " C\n";
}
else
{
ss << "-\n";
}
ss << "\n\n\n";
ss << show( sys.loop.turbine_inlet_valve.get_state() * 100 ) << " %\n";
show_units( ss, sys.loop.turbine_inlet_valve.get_flow() ) << "g/s\n";
if(sys.loop.turbine_inlet_valve.get_auto())
{
ss << show( sys.loop.turbine_inlet_valve.get_setpoint() ) << " C\n";
}
else
{
ss << "-\n";
}
ss << "\n\n\n";
ss << show( sys.loop.primary_pump.get_power() * 100 ) << " %\n";
ss << show( sys.loop.primary_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.loop.primary_pump.get_flow_mass() ) << "g/s\n";
ss << "\n\n\n";
ss << show( sys.loop.condenser.get_heat() ) << " C\n";
show_units( ss, sys.loop.condenser.get_steam() ) << "g\n";
show_units( ss, sys.loop.condenser.get_pressure() ) << "Pa\n";
ss << show( sys.loop.condenser.get_level() / 1000 ) << " / " << show( sys.loop.condenser.get_volume() / 1000 ) << " kL\n";
mesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0)));
}
void PrimaryLoop::remesh_fast(Mesh& rmesh)
{
System& sys = *System::active;
float off1 = sys.loop.primary_pump.powered ? 0.07 : 0;
float off2 = sys.loop.turbine_bypass_valve.get_auto() ? 0.07 : 0;
float off3 = sys.loop.turbine_inlet_valve.get_auto() ? 0.07 : 0;
rmesh.add(g_switch_pump, glm::translate(glm::mat4(1), glm::vec3(0, off1, 0)));
rmesh.add(g_switch_bypass, glm::translate(glm::mat4(1), glm::vec3(0, off2, 0)));
rmesh.add(g_switch_inlet, glm::translate(glm::mat4(1), glm::vec3(0, off3, 0)));
} }
void PrimaryLoop::render() void PrimaryLoop::render()
{ {
mesh1.bind();
mesh1.uniform();
mesh1.render();
mesh2.bind();
mesh2.uniform();
mesh2.render();
gm_switch_pump.bind();
gm_switch_pump.uniform();
gm_switch_pump.render();
gm_switch_inlet.bind();
gm_switch_inlet.uniform();
gm_switch_inlet.render();
gm_switch_bypass.bind();
gm_switch_bypass.uniform();
gm_switch_bypass.render();
} }

View File

@ -1,34 +1,33 @@
#pragma once #pragma once
#include "../mesh/model.hpp" #include "../mesh/glmesh.hpp"
#include "../mesh/meshgen.hpp"
namespace Sim::Graphics::Monitor namespace Sim::Graphics::Monitor
{ {
class PrimaryLoop : public MeshGen class PrimaryLoop
{ {
glm::mat4 mat; GLMesh mesh1, mesh2;
double clock_at = 0, clock_now = 0;
GLMesh gm_switch_pump;
GLMesh gm_switch_bypass;
GLMesh gm_switch_inlet;
Mesh m_joystick_turbine_bypass; Mesh m_joystick_turbine_bypass;
Mesh m_joystick_turbine_inlet; Mesh m_joystick_turbine_inlet;
Mesh g_switch_pump;
Mesh g_switch_bypass;
Mesh g_switch_inlet;
Mesh m_switch_pump; Mesh m_switch_pump;
Mesh m_switch_bypass; Mesh m_switch_bypass;
Mesh m_switch_inlet; Mesh m_switch_inlet;
public: public:
PrimaryLoop(const Model& model, Mesh& rmesh); PrimaryLoop();
virtual void update(double dt); void init();
virtual void remesh_slow(Mesh& rmesh); void update(double dt);
virtual void remesh_fast(Mesh& rmesh); void render();
virtual void render();
}; };
}; };

View File

@ -16,13 +16,25 @@ using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor; using namespace Sim::Graphics::Monitor;
using namespace Sim::Util::Streams; using namespace Sim::Util::Streams;
SecondaryLoop::SecondaryLoop()
SecondaryLoop::SecondaryLoop(const Model& model, Mesh& rmesh)
{ {
mat = Locations::monitors[5];
}
void SecondaryLoop::init()
{
mesh1.model_matrix = Locations::monitors[5];
mesh2.model_matrix = glm::translate(mesh1.model_matrix, glm::vec3(0.5, 0, 0));
mesh1.colour_matrix = mesh2.colour_matrix = {
1, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
std::stringstream ss; std::stringstream ss;
Sim::Graphics::Mesh mesh; Sim::Graphics::Mesh rmesh;
ss << "Cooling Tower\n\n"; ss << "Cooling Tower\n\n";
ss << "Heat\nSteam\nPressure\nLevel\n\n"; ss << "Heat\nSteam\nPressure\nLevel\n\n";
@ -31,65 +43,80 @@ SecondaryLoop::SecondaryLoop(const Model& model, Mesh& rmesh)
ss << "Freight Pump\n\n"; ss << "Freight Pump\n\n";
ss << "Power\nSpeed\nFlow\n\n"; ss << "Power\nSpeed\nFlow\n\n";
mesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, mat); mesh1.bind();
mesh1.set(rmesh, GL_STATIC_DRAW);
g_switch_2 = model.load("visual_pump_switch_2"); rmesh.load_model("../assets/model", "pump_switch_2.glb");
g_switch_3 = model.load("visual_pump_switch_3"); gm_switch_2.bind();
gm_switch_2.set(rmesh, GL_STATIC_DRAW);
rmesh.load_model("../assets/model", "pump_switch_3.glb");
gm_switch_3.bind();
gm_switch_3.set(rmesh, GL_STATIC_DRAW);
m_joystick_turbine_bypass = model.load("click_bypass_joystick"); m_joystick_turbine_bypass.load_model("../assets/model", "turbine_valve_bypass_joystick.stl");
m_joystick_turbine_inlet = model.load("click_inlet_joystick"); m_joystick_turbine_inlet.load_model("../assets/model", "turbine_valve_inlet_joystick.stl");
m_switch_2 = model.load("click_pump_switch_2"); m_switch_2.load_model("../assets/model", "pump_switch_click_2.stl");
m_switch_3 = model.load("click_pump_switch_3"); m_switch_3.load_model("../assets/model", "pump_switch_click_3.stl");
} }
void SecondaryLoop::update(double dt) void SecondaryLoop::update(double dt)
{ {
System& sys = *System::active; System& sys = *System::active;
clock_now += dt;
if(clock_at + 1.0/30.0 < clock_now)
{
std::stringstream ss;
Sim::Graphics::Mesh rmesh;
clock_at += 1.0/30.0;
ss << "\n\n";
ss << show( sys.evaporator.get_heat() ) << " C\n";
show_units( ss, sys.evaporator.get_steam_output() ) << "g/s\n";
show_units( ss, sys.evaporator.get_pressure() ) << "Pa\n";
ss << show( sys.evaporator.get_level() / 1000 ) << " / " << show( sys.evaporator.get_volume() / 1000 ) << " kL\n";
ss << "\n\n\n";
ss << show( sys.loop.secondary_pump.get_power() * 100 ) << " %\n";
ss << show( sys.loop.secondary_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.loop.secondary_pump.get_flow_mass() ) << "g/s\n";
ss << "\n\n\n";
ss << show( sys.freight_pump.get_power() * 100 ) << " %\n";
ss << show( sys.freight_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.freight_pump.get_flow_mass() ) << "g/s\n";
rmesh.load_text(ss.str().c_str(), 0.04);
mesh2.bind();
mesh2.set(rmesh, GL_DYNAMIC_DRAW);
}
if(m_switch_2.check_focus()) if(m_switch_2.check_focus())
sys.loop.secondary_pump.powered = !sys.loop.secondary_pump.powered; sys.loop.secondary_pump.powered = !sys.loop.secondary_pump.powered;
if(m_switch_3.check_focus()) if(m_switch_3.check_focus())
sys.freight_pump.powered = !sys.freight_pump.powered; sys.freight_pump.powered = !sys.freight_pump.powered;
}
gm_switch_2.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.secondary_pump.powered ? 0.07 : 0, 0));
void SecondaryLoop::remesh_slow(Mesh& rmesh) gm_switch_3.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.freight_pump.powered ? 0.07 : 0, 0));
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
System& sys = *System::active;
ss << "\n\n";
ss << show( sys.evaporator.get_heat() ) << " C\n";
show_units( ss, sys.evaporator.get_steam_output() ) << "g/s\n";
show_units( ss, sys.evaporator.get_pressure() ) << "Pa\n";
ss << show( sys.evaporator.get_level() / 1000 ) << " / " << show( sys.evaporator.get_volume() / 1000 ) << " kL\n";
ss << "\n\n\n";
ss << show( sys.loop.secondary_pump.get_power() * 100 ) << " %\n";
ss << show( sys.loop.secondary_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.loop.secondary_pump.get_flow_mass() ) << "g/s\n";
ss << "\n\n\n";
ss << show( sys.freight_pump.get_power() * 100 ) << " %\n";
ss << show( sys.freight_pump.get_rpm() ) << " r/min\n";
show_units( ss, sys.freight_pump.get_flow_mass() ) << "g/s\n";
mesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0)));
}
void SecondaryLoop::remesh_fast(Mesh& rmesh)
{
System& sys = *System::active;
float off2 = sys.loop.secondary_pump.powered ? 0.07 : 0;
float off3 = sys.freight_pump.powered ? 0.07 : 0;
rmesh.add(g_switch_2, glm::translate(glm::mat4(1), glm::vec3(0, off2, 0)));
rmesh.add(g_switch_3, glm::translate(glm::mat4(1), glm::vec3(0, off3, 0)));
} }
void SecondaryLoop::render() void SecondaryLoop::render()
{ {
mesh1.bind();
mesh1.uniform();
mesh1.render();
mesh2.bind();
mesh2.uniform();
mesh2.render();
gm_switch_2.bind();
gm_switch_2.uniform();
gm_switch_2.render();
gm_switch_3.bind();
gm_switch_3.uniform();
gm_switch_3.render();
} }

View File

@ -1,31 +1,30 @@
#pragma once #pragma once
#include "../mesh/model.hpp" #include "../mesh/glmesh.hpp"
#include "../mesh/meshgen.hpp"
namespace Sim::Graphics::Monitor namespace Sim::Graphics::Monitor
{ {
class SecondaryLoop : public MeshGen class SecondaryLoop
{ {
glm::mat4 mat; Sim::Graphics::GLMesh mesh1, mesh2;
double clock_at = 0, clock_now = 0;
Mesh g_switch_2; Sim::Graphics::GLMesh gm_switch_2;
Mesh g_switch_3; Sim::Graphics::GLMesh gm_switch_3;
Mesh m_joystick_turbine_bypass; Sim::Graphics::Mesh m_joystick_turbine_bypass;
Mesh m_joystick_turbine_inlet; Sim::Graphics::Mesh m_joystick_turbine_inlet;
Mesh m_switch_2; Sim::Graphics::Mesh m_switch_2;
Mesh m_switch_3; Sim::Graphics::Mesh m_switch_3;
public: public:
SecondaryLoop(const Model& model, Mesh& rmesh); SecondaryLoop();
virtual void update(double dt); void init();
virtual void remesh_slow(Mesh& rmesh); void update(double dt);
virtual void remesh_fast(Mesh& rmesh); void render();
virtual void render();
}; };
}; };

View File

@ -16,33 +16,85 @@ using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor; using namespace Sim::Graphics::Monitor;
using namespace Sim::Util::Streams; using namespace Sim::Util::Streams;
Turbine::Turbine(const Model& model, Mesh& rmesh) Turbine::Turbine()
{ {
mat = Locations::monitors[4];
}
void Turbine::init()
{
mesh1.model_matrix = mesh2.model_matrix = Locations::monitors[4];
mesh1.colour_matrix = mesh2.colour_matrix = {
1, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
std::stringstream ss; std::stringstream ss;
Sim::Graphics::Mesh mesh; Sim::Graphics::Mesh rmesh, rmesh2;
ss << "Turbine\n\n"; ss << "Turbine\n\n";
ss << "Heat\nPressure\nSpeed\n\n"; ss << "Heat\nPressure\nSpeed\n\n";
mesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, mat); rmesh2.load_text("Synchroscope", 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0, 0.6, 0)));
mesh.load_text("Synchroscope", 0.04); mesh1.bind();
rmesh.add(mesh, glm::translate(mat, glm::vec3(0, 0.6, 0))); mesh1.set(rmesh, GL_STATIC_DRAW);
mesh = model.load("visual_synchroscope_dial"); rmesh.load_model("../assets/model", "synchroscope_dial.stl");
gm_synchroscope_dial.bind(); gm_synchroscope_dial.bind();
gm_synchroscope_dial.set(mesh, GL_STATIC_DRAW); gm_synchroscope_dial.set(rmesh, GL_STATIC_DRAW);
g_switch_breaker = model.load("visual_breaker_switch"); rmesh.load_model("../assets/model", "turbine_breaker_switch.glb");
m_switch_breaker = model.load("click_breaker_switch"); gm_switch_breaker.bind();
gm_switch_breaker.set(rmesh, GL_STATIC_DRAW);
m_switch_breaker.load_model("../assets/model", "turbine_breaker_switch_click.stl");
} }
void Turbine::update(double dt) void Turbine::update(double dt)
{ {
System& sys = *System::active; System& sys = *System::active;
clock_now += dt;
if(clock_at + 1.0/30.0 < clock_now)
{
std::stringstream ss;
Sim::Graphics::Mesh rmesh, rmesh2;
clock_at += 1.0/30.0;
ss << "\n\n";
ss << show( sys.loop.turbine.get_heat() ) << " C\n";
ss << show( sys.loop.turbine.get_pressure() / 1000 ) << " kPa\n";
ss << show( sys.loop.generator.get_rpm() ) << " r/min\n";
rmesh2.load_text(ss.str().c_str(), 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.5, 0, 0)));
ss = std::stringstream();
ss << "Local\n\n";
ss << show( sys.loop.generator.get_rpm() / 60 ) << " Hz\n";
Util::Streams::show_units( ss, sys.loop.generator.get_energy_generated() ) << "W\n";
rmesh2.load_text(ss.str().c_str(), 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.4, 0.7, 0)));
ss = std::stringstream();
ss << "Grid\n\n";
ss << show( sys.grid.frequency ) << " Hz\n";
rmesh2.load_text(ss.str().c_str(), 0.04);
rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.7, 0.7, 0)));
mesh2.bind();
mesh2.set(rmesh, GL_DYNAMIC_DRAW);
}
double rpm = sys.loop.generator.get_rpm(); double rpm = sys.loop.generator.get_rpm();
if(rpm > 3570 && rpm < 3630) if(rpm > 3570 && rpm < 3630)
@ -56,49 +108,20 @@ void Turbine::update(double dt)
if(m_switch_breaker.check_focus()) if(m_switch_breaker.check_focus())
sys.loop.generator.breaker_closed = !sys.loop.generator.breaker_closed; sys.loop.generator.breaker_closed = !sys.loop.generator.breaker_closed;
}
void Turbine::remesh_slow(Mesh& rmesh) gm_switch_breaker.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.loop.generator.breaker_closed ? 0.07 : 0, 0));
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
System& sys = *System::active;
ss << "\n\n";
ss << show( sys.loop.turbine.get_heat() ) << " C\n";
ss << show( sys.loop.turbine.get_pressure() / 1000 ) << " kPa\n";
ss << show( sys.loop.generator.get_rpm() ) << " r/min\n";
mesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0)));
ss = std::stringstream();
ss << "Local\n\n";
ss << show( sys.loop.generator.get_rpm() / 60 ) << " Hz\n";
Util::Streams::show_units( ss, sys.loop.generator.get_energy_generated() ) << "W\n";
mesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, glm::translate(mat, glm::vec3(0.4, 0.7, 0)));
ss = std::stringstream();
ss << "Grid\n\n";
ss << show( sys.grid.frequency ) << " Hz\n";
mesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, glm::translate(mat, glm::vec3(0.7, 0.7, 0)));
}
void Turbine::remesh_fast(Mesh& rmesh)
{
System& sys = *System::active;
float off1 = sys.loop.generator.breaker_closed ? 0.07 : 0;
rmesh.add(g_switch_breaker, glm::translate(glm::mat4(1), glm::vec3(0, off1, 0)));
} }
void Turbine::render() void Turbine::render()
{ {
mesh1.bind();
mesh1.uniform();
mesh1.render();
mesh2.bind();
mesh2.uniform();
mesh2.render();
double rpm = System::active->loop.generator.get_rpm(); double rpm = System::active->loop.generator.get_rpm();
if(rpm > 3570 && rpm < 3630) if(rpm > 3570 && rpm < 3630)
@ -107,5 +130,9 @@ void Turbine::render()
gm_synchroscope_dial.uniform(); gm_synchroscope_dial.uniform();
gm_synchroscope_dial.render(); gm_synchroscope_dial.render();
} }
gm_switch_breaker.bind();
gm_switch_breaker.uniform();
gm_switch_breaker.render();
} }

View File

@ -1,28 +1,26 @@
#pragma once #pragma once
#include "../mesh/model.hpp"
#include "../mesh/glmesh.hpp" #include "../mesh/glmesh.hpp"
#include "../mesh/meshgen.hpp"
namespace Sim::Graphics::Monitor namespace Sim::Graphics::Monitor
{ {
class Turbine : public MeshGen class Turbine
{ {
glm::mat4 mat; Sim::Graphics::GLMesh mesh1, mesh2;
double clock_at = 0, clock_now = 0;
GLMesh gm_synchroscope_dial; Sim::Graphics::GLMesh gm_synchroscope_dial;
Mesh g_switch_breaker; Sim::Graphics::GLMesh gm_switch_breaker;
Mesh m_switch_breaker; Sim::Graphics::Mesh m_switch_breaker;
public: public:
Turbine(const Model& model, Mesh& rmesh); Turbine();
virtual void update(double dt); void init();
virtual void remesh_slow(Mesh& rmesh); void update(double dt);
virtual void remesh_fast(Mesh& rmesh); void render();
virtual void render();
}; };
}; };

View File

@ -15,12 +15,25 @@
using namespace Sim::Graphics::Monitor; using namespace Sim::Graphics::Monitor;
using namespace Sim::Util::Streams; using namespace Sim::Util::Streams;
Vessel::Vessel(const Model& model, Mesh& rmesh) Vessel::Vessel()
{ {
mat = Locations::monitors[1];
}
void Vessel::init()
{
mesh1.model_matrix = Locations::monitors[1];
mesh2.model_matrix = glm::translate(mesh1.model_matrix, glm::vec3(0.5, 0, 0));
mesh1.colour_matrix = mesh2.colour_matrix = {
1, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
std::stringstream ss; std::stringstream ss;
Sim::Graphics::Mesh mesh; Sim::Graphics::Mesh rmesh;
ss << "Reactor Vessel\n\n"; ss << "Reactor Vessel\n\n";
ss << "Heat\n"; ss << "Heat\n";
@ -34,23 +47,27 @@ Vessel::Vessel(const Model& model, Mesh& rmesh)
ss << "Temperature\nMin\nMax\n\n"; ss << "Temperature\nMin\nMax\n\n";
ss << "Control Rods\nMin\nMax\nSpeed\n"; ss << "Control Rods\nMin\nMax\nSpeed\n";
mesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, mat); mesh1.bind();
mesh1.set(rmesh, GL_STATIC_DRAW);
} }
void Vessel::update(double dt) void Vessel::update(double dt)
{
}
void Vessel::remesh_slow(Mesh& rmesh)
{ {
std::stringstream ss; std::stringstream ss;
Sim::Graphics::Mesh mesh; Sim::Graphics::Mesh rmesh;
Sim::System& sys = *System::active; Sim::System& sys = *System::active;
clock_now += dt;
if(clock_at + 1.0/30.0 > clock_now)
{
return;
}
double temp_min, temp_max; double temp_min, temp_max;
double crod_min = INFINITY, crod_max = -INFINITY; double crod_min = INFINITY, crod_max = -INFINITY;
clock_at += 1.0/30.0;
sys.reactor.get_stats(Sim::Reactor::Rod::val_t::HEAT, temp_min, temp_max); sys.reactor.get_stats(Sim::Reactor::Rod::val_t::HEAT, temp_min, temp_max);
for(int i = 0; i < sys.reactor.size; i++) for(int i = 0; i < sys.reactor.size; i++)
@ -93,15 +110,19 @@ void Vessel::remesh_slow(Mesh& rmesh)
if(sys.reactor.rod_speed == 0) ss << " (Stopped)"; if(sys.reactor.rod_speed == 0) ss << " (Stopped)";
ss << "\n"; ss << "\n";
mesh.load_text(ss.str().c_str(), 0.04); rmesh.load_text(ss.str().c_str(), 0.04);
rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0))); mesh2.bind();
} mesh2.set(rmesh, GL_DYNAMIC_DRAW);
void Vessel::remesh_fast(Mesh& rmesh)
{
} }
void Vessel::render() void Vessel::render()
{ {
mesh1.bind();
mesh1.uniform();
mesh1.render();
mesh2.bind();
mesh2.uniform();
mesh2.render();
} }

View File

@ -1,23 +1,22 @@
#pragma once #pragma once
#include "../mesh/model.hpp" #include "../mesh/glmesh.hpp"
#include "../mesh/meshgen.hpp"
namespace Sim::Graphics::Monitor namespace Sim::Graphics::Monitor
{ {
class Vessel : public MeshGen class Vessel
{ {
glm::mat4 mat; Sim::Graphics::GLMesh mesh1, mesh2;
double clock_at = 0, clock_now = 0;
public: public:
Vessel(const Model& model, Mesh& rmesh); Vessel();
virtual void update(double dt); void init();
virtual void remesh_slow(Mesh& rmesh); void update(double dt);
virtual void remesh_fast(Mesh& rmesh); void render();
virtual void render();
}; };
}; };

View File

@ -13,8 +13,6 @@ using namespace Sim::Graphics;
Shader Shader::MAIN; Shader Shader::MAIN;
Shader Shader::BLUR; Shader Shader::BLUR;
Shader Shader::LIGHT;
Shader* Shader::ACTIVE;
static int load_shader(const char* src, int type) static int load_shader(const char* src, int type)
{ {
@ -41,12 +39,6 @@ static std::string read_shader(const char* path)
return ss.str(); return ss.str();
} }
static std::string read_shader(const char* base, const char* file)
{
std::string path = std::string(base) + "/" + std::string(file);
return read_shader(path.c_str());
}
Shader::Shader() Shader::Shader()
{ {
@ -68,29 +60,18 @@ Shader::~Shader()
void Shader::load(const char* path, const char* file_vsh, const char* file_fsh) void Shader::load(const char* path, const char* file_vsh, const char* file_fsh)
{ {
load(path, file_vsh, nullptr, file_fsh); std::string path_vsh = std::string(path) + "/" + std::string(file_vsh);
} std::string path_fsh = std::string(path) + "/" + std::string(file_fsh);
std::string shader_vsh = read_shader(path_vsh.c_str());
void Shader::load(const char* path, const char* file_vsh, const char* file_gsh, const char* file_fsh) std::string shader_fsh = read_shader(path_fsh.c_str());
{
std::string shader_vsh = file_vsh ? read_shader(path, file_vsh) : "";
std::string shader_gsh = file_gsh ? read_shader(path, file_gsh) : "";
std::string shader_fsh = file_fsh ? read_shader(path, file_fsh) : "";
int success; int success;
int vsh_id = file_vsh ? load_shader(shader_vsh.c_str(), GL_VERTEX_SHADER) : 0; int vsh_id = load_shader(shader_vsh.c_str(), GL_VERTEX_SHADER);
int gsh_id = file_gsh ? load_shader(shader_gsh.c_str(), GL_GEOMETRY_SHADER) : 0; int fsh_id = load_shader(shader_fsh.c_str(), GL_FRAGMENT_SHADER);
int fsh_id = file_fsh ? load_shader(shader_fsh.c_str(), GL_FRAGMENT_SHADER) : 0;
prog_id = glCreateProgram(); prog_id = glCreateProgram();
if(file_vsh) glAttachShader(prog_id, vsh_id);
glAttachShader(prog_id, vsh_id); glAttachShader(prog_id, fsh_id);
if(file_gsh)
glAttachShader(prog_id, gsh_id);
if(file_fsh)
glAttachShader(prog_id, fsh_id);
glLinkProgram(prog_id); glLinkProgram(prog_id);
glGetProgramiv(prog_id, GL_LINK_STATUS, &success); glGetProgramiv(prog_id, GL_LINK_STATUS, &success);
@ -104,21 +85,13 @@ void Shader::load(const char* path, const char* file_vsh, const char* file_gsh,
} }
glUseProgram(prog_id); glUseProgram(prog_id);
glDeleteShader(vsh_id);
if(file_vsh) glDeleteShader(fsh_id);
glDeleteShader(vsh_id);
if(file_gsh)
glDeleteShader(gsh_id);
if(file_fsh)
glDeleteShader(fsh_id);
ACTIVE = this;
} }
void Shader::use() void Shader::use()
{ {
glUseProgram(prog_id); glUseProgram(prog_id);
ACTIVE = this;
} }
unsigned int Shader::operator [](const char* pos) unsigned int Shader::operator [](const char* pos)
@ -133,8 +106,3 @@ unsigned int Shader::operator [](const char* pos)
return uniform_locations[pos] = glGetUniformLocation(prog_id, pos); return uniform_locations[pos] = glGetUniformLocation(prog_id, pos);
} }
unsigned int Shader::get(const char* pos)
{
return operator[](pos);
}

View File

@ -16,21 +16,16 @@ public:
static Shader MAIN; static Shader MAIN;
static Shader BLUR; static Shader BLUR;
static Shader LIGHT;
static Shader* ACTIVE;
Shader(); Shader();
Shader(const Shader& o) = delete; Shader(const Shader& o) = delete;
Shader(Shader&& o); Shader(Shader&& o);
~Shader(); ~Shader();
void load(const char* path, const char* file_vsh, const char* file_gsh, const char* file_fsh);
void load(const char* path, const char* file_vsh, const char* file_fsh); void load(const char* path, const char* file_vsh, const char* file_fsh);
void use(); void use();
unsigned int operator[](const char* pos); unsigned int operator[](const char* pos);
unsigned int get(const char* pos);
}; };
}; };

View File

@ -18,13 +18,9 @@
using namespace Sim::Graphics; using namespace Sim::Graphics;
static GLMesh gm_ui; static GLMesh s_mesh;
static GLMesh gm_dynamic_slow[2];
static Widget::Clock w_clock; static Widget::Clock w_clock;
static int gm_dynamic_slow_at = 0;
void UI::init() void UI::init()
{ {
Mesh m; Mesh m;
@ -41,8 +37,8 @@ void UI::init()
m.set_indices(indices, 6); m.set_indices(indices, 6);
m.set_vertices(vertices, 4); m.set_vertices(vertices, 4);
gm_ui.bind(); s_mesh.bind();
gm_ui.set(m, GL_STATIC_DRAW); s_mesh.set(m, GL_STATIC_DRAW);
} }
void UI::update(double dt) void UI::update(double dt)
@ -50,17 +46,6 @@ void UI::update(double dt)
w_clock.update(dt); w_clock.update(dt);
} }
void UI::update_slow()
{
Mesh mesh;
w_clock.remesh_slow(mesh);
gm_dynamic_slow[gm_dynamic_slow_at].bind();
gm_dynamic_slow[gm_dynamic_slow_at].set(mesh, GL_DYNAMIC_DRAW);
gm_dynamic_slow_at = (gm_dynamic_slow_at + 1) % 2;
}
void UI::render() void UI::render()
{ {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
@ -72,13 +57,9 @@ void UI::render()
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]); glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]);
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]); glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]);
gm_ui.bind(); s_mesh.bind();
gm_ui.uniform(); s_mesh.uniform();
gm_ui.render(); s_mesh.render();
gm_dynamic_slow[gm_dynamic_slow_at].bind();
gm_dynamic_slow[gm_dynamic_slow_at].uniform();
gm_dynamic_slow[gm_dynamic_slow_at].render();
w_clock.render(); w_clock.render();
} }

View File

@ -6,7 +6,6 @@ namespace Sim::Graphics::UI
void init(); void init();
void update(double dt); void update(double dt);
void update_slow();
void render(); void render();
}; };

View File

@ -19,11 +19,6 @@
using namespace Sim::Graphics::Widget; using namespace Sim::Graphics::Widget;
void Clock::update(double dt) void Clock::update(double dt)
{
this->dt = dt;
}
void Clock::remesh_slow(Mesh& rmesh)
{ {
Mesh m; Mesh m;
double at = System::active->clock; double at = System::active->clock;
@ -34,17 +29,23 @@ void Clock::remesh_slow(Mesh& rmesh)
int t_m = std::fmod(at / 60, 60); int t_m = std::fmod(at / 60, 60);
int t_h = std::fmod(at / 3600, 24); int t_h = std::fmod(at / 3600, 24);
// ss << "FPS: " << (1.0 / dt) << "\n";
ss << "Time: " << std::setfill('0') << std::setw(2) << t_h << ":"; ss << "Time: " << std::setfill('0') << std::setw(2) << t_h << ":";
ss << std::setfill('0') << std::setw(2) << t_m << ":"; ss << std::setfill('0') << std::setw(2) << t_m << ":";
ss << std::setfill('0') << std::setw(2) << t_s << "\n"; ss << std::setfill('0') << std::setw(2) << t_s << "\n";
ss << "Day: " << std::floor(at / (3600 * 24)) << "\n"; ss << "Day: " << std::floor(at / (3600 * 24)) << "\n";
m.load_text(ss.str().c_str(), 20); m.load_text(ss.str().c_str(), 20);
rmesh.add(m, glm::translate(glm::mat4(1), glm::vec3(-wsize + glm::vec2(2, 2), 0)));
data.bind();
data.model_matrix = glm::translate(glm::mat4(1), glm::vec3(-wsize + glm::vec2(2, 2), 0));
data.colour_matrix = Arrays::colour({1, 1, 1, 1});
data.set(m, GL_DYNAMIC_DRAW);
} }
void Clock::render() void Clock::render()
{ {
data.bind();
data.uniform();
data.render();
} }

View File

@ -8,10 +8,9 @@ namespace Sim::Graphics::Widget
struct Clock struct Clock
{ {
double dt; GLMesh data;
void update(double dt); void update(double dt);
void remesh_slow(Mesh& rmesh);
void render(); void render();
}; };

View File

@ -7,8 +7,6 @@
#include <glm/ext/matrix_clip_space.hpp> // glm::perspective #include <glm/ext/matrix_clip_space.hpp> // glm::perspective
#include <iostream> #include <iostream>
#include <vector>
#include <memory>
#include "mesh/mesh.hpp" #include "mesh/mesh.hpp"
#include "mesh/arrays.hpp" #include "mesh/arrays.hpp"
@ -27,10 +25,6 @@
#include "monitor/secondary_loop.hpp" #include "monitor/secondary_loop.hpp"
#include "monitor/turbine.hpp" #include "monitor/turbine.hpp"
#include "mesh/texture.hpp" #include "mesh/texture.hpp"
#include "mesh/model.hpp"
#include "mesh/gllight.hpp"
#include "mesh/meshgen.hpp"
#include "equipment/reactor.hpp"
#include "../system.hpp" #include "../system.hpp"
#include "../util/streams.hpp" #include "../util/streams.hpp"
#include "ui.hpp" #include "ui.hpp"
@ -40,32 +34,20 @@ using namespace Sim::Graphics;
static GLFWwindow* win; static GLFWwindow* win;
static bool win_should_close = false; static bool win_should_close = false;
static unsigned int ssbo_lights; static unsigned int ssbo_lights;
static unsigned int ssbo_shadow_maps;
static double secs_wait_at = 0;
static double secs_wait_now = 0;
static int gm_dynamic_slow_at = 0; static GLMesh mesh_scene;
static GLMesh gm_scene; static Monitor::Vessel monitor_vessel;
static GLMesh gm_transparent; static Monitor::Core monitor_core;
static GLMesh gm_dynamic_slow[2]; static Monitor::PrimaryLoop monitor_primary_loop;
static GLMesh gm_dynamic_fast; static Monitor::SecondaryLoop monitor_secondary_loop;
static Mesh m_dynamic_fast; static Monitor::Turbine monitor_turbine;
static std::vector<GLLight> lights;
static std::vector<std::unique_ptr<MeshGen>> monitors;
static std::vector<std::unique_ptr<MeshGen>> equipment;
glm::mat4 Window::projection_matrix; glm::mat4 Window::projection_matrix;
static void GLAPIENTRY cb_debug_message(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) static void GLAPIENTRY cb_debug_message(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
{ {
if(severity == GL_DEBUG_SEVERITY_HIGH) if(severity != GL_DEBUG_SEVERITY_NOTIFICATION)
{
throw std::runtime_error(message);
}
else if(severity != GL_DEBUG_SEVERITY_NOTIFICATION)
{ {
std::cout << "GL CALLBACK: " << message << "\n"; std::cout << "GL CALLBACK: " << message << "\n";
} }
@ -126,6 +108,7 @@ void Window::create()
Mouse::init(); Mouse::init();
Resize::init(); Resize::init();
Texture::init(); Texture::init();
Camera::init();
Font::init(); Font::init();
UI::init(); UI::init();
@ -133,180 +116,109 @@ void Window::create()
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
Sim::System& sys = *System::active; Sim::System& sys = *System::active;
Mesh m_scene, m_transparent; Mesh m, m2;
Model model("../assets", "scene.glb"); m.load_model("../assets", "scene.glb");
m_transparent = model.load("visual_water");
m_scene = model.load("scene"); // find the floor parts of the model and set them slightly transparent
for(int i = 0; i < m.indices.size(); i += 3)
Camera::init(model); {
Arrays::Vertex& v1 = m.vertices[m.indices[i]];
Arrays::Vertex& v2 = m.vertices[m.indices[i + 1]];
Arrays::Vertex& v3 = m.vertices[m.indices[i + 2]];
if(v1.pos.z <= 0 && v2.pos.z <= 0 && v3.pos.z <= 0)
{
v1.colour.w = 0.95;
v2.colour.w = 0.95;
v3.colour.w = 0.95;
}
}
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 // send all the light data
glGenBuffers(1, &ssbo_lights); glGenBuffers(1, &ssbo_lights);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 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); 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); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo_lights);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glUniform1i(Shader::MAIN["lights_count"], model.lights.size()); glUniform1i(Shader::MAIN["lights_count"], m.lights.size());
monitors.push_back(std::make_unique<Monitor::Core>(model, m_scene)); mesh_scene.bind();
monitors.push_back(std::make_unique<Monitor::Vessel>(model, m_scene)); mesh_scene.set(m, GL_STATIC_DRAW);
monitors.push_back(std::make_unique<Monitor::PrimaryLoop>(model, m_scene));
monitors.push_back(std::make_unique<Monitor::SecondaryLoop>(model, m_scene));
monitors.push_back(std::make_unique<Monitor::Turbine>(model, m_scene));
equipment.push_back(std::make_unique<Equipment::Reactor>(model, m_scene)); monitor_core.init();
monitor_vessel.init();
gm_scene.bind(); monitor_primary_loop.init();
gm_scene.set(m_scene, GL_STATIC_DRAW); monitor_secondary_loop.init();
monitor_turbine.init();
gm_transparent.bind();
gm_transparent.set(m_transparent, GL_STATIC_DRAW);
glfwShowWindow(win); glfwShowWindow(win);
glViewport(0, 0, 800, 600);
// setup lighting and prerender shadows
Shader::LIGHT.load("../assets/shader", "light.vsh", "light.gsh", "light.fsh");
glUniform1f(Shader::LIGHT["far_plane"], 100.0f);
GLLight::init();
std::vector<unsigned long> light_handles;
for(int i = 0; i < model.lights.size(); i++)
{
GLLight light(model.lights[i]);
light.render();
light_handles.push_back(light.handle);
lights.push_back(std::move(light));
}
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);
}
void update_slow()
{
Mesh mesh;
for(auto& monitor : monitors)
{
monitor->remesh_slow(mesh);
}
for(auto& equipment : equipment)
{
equipment->remesh_slow(mesh);
}
gm_dynamic_slow[gm_dynamic_slow_at].bind();
gm_dynamic_slow[gm_dynamic_slow_at].set(mesh, GL_DYNAMIC_DRAW);
gm_dynamic_slow_at = (gm_dynamic_slow_at + 1) % 2;
UI::update_slow();
} }
void Window::update(double dt) void Window::update(double dt)
{ {
Mesh mesh;
glfwPollEvents(); glfwPollEvents();
for(auto& monitor : monitors) monitor_core.update(dt);
{ monitor_vessel.update(dt);
monitor->update(dt); monitor_primary_loop.update(dt);
} monitor_secondary_loop.update(dt);
monitor_turbine.update(dt);
for(auto& equipment : equipment)
{
equipment->update(dt);
}
UI::update(dt); UI::update(dt);
for(auto& monitor : monitors)
{
monitor->remesh_fast(mesh);
}
for(auto& equipment : equipment)
{
equipment->remesh_fast(mesh);
}
if(mesh != m_dynamic_fast)
{
gm_dynamic_fast.bind();
gm_dynamic_fast.set(mesh, GL_DYNAMIC_DRAW);
m_dynamic_fast = std::move(mesh);
}
secs_wait_now += dt;
if(secs_wait_now > secs_wait_at + 1.0/30.0)
{
secs_wait_at += 1.0/30.0;
update_slow();
}
} }
void Window::render_scene() void render_scene()
{ {
gm_scene.bind(); mesh_scene.bind();
gm_scene.uniform(); mesh_scene.uniform();
gm_scene.render(); mesh_scene.render();
gm_dynamic_slow[gm_dynamic_slow_at].bind(); monitor_core.render();
gm_dynamic_slow[gm_dynamic_slow_at].uniform(); monitor_vessel.render();
gm_dynamic_slow[gm_dynamic_slow_at].render(); monitor_primary_loop.render();
monitor_secondary_loop.render();
gm_dynamic_fast.bind(); monitor_turbine.render();
gm_dynamic_fast.uniform();
gm_dynamic_fast.render();
for(auto& monitor : monitors)
{
monitor->render();
}
for(auto& equipment : equipment)
{
equipment->render();
}
gm_transparent.bind();
gm_transparent.uniform();
gm_transparent.render();
Focus::render(); Focus::render();
} }
void Window::render() void Window::render()
{ {
glm::vec<2, int> size = Resize::get_size();
glm::vec3 camera_pos = Camera::get_pos(); glm::vec3 camera_pos = Camera::get_pos();
glm::mat4 mat_camera = Camera::get_matrix(); glm::mat4 mat_camera = Camera::get_matrix();
mat_camera = glm::scale(mat_camera, {1, 1, -1});
Shader::MAIN.use(); camera_pos.z *= -1;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, size.x, size.y);
glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity()); glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity());
glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 100.f); glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 20.f);
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]); glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]);
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]); glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]);
glUniform3fv(Shader::MAIN["camera_pos"], 1, &camera_pos[0]);
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]); glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
glUniform3fv(Shader::MAIN["camera_pos"], 1, &camera_pos[0]);
projection_matrix = mat_projection;
glFrontFace(GL_CCW);
glClearColor(0, 0, 0, 1.0f); glClearColor(0, 0, 0, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
glFrontFace(GL_CW);
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);
render_scene(); render_scene();

View File

@ -15,7 +15,6 @@ bool should_close();
void create(); void create();
void update(double dt); void update(double dt);
void render(); void render();
void render_scene();
void destroy(); void destroy();
void close(); void close();