initial commit

This commit is contained in:
Confideo-IOM
2026-07-17 15:30:29 +01:00
commit 7e8ec5a825
416 changed files with 40308 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
#ifndef GLEWINCLUDES
#define GLEWINCLUDES
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#endif /* GLEWINCLUDES */
+245
View File
@@ -0,0 +1,245 @@
#ifndef HYDRADEFINES
#define HYDRADEFINES
#include <bitset>
#include <cstdint>
#define GLFW_MANAGER 1
//#define GLEW_STATIC
#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
#define OS_Windows 0
#define CLASS_DEFINE
#elif defined(_WIN32) || defined(WIN32) /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
#include <windows.h>
#define WIN32_LEAN_AND_MEAN
#ifdef _EXPORTING
#define CLASS_DEFINE __declspec(dllexport)
#else
#define CLASS_DEFINE __declspec(dllimport)
#endif
#endif
#ifndef PROJECT_DIRS
char const * const texture_base = "C:/Code/HydraV3/Media/Textures/";
char const * const shader_base = "C:/Code/HydraV3/HydraEngine/source/ShaderFiles/";
#define PROJECT_DIRS = 1
#endif
using HydraID = uint32_t;
using byte = uint8_t;
using HydraSignature = std::bitset<64>;
const HydraID INVALID_HYDRA_ID = 4294967295;
const uint32_t MAX_TASKS = 10000;
const uint32_t MAX_MATERIALS = 1000;
const uint32_t MAX_TEXTURES = 1000;
const uint32_t MAX_ACTORS = 10000;
const uint32_t MAX_LIGHTS = 500;
enum class HYDRA_RENDERABLE_TYPE
{
HYDRA_COLOUR = 1,
HYDRA_SHADOW,
HYDRA_TRANSPARENT,
HYDRA_LIGHTING,
HYDRA_OUTPUT
};
enum class HYDRA_BUFFER_TYPE
{
HYDRA_UKNOWN_BUFFER = 0,
HYDRA_UBO_BUFFER = 1,
HYDRA_SSBO_BUFFER = 2,
HYDRA_VERTEX_BUFFER = 3,
HYDRA_INDEX_BUFFER = 4
};
enum class HYDRA_ACTOR_STATE
{
WAITING_FOR_INIT = 0,
ACTIVE = 1,
WAITING_FOR_DELETE = 2
};
enum class HydraThreadAffinity
{
Unknown = 0,
General = 1,
Render = 2,
Physics = 3
};
enum class HYDRA_LIGHT_TYPE
{
HYDRA_LIGHT_DIRECTIONAL = 1,
HYDRA_LIGHT_POINT = 2,
HYDRA_LIGHT_SPOT = 3
};
enum class HYDRA_STATE
{
Empty = 0,
Waiting = 1,
Ready = 2,
Deleted = 3
};
enum class KEY_PRESS_ACTIONS
{
HYDRA_KEY_PRESSED = 1,
HYDRA_KEY_RELEASED = 2
};
enum class HYDRA_KEY_CODES
{
HYDRA_KEY_UNKNOWN =-1,
HYDRA_KEY_SPACE =32,
HYDRA_KEY_APOSTROPHE =39,
HYDRA_KEY_COMMA =44,
HYDRA_KEY_MINUS =45,
HYDRA_KEY_PERIOD =46,
HYDRA_KEY_SLASH =47,
HYDRA_KEY_0 =48,
HYDRA_KEY_1 =49,
HYDRA_KEY_2 =50,
HYDRA_KEY_3 =51,
HYDRA_KEY_4 =52,
HYDRA_KEY_5 =53,
HYDRA_KEY_6 =54,
HYDRA_KEY_7 =55,
HYDRA_KEY_8 =56,
HYDRA_KEY_9 =57,
HYDRA_KEY_SEMICOLON =59,
HYDRA_KEY_EQUAL =61,
HYDRA_KEY_A =65,
HYDRA_KEY_B =66,
HYDRA_KEY_C =67,
HYDRA_KEY_D =68,
HYDRA_KEY_E =69,
HYDRA_KEY_F =70,
HYDRA_KEY_G =71,
HYDRA_KEY_H =72,
HYDRA_KEY_I =73,
HYDRA_KEY_J =74,
HYDRA_KEY_K =75,
HYDRA_KEY_L =76,
HYDRA_KEY_M =77,
HYDRA_KEY_N =78,
HYDRA_KEY_O =79,
HYDRA_KEY_P =80,
HYDRA_KEY_Q =81,
HYDRA_KEY_R =82,
HYDRA_KEY_S =83,
HYDRA_KEY_T =84,
HYDRA_KEY_U =85,
HYDRA_KEY_V =86,
HYDRA_KEY_W =87,
HYDRA_KEY_X =88,
HYDRA_KEY_Y =89,
HYDRA_KEY_Z =90,
HYDRA_KEY_LEFT_BRACKET =91,
HYDRA_KEY_BACKSLASH =92,
HYDRA_KEY_RIGHT_BRACKET =93,
HYDRA_KEY_GRAVE_ACCENT =96,
HYDRA_KEY_WORLD_1 =161,
HYDRA_KEY_WORLD_2 =162,
HYDRA_KEY_ESCAPE =256,
HYDRA_KEY_ENTER =257,
HYDRA_KEY_TAB =258,
HYDRA_KEY_BACKSPACE =259,
HYDRA_KEY_INSERT =260,
HYDRA_KEY_DELETE =261,
HYDRA_KEY_RIGHT =262,
HYDRA_KEY_LEFT =263,
HYDRA_KEY_DOWN =264,
HYDRA_KEY_UP =265,
HYDRA_KEY_PAGE_UP =266,
HYDRA_KEY_PAGE_DOWN =267,
HYDRA_KEY_HOME =268,
HYDRA_KEY_END =269,
HYDRA_KEY_CAPS_LOCK =280,
HYDRA_KEY_SCROLL_LOCK =281,
HYDRA_KEY_NUM_LOCK =282,
HYDRA_KEY_PRINT_SCREEN =283,
HYDRA_KEY_PAUSE =284,
HYDRA_KEY_F1 =290,
HYDRA_KEY_F2 =291,
HYDRA_KEY_F3 =292,
HYDRA_KEY_F4 =293,
HYDRA_KEY_F5 =294,
HYDRA_KEY_F6 =295,
HYDRA_KEY_F7 =296,
HYDRA_KEY_F8 =297,
HYDRA_KEY_F9 =298,
HYDRA_KEY_F10 =299,
HYDRA_KEY_F11 =300,
HYDRA_KEY_F12 =301,
HYDRA_KEY_F13 =302,
HYDRA_KEY_F14 =303,
HYDRA_KEY_F15 =304,
HYDRA_KEY_F16 =305,
HYDRA_KEY_F17 =306,
HYDRA_KEY_F18 =307,
HYDRA_KEY_F19 =308,
HYDRA_KEY_F20 =309,
HYDRA_KEY_F21 =310,
HYDRA_KEY_F22 =311,
HYDRA_KEY_F23 =312,
HYDRA_KEY_F24 =313,
HYDRA_KEY_F25 =314,
HYDRA_KEY_KP_0 =320,
HYDRA_KEY_KP_1 =321,
HYDRA_KEY_KP_2 =322,
HYDRA_KEY_KP_3 =323,
HYDRA_KEY_KP_4 =324,
HYDRA_KEY_KP_5 =325,
HYDRA_KEY_KP_6 =326,
HYDRA_KEY_KP_7 =327,
HYDRA_KEY_KP_8 =328,
HYDRA_KEY_KP_9 =329,
HYDRA_KEY_KP_DECIMAL =330,
HYDRA_KEY_KP_DIVIDE =331,
HYDRA_KEY_KP_MULTIPLY =332,
HYDRA_KEY_KP_SUBTRACT =333,
HYDRA_KEY_KP_ADD =334,
HYDRA_KEY_KP_ENTER =335,
HYDRA_KEY_KP_EQUAL =336,
HYDRA_KEY_LEFT_SHIFT =340,
HYDRA_KEY_LEFT_CONTROL =341,
HYDRA_KEY_LEFT_ALT =342,
HYDRA_KEY_LEFT_SUPER =343,
HYDRA_KEY_RIGHT_SHIFT =344,
HYDRA_KEY_RIGHT_CONTROL =345,
HYDRA_KEY_RIGHT_ALT =346,
HYDRA_KEY_RIGHT_SUPER =347,
HYDRA_KEY_MENU =348
};
struct HydraKeyPressStuct
{
HydraKeyPressStuct() {};
HydraKeyPressStuct(int key_code_in, KEY_PRESS_ACTIONS key_action_in) { key_code = key_code_in; key_action = key_action_in; }
int key_code = -1;
KEY_PRESS_ACTIONS key_action = KEY_PRESS_ACTIONS::HYDRA_KEY_PRESSED;
};
struct HydraMouseMoveStruct
{
HydraMouseMoveStruct() {};
HydraMouseMoveStruct(int x_in, int y_in) { x = x_in; y = y_in; }
int x = 0;
int y = 0;
};
#endif /* HYDRADEFINES */
@@ -0,0 +1,225 @@
//*PIXEL*
#version 460 core
#extension GL_ARB_bindless_texture : require
uint INVALID_HYDRA_ID = 4294967295;
uint DEPTH_TEXTURE_ID = 0;
uint DIFFUSE_TEXTURE_ID = 1;
uint METAL_ROUGH_TEXTURE_ID = 2;
uint NORMAL_TEXTURE_ID = 3;
uint POSITION_TEXTIURE_ID = 4;
struct light_structure
{
vec4 light_colour;
float light_intensity;
uint chunk_id;
uint light_type;
float padding[1];
};
layout(binding = 0) uniform uniform_per_frame
{
mat4 view;
mat4 proj;
vec3 viewer_pos;
uint light_count;
} ubo_per_frame;
layout(binding = 1) uniform uniform_output_textures
{
uint texture_ids[16];
};
layout(binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
layout( std430, binding = 3) readonly buffer TextureBuffer {
uvec2 textures[1000];
};
layout (std430, binding = 4) readonly buffer LightBuffer
{
light_structure lights[500];
};
layout (location=0) in VS_OUT
{
vec2 vsUV;
}vs_out;
layout (location=0) out vec4 uFragColor;
const float PI = 3.14159265358979323846;
const float M_INV_PI = 0.31830988618379067153776752674503;
float sqr(float x) { return x*x; }
// ----------------------------------------------------------------------------
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 nom = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
return nom / denom;
}
// ----------------------------------------------------------------------------
float GeometrySchlickGGX(float NdotV, float roughness)
{
float r = (roughness + 1.0);
float k = (r*r) / 8.0;
float nom = NdotV;
float denom = NdotV * (1.0 - k) + k;
return nom / 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;
}
// ----------------------------------------------------------------------------
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
}
vec3 DirectionalShading(vec3 normal, vec3 diffuse, float roughness, float metallic, float light_intensity, vec3 lightColour, vec3 lightDir, vec3 lightPos, vec3 worldPos, vec3 viewPos)
{
vec3 N = normalize(normal);
vec3 V = normalize(viewPos - worldPos);
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
vec3 F0 = vec3(0.04);
F0 = mix(F0, diffuse, metallic);
// reflectance equation
vec3 Lo = vec3(0.0);
// calculate per-light radiance
vec3 L = normalize(lightDir);
vec3 H = normalize(V + L);
float distance = length(lightPos - worldPos);
float attenuation = 1.0;
// if(light_intensity > 0)
// {
// attenuation = light_intensity / (distance * distance);
// }
vec3 radiance = lightColour * attenuation;
// Cook-Torrance BRDF
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
vec3 numerator = NDF * G * F;
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero
vec3 specular = numerator / denominator;
// kS is equal to Fresnel
vec3 kS = F;
// for energy conservation, the diffuse and specular light can't
// be above 1.0 (unless the surface emits light); to preserve this
// relationship the diffuse component (kD) should equal 1.0 - kS.
vec3 kD = vec3(1.0) - kS;
// multiply kD by the inverse metalness such that only non-metals
// have diffuse lighting, or a linear blend if partly metal (pure metals
// have no diffuse light).
kD *= 1.0 - metallic;
// scale light by NdotL
float NdotL = max(dot(N, L), 0.0);
// add to outgoing radiance Lo
Lo += (kD * diffuse / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
return Lo;
}
mat3 GetRotationOnlyMatrix(mat4 model_mat)
{
mat3 rot_mat;
rot_mat[0] = model_mat[0].xyz;
rot_mat[1] = model_mat[1].xyz;
rot_mat[2] = model_mat[2].xyz;
return rot_mat;
}
void main()
{
uvec2 diffuse_handle = textures[texture_ids[DIFFUSE_TEXTURE_ID]];
uvec2 normal_handle = textures[texture_ids[NORMAL_TEXTURE_ID]];
uvec2 metal_rough_handle = textures[texture_ids[METAL_ROUGH_TEXTURE_ID]];
uvec2 world_pos_handle = textures[texture_ids[POSITION_TEXTIURE_ID]];
vec4 diffuse = texture(sampler2D(diffuse_handle), vs_out.vsUV.xy);
if(diffuse[3] <= 0.1)
{
discard;
}
vec3 normal = texture(sampler2D(normal_handle), vs_out.vsUV.xy).xyz;
vec3 metal_rough = texture(sampler2D(metal_rough_handle), vs_out.vsUV.xy).xyz;
vec3 world_pos = texture(sampler2D(world_pos_handle), vs_out.vsUV.xy).xyz;
float rough = metal_rough[1];
float metal = metal_rough[2];
vec3 Lo = vec3(0,0,0);
for(int i = 0; i < ubo_per_frame.light_count; i ++)
{
mat4 model = model_matrix[lights[i].chunk_id];
mat3 rot_mat = GetRotationOnlyMatrix(model);
vec3 light_direction = rot_mat * vec3(0,0,1);
vec3 light_pos = model[3].xyz;
vec3 colour = DirectionalShading(normal, diffuse.xyz, rough, metal, lights[i].light_intensity, lights[i].light_colour.xyz, light_direction, light_pos, world_pos, ubo_per_frame.viewer_pos);
Lo = colour;
//uFragColor = vec4(light_direction, 1);
}
float lighting = 0;
// ambient lighting (note that the next IBL tutorial will replace
// this ambient lighting with environment lighting).
float ao = 1;
vec3 ambient = vec3(0.05) * diffuse.xyz * ao;
vec3 output_color = ambient + Lo;
// HDR tonemapping
output_color = output_color / (output_color + vec3(1.0));
// gamma correct
output_color = pow(output_color, vec3(1.0/2.1));
uFragColor = vec4(output_color, 1.0);
// float light = dot(lights[0].light_direction, normal);
// uFragColor = vec4(diffuse.xyz * light,1);
// uFragColor = vec4(normal, 1);
}
@@ -0,0 +1,39 @@
#version 460 core
#extension GL_ARB_bindless_texture : require
layout(binding = 0) uniform uniform_per_frame
{
mat4 view;
mat4 proj;
vec3 viewer_pos;
uint light_count;
} ubo_per_frame;
layout(binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
layout (location = 0) in vec3 inPos; //12 bytes : 0
layout (location = 1) in vec2 inUV; //8 Bytes : 12
layout (location = 2) in uvec3 inChunkID; //12 Bytes : 20
layout (location = 3) in vec3 inNormal; //8 Bytes : 12
layout (location = 4) in vec3 inBiTangent;
layout (location = 5) in vec3 inTangent;
layout(location=0) out VS_OUT
{
vec2 vsUV;
}vs_out;
void main()
{
mat4 view = ubo_per_frame.view;
mat4 proj = ubo_per_frame.proj;
gl_Position = proj * view * vec4(inPos, 1.0);
vs_out.vsUV = inUV;
}
@@ -0,0 +1,79 @@
//*PIXEL*
#version 460 core
#extension GL_ARB_bindless_texture : require
uint INVALID_HYDRA_ID = 4294967295;
struct MaterialStore
{
vec4 diffuse_colour;
vec4 matalic_rough;
uint diffuse_texture_id;
uint metallic_rough_texture_id;
uint normal_texture_id;
uint padding[1];
};
layout(binding = 2, std430) readonly buffer MaterialBuffer
{
MaterialStore materials[1000];
};
layout( std430, binding = 3) readonly buffer TextureBuffer {
uvec2 textures[1000];
};
layout (location=0) in VS_OUT
{
vec2 vsUV;
vec4 vsWorldPos;
vec3 vsNormal;
vec3 vsBiTangent;
vec3 vsTangent;
mat3 vsTBN;
flat uint vsChunkID;
flat uint vsMaterialID;
}vs_out;
layout (location=0) out vec4 diffuse_out;
layout (location=1) out vec4 metalic_rough_out;
layout (location=2) out vec4 normal_out;
layout (location=3) out vec4 position_out;
void main()
{
MaterialStore mat = materials[vs_out.vsMaterialID];
vec4 diffuse_val = mat.diffuse_colour;
vec4 mat_rough_val =mat.matalic_rough;
vec3 normal_val = vs_out.vsNormal;
if(mat.diffuse_texture_id != INVALID_HYDRA_ID)
{
uvec2 diffuse_handle = textures[mat.diffuse_texture_id];
diffuse_val = diffuse_val * texture(sampler2D(diffuse_handle), vs_out.vsUV.xy);
}
if(mat.metallic_rough_texture_id != INVALID_HYDRA_ID)
{
uvec2 metal_rough_handle = textures[mat.metallic_rough_texture_id];
mat_rough_val = texture(sampler2D(metal_rough_handle), vs_out.vsUV.xy);
}
if(mat.normal_texture_id != INVALID_HYDRA_ID)
{
uvec2 normal_handle = textures[mat.normal_texture_id];
normal_val = texture(sampler2D(normal_handle), vs_out.vsUV.xy).xyz;
normal_val = (normal_val * 2.0) - 1.0;
normal_val = normalize(vs_out.vsTBN * normal_val);
}
if(diffuse_val[3] <= 0.4)
{
discard;
}
diffuse_out = diffuse_val;
metalic_rough_out = mat_rough_val;
normal_out = vec4(normal_val,1);
position_out = vs_out.vsWorldPos;
}
@@ -0,0 +1,56 @@
#version 460 core
#extension GL_ARB_bindless_texture : require
layout(binding = 0) uniform uniform_per_frame
{
mat4 view;
mat4 proj;
vec3 viewer_pos;
uint light_count;
} ubo_per_frame;
layout(binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
layout (location = 0) in vec3 inPos; //12 bytes : 0
layout (location = 1) in vec2 inUV; //8 Bytes : 12
layout (location = 2) in uvec3 inChunkID; //12 Bytes : 20
layout (location = 3) in vec3 inNormal; //8 Bytes : 12
layout (location = 4) in vec3 inBiTangent;
layout (location = 5) in vec3 inTangent;
layout(location=0) out VS_OUT
{
vec2 vsUV;
vec4 vsWorldPos;
vec3 vsNormal;
vec3 vsBiTangent;
vec3 vsTangent;
mat3 vsTBN;
flat uint vsChunkID;
flat uint vsMaterialID;
}vs_out;
void main()
{
uint chunkid = inChunkID[0];
mat4 model = model_matrix[chunkid];
mat4 view = ubo_per_frame.view;
mat4 proj = ubo_per_frame.proj;
//model = mat4(1);
gl_Position = proj * view * model * vec4(inPos, 1.0);
vs_out.vsWorldPos = model * vec4(inPos,1);
vs_out.vsNormal = normalize(vec3(model * vec4(normalize(inNormal),0)));
vs_out.vsTangent = normalize(vec3(model *vec4(inTangent,0))) ;
vs_out.vsBiTangent = normalize(vec3(model *vec4(inBiTangent,0)));
vs_out.vsTBN = mat3(vs_out.vsTangent, vs_out.vsBiTangent, vs_out.vsNormal);
vs_out.vsUV = inUV;
vs_out.vsChunkID = chunkid;
vs_out.vsMaterialID = inChunkID[1];
}
@@ -0,0 +1,58 @@
//*PIXEL*
#version 460 core
#extension GL_ARB_bindless_texture : require
uint INVALID_HYDRA_ID = 4294967295;
struct MaterialStore
{
vec4 diffuse_colour;
uint diffuse_texture_id;
uint padding[3];
};
layout(binding = 2, std430) readonly buffer MaterialBuffer
{
MaterialStore materials[1000];
};
layout( std430, binding = 3) readonly buffer TextureBuffer {
uvec2 textures[1000];
};
layout (location=0) in VS_OUT
{
vec2 vsUV;
vec4 vsWorldPos;
vec4 normal;
flat uint vsChunkID;
flat uint vsMaterialID;
}vs_out;
layout (location=0) out vec4 uFragColor;
void main()
{
MaterialStore mat = materials[vs_out.vsMaterialID];
//uvec2 tex_handle = textures[mat.diffuse_texture_id];
uvec2 handle = textures[mat.diffuse_texture_id];
// 2. Explicitly cast the 64-bit integer handle to a sampler type
// sampler2D tex = sampler2D(handle);
// 3. Sample the texture normally
vec4 output_colour = texture(sampler2D(handle), vs_out.vsUV.xy);
if(output_colour[3] <= 0.1)
{
discard;
}
uFragColor = output_colour;
//uFragColor = vec4(vs_out.vsUV.x, vs_out.vsUV.y, 1, 1);
}
@@ -0,0 +1,41 @@
#version 460 core
#extension GL_ARB_bindless_texture : require
layout(binding = 0) uniform uniform_per_frame
{
mat4 view;
mat4 proj;
vec3 viewer_pos;
uint light_count;
} ubo_per_frame;
layout(binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
layout (location = 0) in vec3 inPos; //12 bytes : 0
layout (location = 1) in vec2 inUV; //8 Bytes : 12
layout (location = 2) in uvec3 inChunkID; //12 Bytes : 20
layout(location=0) out VS_OUT
{
vec2 vsUV;
vec4 vsWorldPos;
flat uint vsChunkID;
flat uint vsMaterialID;
}vs_out;
void main()
{
uint chunkid = inChunkID[0];
mat4 model = model_matrix[chunkid];
mat4 view = ubo_per_frame.view;
mat4 proj = ubo_per_frame.proj;
//model = mat4(1);
gl_Position = proj * view * model * vec4(inPos, 1.0);
vs_out.vsWorldPos = model * vec4(inPos,1);
vs_out.vsUV = inUV;
vs_out.vsChunkID = chunkid;
vs_out.vsMaterialID = inChunkID[1];
}
+4
View File
@@ -0,0 +1,4 @@
#include "HydraActor.h"
#include "HydraActorManager.h"
#include "../engine/HydraEngine.h"
+34
View File
@@ -0,0 +1,34 @@
#ifndef HYDRAACTOR
#define HYDRAACTOR
#include "../engine/HydraObject.h"
//#include "HydraActorManager.h"
#include <vector>
//class HydraComponent;
class CLASS_DEFINE HydraActor : public HydraObject
{
private:
HYDRA_ACTOR_STATE m_status = HYDRA_ACTOR_STATE::WAITING_FOR_INIT;
HydraID m_id = INVALID_HYDRA_ID;
HydraID m_parent_id = INVALID_HYDRA_ID;
std::vector<HydraID> m_children;
std::vector<uint32_t> m_component_types;
uint32_t m_components_waiting = 0;
friend class HydraActorManager;
friend class HydraDeleteActorTask;
protected:
bool m_fixed_tick =false;
public:
std::string Name;
virtual ~HydraActor(){};
virtual void InitialiseComponents() = 0;
virtual void DeferredInitialiseComponents() {};
HydraID GetID() {return m_id;}
virtual void FixedTick(float delta_t) {};
virtual void Destroy() = 0;
};
#endif /* HYDRAACTOR */
@@ -0,0 +1,525 @@
//
#include "HydraActorManager.h"
#include "../actor/HydraActor.h"
#include "../engine/HydraEngine.h"
#include "../ecs/HydraEntityManager.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/systems/HydraTransformSystem.h"
#include "../fileaccess/HydraGLTFLoader.h"
#include "../task/actor/HydraLoadGLTFFileTask.hpp"
#include "../scheduler/HydraTaskScheduler.h"
#include <stdio.h>
HydraActor *const HydraActorManager::GetActor(HydraID actorID)
{
if (actorID < MAX_ACTORS)
{
return m_actors[actorID];
}
return nullptr;
}
std::vector<HydraID> &HydraActorManager::GetChildren(HydraID actor_id)
{
return m_actors[actor_id]->m_children;
}
void HydraActorManager::DeleteActor(HydraID actorID)
{
m_actors_waiting_for_delete.push_back(actorID);
}
void HydraActorManager::_SetActorDeleted(HydraID actorID)
{
if (m_actors[actorID] != nullptr)
{
delete m_actors[actorID];
}
m_actors[actorID] = nullptr;
m_available_actor_ids.push_back(actorID);
}
HydraID HydraActorManager::LoadActor(std::string filename)
{
HydraID actor_id = INVALID_HYDRA_ID;
HydraTaskScheduler* task_scheduler = GetEngine()->TaskScheduler();
HydraID load_task_id = task_scheduler->CreateTask<HydraLoadGLTFFileTask>(HydraThreadAffinity::Render);
HydraLoadGLTFFileTask* load_task = static_cast<HydraLoadGLTFFileTask*>(task_scheduler->GetTask(load_task_id));
load_task->Initialise(filename, &actor_id);
task_scheduler->WaitForTask(load_task_id);
return actor_id;
}
/*
HydraID HydraActorManager::_ProcessGLTFNode(aiScene const *scene, aiNode *parent_node, std::vector<uint32_t>material_lookup)
{
HydraID parent_actor_id = CreateActor<HydraGLTFActor>();
HydraECS *ecs = GetEngine()->ECS();
HydraECSPositionComponent position_component;
aiVector3D tmp_scaling = {};
aiQuaternion tmp_rotation = {};
aiVector3D tmp_position = {};
parent_node->mTransformation.Decompose(tmp_scaling, tmp_rotation, tmp_position);
glm::dvec3 scaling = glm::dvec3(tmp_scaling.x, tmp_scaling.y, tmp_scaling.z);
glm::quat rotation = glm::quat(tmp_rotation.w, tmp_rotation.x, tmp_rotation.y, tmp_rotation.z);
glm::dvec3 position = glm::dvec3(tmp_position.x, tmp_position.y, tmp_position.z);
ecs->AddComponent<HydraECSPositionComponent>(parent_actor_id, position_component);
SetPosition(parent_actor_id, position, rotation, false);
for (uint32_t i_mesh = 0; i_mesh < parent_node->mNumMeshes; i_mesh++)
{
aiMesh *mesh = scene->mMeshes[parent_node->mMeshes[i_mesh]];
_ProcessGLTFMesh(scene, parent_actor_id, mesh, material_lookup);
}
for (uint32_t i_node = 0; i_node < parent_node->mNumChildren; i_node++)
{
HydraID child_actor_id = _ProcessGLTFNode(scene, parent_node->mChildren[i_node], material_lookup);
SetRelationship(parent_actor_id, child_actor_id);
}
return parent_actor_id;
}
void HydraActorManager::_ProcessGLTFMesh(aiScene const *scene, HydraID parent_actor_id, aiMesh *mesh, std::vector<uint32_t>material_lookup)
{
HydraID mesh_actor_id = CreateActor<HydraGLTFActor>();
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
std::vector<StandardVertexStruct> vertexes;
HydraECS *ecs = GetEngine()->ECS();
HydraECSPositionComponent position_component = {};
ecs->AddComponent<HydraECSPositionComponent>(mesh_actor_id, position_component);
for (uint32_t i_face = 0; i_face < mesh->mNumFaces; i_face++)
{
aiFace face = mesh->mFaces[i_face];
for (uint32_t i_index = 0; i_index < face.mNumIndices; i_index++)
{
uint32_t current_idx = face.mIndices[i_index];
StandardVertexStruct vert = {};
if (mesh->HasPositions())
{
vert.vertex[0] = mesh->mVertices[current_idx].x;
vert.vertex[1] = mesh->mVertices[current_idx].y;
vert.vertex[2] = mesh->mVertices[current_idx].z;
}
if (mesh->HasNormals())
{
vert.normal[0] = mesh->mNormals[current_idx].x;
vert.normal[1] = mesh->mNormals[current_idx].y;
vert.normal[2] = mesh->mNormals[current_idx].z;
}
if (mesh->HasTextureCoords(0))
{
vert.uv[0] = mesh->mTextureCoords[0][current_idx].x;
vert.uv[1] = mesh->mTextureCoords[0][current_idx].y;
}
vert.indexes[0] = mesh_actor_id;
vertexes.push_back(vert);
}
}
HydraMeshManager *mesh_manager = GetEngine()->MeshManager();
HydraID mesh_id = mesh_manager->CreateMesh(mesh_actor_id);
mesh_manager->SetVertexes(mesh_id, vertexes);
mesh_manager->CalculateNormals(mesh_id);
HydraECSMeshComponent mesh_comp;
mesh_comp.mesh_id = mesh_id;
ecs->AddComponent<HydraECSMeshComponent>(mesh_actor_id, mesh_comp);
aiString mat_name;
mat->Get(AI_MATKEY_NAME, mat_name);
HydraID material_id = material_lookup[mesh->mMaterialIndex];
if(material_id != INVALID_HYDRA_ID)
{
HydraECSMaterialComponent mat_comp;
mat_comp.material_id = material_id;
ecs->AddComponent<HydraECSMaterialComponent>(mesh_actor_id, mat_comp);
HydraMaterialStruct const * const mat_data = GetEngine()->MaterialManager()->GetMaterial(material_id);
GetEngine()->BufferManager()->AddMaterial(mesh_actor_id, material_id, *mat_data);
}
mesh_manager->SetMeshWaiting(mesh_id);
//Add renderable component
HydraPipelineManager* pipeline_manager = GetEngine()->PipelineManager();
uint32_t pipeline_id = pipeline_manager->GetPipelineID("FORWARD");
uint32_t shadow_pipeline_id = pipeline_manager->GetPipelineID("SHADOW");
uint32_t deferred_pipeline_id = pipeline_manager->GetPipelineID("DEFERRED");
HydraECSRenderableComponent render_comp;
if(pipeline_id != INVALID_HYDRA_ID)
{
render_comp.pipelines.set(pipeline_id);
}
render_comp.pipelines.set(shadow_pipeline_id);
render_comp.pipelines.set(deferred_pipeline_id);
ecs->AddComponent<HydraECSRenderableComponent>(mesh_actor_id, render_comp);
SetRelationship(parent_actor_id, mesh_actor_id);
}
/// @brief Load all of the scene textures
/// @param scene containing scene
/// @param texture_lookup index of texture in the scene to the Hydra texture ID
void HydraActorManager::_ProcessGLTFTextures(aiScene const *scene, std::vector<uint32_t> &texture_lookup)
{
HydraTextureManager *texture_manager = GetEngine()->TextureManager();
// Make space for the texture lookups
texture_lookup.resize(scene->mNumTextures);
for (uint32_t i_tex = 0; i_tex < scene->mNumTextures; i_tex++)
{
aiTexture *tex = scene->mTextures[i_tex];
// Create a holder for the texture
HydraID texture_id = texture_manager->CreateTexture(0, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false);
// load the texture data from the scene texture
texture_manager->FillTexture(texture_id, reinterpret_cast<unsigned char *>(tex->pcData), tex->mWidth);
// store the texture id against the scene index for the texture. Materials will have *n where n is the index
texture_lookup[i_tex] = texture_id;
texture_manager->FinaliseTexture(texture_id);
}
}
void HydraActorManager::_ProcessGLTFMaterials(aiScene const *scene,
std::vector<uint32_t>& texture_lookup,
std::vector<uint32_t>& material_lookup,
std::string filename)
{
material_lookup.resize(scene->mNumMaterials);
HydraTextureManager *texture_manager = GetEngine()->TextureManager();
for (uint32_t i_mat = 0; i_mat < scene->mNumMaterials; i_mat++)
{
HydraMaterialStruct material;
aiMaterial *mat = scene->mMaterials[i_mat];
aiColor3D color(0.f, 0.f, 0.f);
aiString name;
mat->Get(AI_MATKEY_COLOR_DIFFUSE, color);
mat->Get(AI_MATKEY_NAME, name);
std::string mat_name = filename + std::to_string(i_mat);
aiTexture diffuse_tex;
uint32_t diffuse_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_DIFFUSE);
// have to do something here for multiple diffuse textures at some point.
aiString texture_path;
aiTextureMapping texture_mapping;
uint32_t uv_index;
if (diffuse_tex_count > 0)
{
mat->GetTexture(aiTextureType::aiTextureType_DIFFUSE, 0, &texture_path, &texture_mapping, &uv_index);
std::string path = std::string(texture_path.C_Str());
uint32_t texture_index = atoi(path.substr(1).c_str());
HydraID texture_id = texture_lookup[texture_index];
material.diffuse_texture = texture_id;
material.texture_types += static_cast<uint32_t>(HYDRA_TEXTURE_TYPE::DIFFUSE_TEXTURE);
}
material.diffuse_colour = glm::vec4(color.r, color.g, color.b, 1);
HydraID material_id = GetEngine()->MaterialManager()->CreateMaterial(mat_name, material);
material_lookup[i_mat] = material_id;
if (material_id == INVALID_HYDRA_ID)
{
throw std::runtime_error("Could not create material");
}
}
}
*/
HydraID HydraActorManager::_SaveActor(HydraActor *actor)
{
HydraECS *ecs = GetEngine()->ECS();
if (m_available_actor_ids.size() > 0)
{
HydraID id = m_available_actor_ids.front();
m_available_actor_ids.pop_front();
actor->m_id = id;
m_actors[id] = actor;
return id;
}
delete actor;
return INVALID_HYDRA_ID;
}
void HydraActorManager::Initialise(size_t max_actors)
{
m_max_actors = max_actors;
std::lock_guard<std::mutex> lock(m_mutex);
m_actors.resize(max_actors);
for (int i = 0; i < max_actors; i++)
{
m_available_actor_ids.push_back(i);
}
}
void HydraActorManager::TickActors(float delta_t)
{
// std::lock_guard<std::mutex> lock(m_mutex);
// // HydraID barrierID = GetEngine()->TaskScheduler()->CreateBarrier();
// for (int i = 0; i < m_actors_to_tick_fixed.size(); i++)
// {
// HydraID tick_actors_task_id = GetEngine()->TaskScheduler()->CreateTask<HydraFixedTickActorTask>(HydraThreadAffinity::General);
// if (tick_actors_task_id != INVALID_HYDRA_ID)
// {
// ((HydraFixedTickActorTask *)(GetEngine()->TaskScheduler()->GetTask(tick_actors_task_id)))->Initialise(m_actors_to_tick_fixed[i], delta_t);
// GetEngine()->TaskScheduler()->StartTask(tick_actors_task_id);
// }
// }
// GetEngine()->TaskScheduler()->WaitForBarrier(barrierID);
}
void HydraActorManager::InitialiseActor(HydraID actorID)
{
HydraActor *actor = GetActor(actorID);
if (actor != nullptr)
{
// actor->InitialiseComponents();
m_actors_waiting_for_init.push_back(actorID);
}
}
void HydraActorManager::Shutdown()
{
std::lock_guard<std::mutex> lock(m_mutex);
// for (HydraID actor_id = 0; actor_id < MAX_ACTORS; actor_id++)
// {
// if (m_actors[actor_id] != nullptr)
// {
// HydraActor *actor = m_actors[actor_id];
// m_actors[actor_id]->m_status = HydraActorStatus::WAITING_FOR_DELETE;
// _RemoveActorFromTickFixed(actor_id);
// _RemoveActorFromWaiting(actor_id);
// actor->Destroy();
// // for (int i = 0; i < m_actors[actor_id]->m_component_types.size(); i++)
// // {
// // GetEngine()->ComponentManager()->DeleteComponent(m_actors[actor_id]->m_component_types[i], actor_id);
// // }
// // HydraID delete_task_id = GetEngine()->TaskScheduler()->CreateTask<HydraDeleteActorTask>(HydraThreadAffinity::General);
// // HydraDeleteActorTask *task = (HydraDeleteActorTask *)GetEngine()->TaskScheduler()->GetTask(delete_task_id);
// // task->Initialise(actor_id);
// // GetEngine()->TaskScheduler()->WaitForTask(delete_task_id);
// }
// _SetActorDeleted(actor_id);
// }
}
void HydraActorManager::RotateActor(HydraID actorID, float euler_x, float euler_y, float euler_z)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actorID);
pos_comp.orientation[0] += euler_x;
pos_comp.orientation[1] += euler_y;
pos_comp.orientation[2] += euler_z;
pos_comp.needs_update = true;
ecs->GetSystem<HydraTransformSystem>()->UpdateTransform(actorID);
}
void HydraActorManager::SetPosition(HydraID actorID, glm::dvec3 position)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actorID);
pos_comp.position = position;
// if (ecs->HasComponent<HydraECSPhysicsComponent>(actorID))
// {
// HydraECSPhysicsComponent &phys_comp = ecs->GetComponent<HydraECSPhysicsComponent>(actorID);
// // const float* matrix = glm::value_ptr<float>(GetActorPose(actorID));
// phys_comp.physics_definition.pose = GetActorPose(actorID);
// }
if(!pos_comp.needs_update)
{
ecs->GetSystem<HydraTransformSystem>()->UpdateTransform(actorID);
}
}
void HydraActorManager::SetOrientation(HydraID actorID, float x, float y, float z)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actorID);
pos_comp.orientation = glm::vec3(x, y, z);
if(!pos_comp.needs_update)
{
// if (ecs->HasComponent<HydraECSPhysicsComponent>(actorID))
// {
// HydraECSPhysicsComponent &phys_comp = ecs->GetComponent<HydraECSPhysicsComponent>(actorID);
// phys_comp.physics_definition.pose = GetActorPose(actorID);
// }
ecs->GetSystem<HydraTransformSystem>()->UpdateTransform(actorID);
}
}
void HydraActorManager::SetScale(HydraID actor_id, glm::dvec3 scaling)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actor_id);
pos_comp.scale = glm::vec3(scaling);
// if (ecs->HasComponent<HydraECSPhysicsComponent>(actorID))
// {
// HydraECSPhysicsComponent &phys_comp = ecs->GetComponent<HydraECSPhysicsComponent>(actorID);
// phys_comp.physics_definition.pose = GetActorPose(actorID);
// }
if(!pos_comp.needs_update)
{
ecs->GetSystem<HydraTransformSystem>()->UpdateTransform(actor_id);
}
}
void HydraActorManager::SetRelationship(HydraID parent_id, HydraID child_id)
{
HydraActor *parent_actor = GetActor(parent_id);
HydraActor *child_actor = GetActor(child_id);
child_actor->m_parent_id = parent_id;
parent_actor->m_children.push_back(child_id);
}
void HydraActorManager::TranslateActor(HydraID actorID, glm::dvec3 translation)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actorID);
pos_comp.position = pos_comp.position + translation;
// if (ecs->HasComponent<HydraECSPhysicsComponent>(actorID))
// {
// HydraECSPhysicsComponent &phys_comp = ecs->GetComponent<HydraECSPhysicsComponent>(actorID);
// // const float* matrix = glm::value_ptr<float>(GetActorPose(actorID));
// // std::copy(matrix, matrix + 16, phys_comp.physics_definition.pose);
// phys_comp.physics_definition.pose = GetActorPose(actorID);
// }
ecs->GetSystem<HydraTransformSystem>()->UpdateTransform(actorID);
}
void HydraActorManager::AddComponentType(HydraID actorID, uint32_t component_type)
{
if (actorID < m_actors.size())
{
HydraActor *actor = m_actors[actorID];
if (actor != nullptr)
{
actor->m_component_types.push_back(component_type);
actor->m_components_waiting++;
}
}
}
glm::mat4 HydraActorManager::GetActorPose(HydraID actorID)
{
HydraPositionComponent &pos = GetEngine()->ECS()->GetComponent<HydraPositionComponent>(actorID);
glm::mat4 model_matrix = pos.transform;
// if (pos.needs_update)
// {
// glm::mat4 trans_matrix = glm::translate(pos.position);
// glm::mat4 rot_matrix = glm::toMat4(glm::quat(pos.orientation));
// model_matrix = trans_matrix * rot_matrix;
// }
return model_matrix;
}
glm::vec3 HydraActorManager::GetActorOrientation(HydraID actorID)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actorID);
return pos_comp.orientation;
}
glm::vec3 HydraActorManager::GetActorVelocity(HydraID actorID)
{
return glm::dvec3(0, 0, 0);
}
glm::dvec3 HydraActorManager::GetActorPosition(HydraID actorID)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actorID);
return pos_comp.position;
}
bool HydraActorManager::HasComponentType(HydraID actorID, uint32_t component_type)
{
if (actorID < m_actors.size())
{
HydraActor *actor = m_actors[actorID];
if (actor != nullptr)
{
for (int i = 0; i < actor->m_component_types.size(); i++)
{
if (actor->m_component_types[i] == component_type)
{
return true;
}
}
}
}
return false;
}
void HydraActorManager::RemoveComponentType(HydraID actorID, uint32_t component_type)
{
if (actorID < m_actors.size())
{
HydraActor *actor = m_actors[actorID];
if (actor != nullptr)
{
uint32_t comp_type = static_cast<uint32_t>(component_type);
if (actor->m_component_types.size() > comp_type)
{
actor->m_component_types.erase(actor->m_component_types.begin() + comp_type);
}
}
}
}
HydraID HydraActorManager::GetParent(HydraID actor_id)
{
return m_actors[actor_id]->m_parent_id;
}
HydraID HydraActorManager::GetRoot(HydraID actor_id)
{
HydraID parent_id = GetParent(actor_id);
if(parent_id == INVALID_HYDRA_ID)
{
return actor_id;
}
return GetRoot(parent_id);
}
@@ -0,0 +1,96 @@
#ifndef HYDRAACTORMANAGER
#define HYDRAACTORMANAGER
#include "../engine/HydraObject.h"
#include "../task/HydraTask.h"
#include "HydraActor.h"
#include <GLMIncludes.h>
#include <mutex>
#include <vector>
#include <deque>
#include <queue>
// #include <assimp/Importer.hpp> // C++ importer interface
// #include <assimp/scene.h> // Output data structure
// #include <assimp/postprocess.h> // Post processing flags
class CLASS_DEFINE HydraActorManager : public HydraObject
{
private:
std::mutex m_mutex;
std::vector<HydraActor*> m_actors;
std::deque<HydraID> m_available_actor_ids;
std::deque<HydraID> m_actors_waiting_for_init;
std::deque<HydraID> m_actors_waiting_for_delete;
size_t m_max_actors;
HydraID _SaveActor(HydraActor* actor);
void _RemoveActorFromWaiting(HydraID actorID);
void _RemoveActorFromTickFixed(HydraID actorID);
void _SetActorDeleted(HydraID actorID);
public:
void Initialise(size_t max_actors);
template<class T> HydraID CreateActor();
HydraID LoadActor(std::string filename);
void DeleteActor(HydraID actorID);
HydraActor* const GetActor(HydraID actorID);
std::vector<HydraID>& GetChildren(HydraID actor_id);
void TickActors(float delta_t);
void InitialiseActor(HydraID actorID);
void Shutdown();
void RotateActor(HydraID actorID, float euler_x, float euler_y, float euler_z);
void SetPosition(HydraID actorID, glm::dvec3 position);
void SetOrientation(HydraID actorID, float x, float y, float z);
void SetScale(HydraID actor_id, glm::dvec3 scaling);
void TranslateActor(HydraID actorID, glm::dvec3 translation);
void SetRelationship(HydraID parent_id, HydraID child_id);
void AddComponentType(HydraID actorID, uint32_t component_type);
bool HasComponentType(HydraID actorID, uint32_t component_type);
void RemoveComponentType(HydraID actorID, uint32_t component_type);
HydraID GetParent(HydraID actor_id);
HydraID GetRoot(HydraID actor_id);
glm::mat4 GetActorPose(HydraID actorID);
glm::dvec3 GetActorPosition(HydraID actorID);
glm::vec3 GetActorOrientation(HydraID actorID);
glm::vec3 GetActorVelocity(HydraID actorID);
};
template<class T>
inline HydraID HydraActorManager::CreateActor()
{
T* actorType = new T();
HydraActor* actor = dynamic_cast<HydraActor*>(actorType);
if (actor != nullptr)
{
HydraID actor_id = INVALID_HYDRA_ID;
{
std::lock_guard<std::mutex> lock(m_mutex);
actor_id = _SaveActor(actor);
}
if(actor_id != INVALID_HYDRA_ID)
{
actor->InitialiseComponents();
}
return actor_id;
}
else
{
return INVALID_HYDRA_ID;
}
}
#endif /* HYDRAACTORMANAGER */
@@ -0,0 +1,45 @@
#include "HydraDirectionalLightActor.h"
#include "../engine/HydraEngine.h"
#include "../actor/HydraActorManager.h"
#include "../task/HydraTask.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
#include "../ecs/components/HydraMaterialComponent.h"
#include "../ecs/components/HydraLightComponent.h"
#include "../buffer/HydraLightBufferManager.h"
#include "../buffer/HydraLightBuffer.h"
void HydraDirectionalLightActor::InitialiseComponents()
{
HydraLightComponent light_comp = {};
HydraECS *ecs = GetEngine()->ECS();
// HydraLightBuffer light = {};
// light.light_colour = glm::vec3(1,1,1);
// light.light_direction = glm::vec3(0,0,0);
// light.light_intensity = 1;
// light.light_type = static_cast<uint32_t>(HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL);
//light_comp.light_id = GetEngine()->LightBufferManager()->CreateLight(light);
light_comp.light_colour = glm::vec4(1,1,1,1);
light_comp.light_intensity = 100.0f;
light_comp.light_type = static_cast<uint32_t>(HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL);
light_comp.entity_id = GetID();
ecs->AddComponent<HydraLightComponent>(GetID(), light_comp);
HydraPositionComponent position_component;
ecs->AddComponent<HydraPositionComponent>(GetID(), position_component);
}
void HydraDirectionalLightActor::Destroy()
{
}
@@ -0,0 +1,18 @@
#ifndef HYDRALIGHTACTOR
#define HYDRALIGHTACTOR
#include "HydraActor.h"
class CLASS_DEFINE HydraDirectionalLightActor : public HydraActor
{
private:
protected:
public:
virtual void InitialiseComponents() override;
virtual void Destroy() override;
};
#endif /* HYDRALIGHTACTOR */
+19
View File
@@ -0,0 +1,19 @@
#ifndef HYDRAGLTFACTOR
#define HYDRAGLTFACTOR
#include "HydraActor.h"
class CLASS_DEFINE HydraGLTFActor : public HydraActor
{
private:
protected:
public:
virtual void InitialiseComponents() override {}
virtual void Destroy() override {}
};
#endif /* HYDRAGLTFACTOR */
@@ -0,0 +1,135 @@
#include "HydraOutputActor.h"
#include "../engine/HydraEngine.h"
#include "../actor/HydraActorManager.h"
#include "../task/HydraTask.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
#include "../ecs/components/HydraMaterialComponent.h"
#include "../buffer/HydraMaterialBufferManager.h"
#include "../buffer/HydraTextureBufferManager.h"
#include "../buffer/HydraMaterialBuffer.h"
#include "../mesh/HydraMeshManager.h"
#include "../mesh/HydraMesh.h"
void HydraOutputActor::_CreateMaterial()
{
HydraEngine *engine = GetEngine();
HydraRenderSettings render_settings = engine->RenderSettings();
HydraID buffer_0 = engine->TextureBufferManager()->CreateTexture("deferred_buffer_0",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA8,
GL_NEAREST,
GL_NEAREST);
HydraID depth = engine->TextureBufferManager()->CreateTexture("deferred_depth",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_DEPTH_COMPONENT24,
GL_NEAREST,
GL_NEAREST);
HydraID metal_rough = engine->TextureBufferManager()->CreateTexture("deferred_metal_rough_buffer",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA8,
GL_NEAREST,
GL_NEAREST);
HydraID normal = engine->TextureBufferManager()->CreateTexture("deferred_normal_buffer",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA32F,
GL_NEAREST,
GL_NEAREST);
HydraID position = engine->TextureBufferManager()->CreateTexture("deferred_position_buffer",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA32F,
GL_NEAREST,
GL_NEAREST);
// engine->TextureBufferManager()->BindTexture(depth);
// engine->TextureBufferManager()->BindTexture(buffer_0);
texture_buffers.resize(16);
texture_buffers[0] = depth;
texture_buffers[1] = buffer_0;
texture_buffers[2] = metal_rough;
texture_buffers[3] = normal;
texture_buffers[4] = position;
}
void HydraOutputActor::_CreateMesh()
{
HydraMeshManager *mesh_manager = GetEngine()->MeshManager();
HydraID mesh_id = mesh_manager->CreateMesh();
HydraMesh *mesh = mesh_manager->GetMesh(mesh_id);
mesh->vertexes.resize(4);
mesh->indexes.resize(6);
float scale_x = 1.0f;
float scale_y = 1.0f;
float scale_z = 1.0f;
float min_x = -0.5f * scale_x;
float min_y = -0.5f * scale_y;
float min_z = 0.5f * scale_z;
float max_x = 0.5f * scale_x;
float max_y = 0.5f * scale_y;
float max_z = 0.5f * scale_z;
float min_u = 0;
float min_v = 0;
float max_u = 1;
float max_v = 1;
// 1---2 5---6
// | / | | / |
// 0---3 4---7
HydraID actor_id = GetID();
mesh->vertexes[0] = {min_x, min_y, min_z, min_u, min_v, actor_id, 0, 0, 0,0,0,0,0,0,0,0,0};
mesh->vertexes[1] = {min_x, max_y, min_z, min_u, max_v, actor_id, 0, 0, 0,0,0,0,0,0,0,0,0};
mesh->vertexes[2] = {max_x, max_y, min_z, max_u, max_v, actor_id, 0, 0, 0,0,0,0,0,0,0,0,0};
mesh->vertexes[3] = {max_x, min_y, min_z, max_u, min_v, actor_id, 0, 0, 0,0,0,0,0,0,0,0,0};
// Face 0
mesh->indexes[0] = 0;
mesh->indexes[1] = 1;
mesh->indexes[2] = 2;
mesh->indexes[3] = 0;
mesh->indexes[4] = 2;
mesh->indexes[5] = 3;
HydraECS *ecs = GetEngine()->ECS();
HydraMeshComponent mesh_comp;
mesh_comp.mesh_id = mesh_id;
mesh_comp.mesh_state = HYDRA_STATE::Waiting;
ecs->AddComponent<HydraMeshComponent>(GetID(), mesh_comp);
}
void HydraOutputActor::_CreateRenderableComponent()
{
HydraRenderableComponent render_comp;
HydraECS *ecs = GetEngine()->ECS();
render_comp.renderable_types.set((uint32_t)HYDRA_RENDERABLE_TYPE::HYDRA_OUTPUT, true);
ecs->AddComponent<HydraRenderableComponent>(GetID(), render_comp);
}
void HydraOutputActor::InitialiseComponents()
{
_CreateMaterial();
_CreateMesh();
_CreateRenderableComponent();
}
@@ -0,0 +1,20 @@
#ifndef HYDRAOUTPUTACTOR
#define HYDRAOUTPUTACTOR
#include "HydraActor.h"
class CLASS_DEFINE HydraOutputActor : public HydraActor
{
private:
HydraID m_mesh_component = INVALID_HYDRA_ID;
protected:
void _CreateMaterial();
void _CreateMesh();
void _CreateRenderableComponent();
public:
virtual void InitialiseComponents();
virtual void Destroy(){}
std::vector<HydraID> texture_buffers;
};
#endif /* HYDRAOUTPUTACTOR */
@@ -0,0 +1,208 @@
#include "HydraPlaneActor.h"
#include "../engine/HydraEngine.h"
#include "../actor/HydraActorManager.h"
#include "../task/HydraTask.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
#include "../ecs/components/HydraMaterialComponent.h"
#include "../buffer/HydraMaterialBufferManager.h"
#include "../buffer/HydraTextureBufferManager.h"
#include "../buffer/HydraMaterialBuffer.h"
#include "../mesh/HydraMeshManager.h"
#include "../mesh/HydraMesh.h"
void HydraPlaneActor::InitialiseComponents()
{
// HydraECS* ecs = GetEngine()->ECS();
// HydraID entity_id = ecs->CreateEntity();
_CreatePosition();
// _CreatePhysics();
_CreateMaterial();
_CreateMesh();
_CreateRenderableComponent();
}
void HydraPlaneActor::DeferredInitialiseComponents()
{
}
void HydraPlaneActor::_CreatePosition()
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent position_component;
ecs->AddComponent<HydraPositionComponent>(GetID(), position_component);
}
void HydraPlaneActor::_CreateMesh()
{
HydraMeshManager *mesh_manager = GetEngine()->MeshManager();
HydraID mesh_id = mesh_manager->CreateMesh();
HydraMesh *mesh = mesh_manager->GetMesh(mesh_id);
HydraMaterialComponent mat_comp = GetEngine()->ECS()->GetComponent<HydraMaterialComponent>(GetID());
mesh->vertexes.resize(24);
mesh->indexes.resize(36);
float scale_x = 1000.0f;
float scale_y = 1.0f;
float scale_z = 1000.0f;
float min_x = -0.5f * scale_x;
float min_y = -0.5f * scale_y;
float min_z = -0.5f * scale_z;
float max_x = 0.5f * scale_x;
float max_y = 0.5f * scale_y;
float max_z = 0.5f * scale_z;
float min_u = 1000;
float min_v = 0;
float max_u = 0;
float max_v = 1000;
// 1---2 5---6
//| / | | / |
// 0---3 4---7
HydraID actor_id = GetID();
mesh->vertexes[0] = {min_x, min_y, min_z, min_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[1] = {min_x, max_y, min_z, min_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[2] = {max_x, max_y, min_z, max_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[3] = {max_x, min_y, min_z, max_u, min_v, actor_id, mat_comp.material_id, 0};
// Face 0
mesh->indexes[0] = 0;
mesh->indexes[1] = 1;
mesh->indexes[2] = 2;
mesh->indexes[3] = 0;
mesh->indexes[4] = 2;
mesh->indexes[5] = 3;
mesh->vertexes[4] = {max_x, min_y, min_z, min_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[5] = {max_x, max_y, min_z, min_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[6] = {max_x, max_y, max_z, max_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[7] = {max_x, min_y, max_z, max_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->indexes[6] = 4;
mesh->indexes[7] = 5;
mesh->indexes[8] = 6;
mesh->indexes[9] = 4;
mesh->indexes[10] = 6;
mesh->indexes[11] = 7;
// Back Face
mesh->vertexes[8] = {max_x, min_y, max_z, min_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[9] = {max_x, max_y, max_z, min_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[10] = {min_x, max_y, max_z, max_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[11] = {min_x, min_y, max_z, max_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->indexes[12] = 8;
mesh->indexes[13] = 9;
mesh->indexes[14] = 10;
mesh->indexes[15] = 8;
mesh->indexes[16] = 10;
mesh->indexes[17] = 11;
mesh->vertexes[12] = {min_x, min_y, max_z, min_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[13] = {min_x, max_y, max_z, min_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[14] = {min_x, max_y, min_z, max_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[15] = {min_x, min_y, min_z, max_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->indexes[18] = 12;
mesh->indexes[19] = 13;
mesh->indexes[20] = 14;
mesh->indexes[21] = 12;
mesh->indexes[22] = 14;
mesh->indexes[23] = 15;
mesh->vertexes[16] = {min_x, max_y, min_z, min_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[17] = {min_x, max_y, max_z, min_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[18] = {max_x, max_y, max_z, max_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[19] = {max_x, max_y, min_z, max_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->indexes[24] = 16;
mesh->indexes[25] = 17;
mesh->indexes[26] = 18;
mesh->indexes[27] = 16;
mesh->indexes[28] = 18;
mesh->indexes[29] = 19;
mesh->vertexes[20] = {min_x, min_y, min_z, min_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[21] = {max_x, min_y, min_z, min_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[22] = {max_x, min_y, max_z, max_u, max_v, actor_id, mat_comp.material_id, 0};
mesh->vertexes[23] = {min_x, min_y, max_z, max_u, min_v, actor_id, mat_comp.material_id, 0};
mesh->indexes[30] = 20;
mesh->indexes[31] = 21;
mesh->indexes[32] = 22;
mesh->indexes[33] = 20;
mesh->indexes[34] = 22;
mesh->indexes[35] = 23;
mesh_manager->CalculateNormals(mesh->mesh_id);
HydraECS *ecs = GetEngine()->ECS();
HydraMeshComponent mesh_comp;
mesh_comp.mesh_id = mesh_id;
mesh_comp.mesh_state = HYDRA_STATE::Waiting;
ecs->AddComponent<HydraMeshComponent>(GetID(), mesh_comp);
}
void HydraPlaneActor::_CreateMaterial()
{
HydraEngine *engine = GetEngine();
std::string filename = std::string(texture_base) + std::string("/DesignArea/DesignArea_Albedo.png");
HydraID tex_id = engine->TextureBufferManager()->LoadTexture(filename);
HydraMaterialBuffer material = {};
material.diffuse_texture_id = tex_id;
material.diffuse_colour = glm::vec4(1, 1, 1, 1);
material.metalic_rough = glm::vec4(0, 0.5, 0.3, 1);
HydraID mat_id = engine->MaterialBufferManager()->CreateMaterial(material);
HydraMaterialComponent mat_comp = {};
mat_comp.material_id = mat_id;
engine->ECS()->AddComponent<HydraMaterialComponent>(GetID(), mat_comp);
}
void HydraPlaneActor::_CreatePhysics()
{
// HydraECSPhysicsComponent physics_component;
// physics_component.physics_state = Hydra_State::Waiting;
// physics_component.physics_definition.actor_id = GetID();
// physics_component.physics_definition.physics_type = HydraPhyicsType::Static;
// physics_component.physics_definition.physics_shape = HydraPhysicsShape::HydraBoxShape;
// physics_component.physics_definition.mass = 100000.0f;
// physics_component.physics_definition.extent_x = 1000.0f;
// physics_component.physics_definition.extent_y = 0.5f;
// physics_component.physics_definition.extent_z = 1000.0f;
// physics_component.physics_definition.dynamic_friction = 0.5f;
// physics_component.physics_definition.restitution = 0.5f;
// HydraECS* ecs = GetEngine()->ECS();
// ecs->AddComponent<HydraECSPhysicsComponent>(GetID(), physics_component);
}
void HydraPlaneActor::_CreateRenderableComponent()
{
HydraRenderableComponent render_comp;
HydraECS *ecs = GetEngine()->ECS();
render_comp.renderable_types.set((uint32_t)HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR, true);
ecs->AddComponent<HydraRenderableComponent>(GetID(), render_comp);
}
@@ -0,0 +1,28 @@
#ifndef HYDRAPLANEACTOR
#define HYDRAPLANEACTOR
#include "HydraActor.h"
class CLASS_DEFINE HydraPlaneActor : public HydraActor
{
private:
double m_scale = 1.0;
double m_widthscale = 1000.0f;
HydraID m_material_component = INVALID_HYDRA_ID;
HydraID m_position_component = INVALID_HYDRA_ID;
HydraID m_mesh_component = INVALID_HYDRA_ID;
protected:
void _CreatePosition();
void _CreateMesh();
void _CreateMaterial();
void _CreatePhysics();
void _CreateRenderableComponent();
public:
virtual void InitialiseComponents();
virtual void DeferredInitialiseComponents();
virtual void Destroy(){}
};
#endif /* HYDRAPLANEACTOR */
@@ -0,0 +1,106 @@
#include "HydraPlayerActor.h"
#include "HydraActorManager.h"
#include "../HydraDefines.h"
#include "../engine/HydraEngine.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraPositionComponent.h"
void HydraPlayerActor::InitialiseComponents()
{
HydraECS* ecs = GetEngine()->ECS();
//HydraID entity_id = ecs->CreateEntity();
HydraPositionComponent position_component;
ecs->AddComponent<HydraPositionComponent>(GetID(), position_component);
}
void HydraPlayerActor::DeferredInitialiseComponents()
{
//_CreatePhysics();
}
void HydraPlayerActor::_CreatePhysics()
{
// HydraPhysicsComponent* physics_component = static_cast<HydraPhysicsComponent*>(GetEngine()->ComponentManager()->CreateComponent((uint32_t)HYDRA_COMPONENT_TYPE::PHYSICS, GetID()));
// physics_component->physics_definition.PhysicsType = HydraPhyicsType::Dynamic;
// physics_component->physics_definition.PhysicsShape = HydraPhysicsShape::HydraBoxShape;
// physics_component->physics_definition.Mass = 10.0f;
// physics_component->physics_definition.ExtentX = 0.5f;
// physics_component->physics_definition.ExtentY = 0.5f;
// physics_component->physics_definition.ExtentZ = 0.5f;
// physics_component->physics_definition.DynamicFriction = 0.5f;
// physics_component->physics_definition.Restitution = 0.5f;
// physics_component->physics_definition.Velocity = GetEngine()->ActorManager()->GetActorVelocity(GetID());
}
void HydraPlayerActor::HandleInput(float delta_t)
{
glm::vec2 change = GetEngine()->MouseChange();
bool move_forward = GetEngine()->KeyPressed(HYDRA_KEY_CODES::HYDRA_KEY_W);
bool move_backward = GetEngine()->KeyPressed(HYDRA_KEY_CODES::HYDRA_KEY_S);
bool move_fast = GetEngine()->KeyPressed(HYDRA_KEY_CODES::HYDRA_KEY_LEFT_SHIFT);
bool move_left = GetEngine()->KeyPressed(HYDRA_KEY_CODES::HYDRA_KEY_A);
bool move_right = GetEngine()->KeyPressed(HYDRA_KEY_CODES::HYDRA_KEY_D);
HydraRenderSettings render_settings = GetEngine()->RenderSettings();
float scale = 0.2f;
float x_angle = (change.x / render_settings.DisplayWidth) * -500 * delta_t * scale;
float y_angle = (change.y / render_settings.DisplayHeight) * -500 * delta_t * scale;
float extra_speed = 1.0f;
float speed = 5.0f;
if (move_fast)
{
extra_speed = 150;
}
GetEngine()->ActorManager()->RotateActor(GetID(), y_angle, x_angle, 0.0f);
glm::dvec3 pos_vec = GetEngine()->ActorManager()->GetActorPosition(GetID());
glm::vec3 rot_vec = GetEngine()->ActorManager()->GetActorOrientation(GetID());
glm::mat4 rot = glm::mat4(1);
rot = glm::eulerAngleXYZ(rot_vec.x, rot_vec.y, rot_vec.z);
glm::dvec3 forward = m_forward * rot;
glm::dvec3 right = m_right * rot;
glm::dvec3 up = m_up * rot;
glm::dvec3 trans = glm::dvec3(0, 0, 0);
double distance = (double)(speed * extra_speed * delta_t);
bool moved = false;
if (move_forward)
{
trans = trans - (forward * distance);
moved = true;
}
if (move_backward)
{
trans = trans + (forward * distance);
moved = true;
}
if (move_right)
{
trans = trans - (right * distance);
moved = true;
}
if (move_left)
{
trans = trans + (right * distance);
moved = true;
}
if (moved)
{
GetEngine()->ActorManager()->TranslateActor(GetID(), -trans);
}
}
@@ -0,0 +1,24 @@
#ifndef HYDRAPLAYERACTOR
#define HYDRAPLAYERACTOR
#include "HydraActor.h"
#include <GLMIncludes.h>
class HydraCamara;
class CLASS_DEFINE HydraPlayerActor : public HydraActor
{
private:
protected:
glm::vec4 m_right = glm::vec4(1, 0, 0, 1);
glm::vec4 m_up = glm::vec4(0, -1, 0, 1);
glm::vec4 m_forward = glm::vec4(0, 0, -1 , 1);
void _CreatePhysics();
public:
virtual void InitialiseComponents();
virtual void DeferredInitialiseComponents();
virtual void HandleInput(float delta_t);
virtual void Destroy() {}
};
#endif /* HYDRAPLAYERACTOR */
+14
View File
@@ -0,0 +1,14 @@
#ifndef HYDRABUFFER
#define HYDRABUFFER
#include "../HydraDefines.h"
struct HydraBuffer
{
HydraID buffer_id = INVALID_HYDRA_ID;
uint32_t size_bytes = 0;
uint32_t shader_binding_id; //index of the UBO in the shader
uint32_t gpu_buffer_id; //UBO Block id for bind buffer base
HYDRA_BUFFER_TYPE buffer_type;
std::string buffer_name;
};
#endif /* HYDRABUFFER */
@@ -0,0 +1,163 @@
#include "HydraBufferManager.h"
#include "../GlewIncludes.h"
#include "../mesh/StandardVertex.h"
void HydraBufferManager::Initialise()
{
m_buffers.resize(MAX_BUFFERS);
for(uint32_t i = 0; i < MAX_BUFFERS; i++)
{
m_available_buffer_ids.push(i);
}
}
void HydraBufferManager::Shutdown()
{
for(uint32_t i = 0; i < MAX_BUFFERS; i++)
{
if(m_buffers[i].buffer_id != INVALID_HYDRA_ID)
{
DeleteBuffer(m_buffers[i].buffer_id);
}
}
}
// HydraID HydraBufferManager::CreateGPUBuffer(std::string buffer_name,
// uint32_t buffer_size_bytes,
// uint32_t binding,
// HYDRA_BUFFER_TYPE buffer_type)
// {
// HydraID buffer_id = _GetBufferID();
// HydraBuffer buffer = {};
// buffer.buffer_id = buffer_id;
// buffer.size_bytes = buffer_size_bytes;
// buffer.buffer_name = buffer_name;
// buffer.buffer_type = buffer_type;
// uint32_t gl_buffer_type = _DecodeBufferType(buffer_type);
// //Create the buffer
// glGenBuffers(1, &buffer.gpu_buffer_id);
// glBindBuffer(gl_buffer_type, buffer.gpu_buffer_id);
// //Allocate storage
// glBufferData(gl_buffer_type, buffer.size_bytes, NULL, GL_DYNAMIC_DRAW);
// glBindBufferBase(gl_buffer_type, binding, buffer.gpu_buffer_id);
// glBindBuffer(gl_buffer_type, 0);
// m_buffers[buffer_id] = buffer;
// return buffer_id;
// }
HydraID HydraBufferManager::CreateGPUBuffer(std::string buffer_name,
uint32_t buffer_size_bytes,
uint32_t binding,
HYDRA_BUFFER_TYPE buffer_type)
{
HydraID buffer_id = _GetBufferID();
HydraBuffer buffer = {};
buffer.buffer_id = buffer_id;
buffer.size_bytes = buffer_size_bytes;
buffer.buffer_name = buffer_name;
buffer.buffer_type = buffer_type;
uint32_t gl_buffer_type = _DecodeBufferType(buffer_type);
//Create the buffer
glCreateBuffers(1, &buffer.gpu_buffer_id);
glNamedBufferStorage(
buffer.gpu_buffer_id,
buffer_size_bytes,
NULL,
GL_DYNAMIC_STORAGE_BIT
);
glBindBufferBase(gl_buffer_type, binding, buffer.gpu_buffer_id);
m_buffers[buffer_id] = buffer;
return buffer_id;
}
void HydraBufferManager::DeleteBuffer(HydraID buffer_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(buffer_id < MAX_BUFFERS)
{
if(m_buffers[buffer_id].buffer_id != INVALID_HYDRA_ID)
{
glDeleteBuffers(0, &m_buffers[buffer_id].gpu_buffer_id);
m_buffers[buffer_id].buffer_id = INVALID_HYDRA_ID;
m_available_buffer_ids.push(buffer_id);
}
}
}
void HydraBufferManager::UpdatePartialBuffer(HydraID buffer_id, uint32_t start, uint32_t size, void *data)
{
if(buffer_id >= MAX_BUFFERS)
{
return;
}
if(m_buffers[buffer_id].buffer_id == INVALID_HYDRA_ID)
{
return;
}
glNamedBufferSubData(m_buffers[buffer_id].gpu_buffer_id, start, size, data);
//glBindBuffer(GL_UNIFORM_BUFFER, m_buffers[buffer_id].gpu_buffer_id);
//glBufferSubData(GL_UNIFORM_BUFFER, 0, m_buffers[buffer_id].size_bytes, data);
}
void HydraBufferManager::UpdateWholeBuffer(HydraID buffer_id, void *data)
{
if(buffer_id >= MAX_BUFFERS)
{
return;
}
if(m_buffers[buffer_id].buffer_id == INVALID_HYDRA_ID)
{
return;
}
glNamedBufferSubData(m_buffers[buffer_id].gpu_buffer_id, 0, m_buffers[buffer_id].size_bytes, data);
//glBindBuffer(GL_UNIFORM_BUFFER, m_buffers[buffer_id].gpu_buffer_id);
//glBufferSubData(GL_UNIFORM_BUFFER, 0, m_buffers[buffer_id].size_bytes, data);
}
HydraID HydraBufferManager::FindBuffer(std::string buffer_name)
{
for(uint32_t buffer_idx = 0; buffer_idx < m_buffers.size(); buffer_idx++)
{
if(m_buffers[buffer_idx].buffer_name == buffer_name)
{
return buffer_idx;
}
}
return INVALID_HYDRA_ID;
}
const HydraBuffer &HydraBufferManager::GetBuffer(HydraID buffer_id)
{
return m_buffers[buffer_id];
}
HydraID HydraBufferManager::_GetBufferID()
{
HydraID buffer_id = INVALID_HYDRA_ID;
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_buffer_ids.size() == 0)
{
return INVALID_HYDRA_ID;
}
buffer_id = m_available_buffer_ids.front();
m_available_buffer_ids.pop();
}
return buffer_id;
}
uint32_t HydraBufferManager::_DecodeBufferType(HYDRA_BUFFER_TYPE buffer_type)
{
switch(buffer_type)
{
case HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER:
return GL_UNIFORM_BUFFER;
case HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER:
return GL_SHADER_STORAGE_BUFFER;
}
return 0;
}
@@ -0,0 +1,33 @@
#ifndef HYDRABUFFERMANAGER
#define HYDRABUFFERMANAGER
#include "../engine/HydraObject.h"
#include "HydraBuffer.h"
#include "HydraVertexBuffer.h"
#include <queue>
#include <vector>
#include <mutex>
class HydraBufferManager : public HydraObject
{
public:
const uint32_t MAX_BUFFERS = 10000;
void Initialise();
void Shutdown();
HydraID CreateGPUBuffer(std::string buffer_name,
uint32_t buffer_size_bytes,
uint32_t binding,
HYDRA_BUFFER_TYPE buffer_type);
void DeleteBuffer(HydraID buffer_id);
void UpdatePartialBuffer(HydraID buffer_id, uint32_t start, uint32_t size, void *data);
void UpdateWholeBuffer(HydraID buffer_id, void* data);
HydraID FindBuffer(std::string buffer_name);
const HydraBuffer& GetBuffer(HydraID buffer_id);
private:
std::mutex m_mutex;
std::queue<HydraID> m_available_buffer_ids;
std::vector<HydraBuffer> m_buffers;
HydraID _GetBufferID();
uint32_t _DecodeBufferType(HYDRA_BUFFER_TYPE buffer_type);
};
#endif /* HYDRABUFFERMANAGER */
@@ -0,0 +1,16 @@
#ifndef HYDRALIGHTBUFFER
#define HYDRALIGHTBUFFER
#include <GLMIncludes.h>
struct HydraLightBuffer
{
alignas(16) glm::vec3 light_direction;
alignas(16) glm::vec3 light_colour;
uint32_t light_type;
float light_intensity;
float padding[2];
};
#endif /* HYDRALIGHTBUFFER */
@@ -0,0 +1,47 @@
#include "HydraLightBufferManager.h"
void HydraLightBufferManager::Initialise()
{
m_light_lookup.resize(MAX_LIGHTS);
m_lights.resize(MAX_LIGHTS);
for(uint32_t i = 0; i < MAX_LIGHTS; i ++)
{
m_available_lights.push(i);
}
}
void HydraLightBufferManager::Shutdown()
{
}
HydraID HydraLightBufferManager::CreateLight(HydraLightBuffer light_buffer)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_lights.size() > 0)
{
HydraID light_id = m_available_lights.front();
m_available_lights.pop();
m_lights[m_light_count] = light_buffer;
m_light_lookup[light_id] = m_light_count;
m_light_count++;
return light_id;
}
return INVALID_HYDRA_ID;
}
HydraLightBuffer *const HydraLightBufferManager::GetLightBufferBase()
{
return &m_lights[0];
}
HydraLightBuffer &HydraLightBufferManager::GetLightBuffer(HydraID light_id)
{
HydraID light_idx = m_light_lookup[light_id];
return m_lights[light_idx];
}
uint32_t HydraLightBufferManager::GetLightCount()
{
return m_light_count;
}
@@ -0,0 +1,27 @@
#ifndef HYDRALIGHTBUFFERMANAGER
#define HYDRALIGHTBUFFERMANAGER
#include "../engine/HydraObject.h"
#include "HydraLightBuffer.h"
#include <vector>
#include <queue>
#include <mutex>
class HydraLightBufferManager : public HydraObject
{
public:
void Initialise();
void Shutdown();
HydraID CreateLight(HydraLightBuffer light_buffer);
HydraLightBuffer* const GetLightBufferBase();
HydraLightBuffer& GetLightBuffer(HydraID light_id);
uint32_t GetLightCount();
private:
std::mutex m_mutex;
uint32_t m_light_count = 0;
std::vector<HydraLightBuffer> m_lights;
std::queue<HydraID> m_available_lights;
std::vector<HydraID> m_light_lookup;
};
#endif /* HYDRALIGHTBUFFERMANAGER */
@@ -0,0 +1,18 @@
#ifndef HYDRAMATERIALBUFFER
#define HYDRAMATERIALBUFFER
#include "../HydraDefines.h"
#include <GLMIncludes.h>
struct HydraMaterialBuffer
{
glm::vec4 diffuse_colour = {0, 0, 0, 0}; //0 - 16
glm::vec4 metalic_rough = {0, 0, 0, 0}; //28 - 12
uint32_t diffuse_texture_id = INVALID_HYDRA_ID; //32 - 4
uint32_t metallic_rough_texture_id = INVALID_HYDRA_ID; //36 - 4
uint32_t normal_texture_id = INVALID_HYDRA_ID; //40 - 4
uint32_t padding[1] = {}; //48 - 8
};
#endif /* HYDRAMATERIALBUFFER */
@@ -0,0 +1,35 @@
#include "HydraMaterialBufferManager.h"
void HydraMaterialBufferManager::Intialise()
{
m_material.resize(MAX_MATERIALS);
for(uint32_t mat_idx = 0; mat_idx < MAX_MATERIALS; mat_idx++)
{
m_available_material_ids.push(mat_idx);
}
}
void HydraMaterialBufferManager::Shutdown()
{
}
HydraID HydraMaterialBufferManager::CreateMaterial(const HydraMaterialBuffer &material)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_material_ids.size() == 0)
{
return INVALID_HYDRA_ID;
}
HydraID mat_id = m_available_material_ids.front();
m_available_material_ids.pop();
m_material[mat_id] = material;
return mat_id;
}
void *HydraMaterialBufferManager::GetMaterialBuffer()
{
return &m_material[0];
}
@@ -0,0 +1,30 @@
#ifndef HYDRAMATERIALBUFFERMANAGER
#define HYDRAMATERIALBUFFERMANAGER
#include "../engine/HydraObject.h"
#include "HydraMaterialBuffer.h"
#include <vector>
#include <queue>
#include <unordered_map>
#include <GLMIncludes.h>
#include <stb_image.h>
#include <mutex>
#include <string>
class HydraMaterialBufferManager : public HydraObject
{
public:
void Intialise();
void Shutdown();
HydraID CreateMaterial(const HydraMaterialBuffer& material);
void* GetMaterialBuffer();
private:
std::mutex m_mutex;
std::queue<HydraID> m_available_material_ids;
std::vector<HydraMaterialBuffer> m_material;
};
#endif /* HYDRAMATERIALBUFFERMANAGER */
@@ -0,0 +1,193 @@
#define STB_IMAGE_IMPLEMENTATION
#include "HydraTextureBufferManager.h"
#include "../scheduler/HydraTaskScheduler.h"
#include "../task/buffer/HydraCreateTextureTask.hpp"
void HydraTextureBufferManager::Intialise()
{
m_textures.resize(MAX_TEXTURES);
m_bindless_texture_ids.resize(MAX_TEXTURES);
for (uint32_t tex_idx = 0; tex_idx < MAX_TEXTURES; tex_idx++)
{
m_available_texture_ids.push(tex_idx);
m_bindless_texture_ids[tex_idx] = 0;
}
}
void HydraTextureBufferManager::Shutdown()
{
for (uint32_t tex_idx = 0; tex_idx < MAX_TEXTURES; tex_idx++)
{
if (m_textures[tex_idx].texture_id != INVALID_HYDRA_ID)
{
DeleteTexture(tex_idx);
}
}
}
HydraID HydraTextureBufferManager::LoadTexture(std::string texture_filename)
{
HydraID texture_id = FindTexture(texture_filename);
if (texture_id != INVALID_HYDRA_ID)
{
return texture_id;
}
void *data = nullptr;
int width = 0;
int height = 0;
int channels = 0;
//stbi_set_flip_vertically_on_load(true);
data = stbi_load(texture_filename.c_str(), &width, &height, &channels, 0);
if (data == nullptr)
{
return INVALID_HYDRA_ID;
}
uint32_t format = GL_RGBA;
if (channels == 3)
{
format = GL_RGB;
}
HydraTaskScheduler *scheduler = GetEngine()->TaskScheduler();
HydraID create_tex_id = scheduler->CreateTask<HydraCreateTextureTask>(HydraThreadAffinity::Render);
HydraCreateTextureTask *create_tex_task = static_cast<HydraCreateTextureTask *>(scheduler->GetTask(create_tex_id));
HydraID tex_id = INVALID_HYDRA_ID;
create_tex_task->Initialise(texture_filename,
width,
height,
GL_RGBA8,
format,
GL_NEAREST_MIPMAP_NEAREST,
GL_LINEAR,
GL_UNSIGNED_BYTE,
5,
data,
&tex_id);
scheduler->WaitForTask(create_tex_id);
return tex_id;
}
HydraID HydraTextureBufferManager::FindTexture(std::string texture_name)
{
if (m_texture_lookup.find(texture_name) == m_texture_lookup.end())
{
return INVALID_HYDRA_ID;
}
return m_texture_lookup.find(texture_name)->second;
}
void *HydraTextureBufferManager::GetTextureBuffer()
{
return &m_bindless_texture_ids[0];
}
const HydraTextureBuffer &HydraTextureBufferManager::GetTexture(HydraID texture_id)
{
return m_textures[texture_id];
}
HydraID HydraTextureBufferManager::_GetTextureID()
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_available_texture_ids.size() == 0)
{
return INVALID_HYDRA_ID;
}
HydraID id = m_available_texture_ids.front();
m_available_texture_ids.pop();
return id;
}
HydraID HydraTextureBufferManager::CreateTexture(std::string texture_name,
uint32_t width,
uint32_t height,
uint32_t internal_format,
uint32_t min_filter,
uint32_t mag_filter,
uint32_t format,
uint32_t data_type,
uint32_t mip_levels,
void *data)
{
uint32_t gl_tex_id = 0;
glCreateTextures(GL_TEXTURE_2D, 1, &gl_tex_id);
glBindTexture(GL_TEXTURE_2D, gl_tex_id);
// important to create mip_levels + 1 images
glTextureStorage2D(gl_tex_id, mip_levels + 1, internal_format, width, height);
if (data != nullptr)
{
glTextureSubImage2D(
gl_tex_id,
// level, xoffset, yoffset, width, height
0, 0, 0, width, height,
format, data_type,
data);
if (mip_levels > 0)
{
glGenerateTextureMipmap(gl_tex_id);
}
}
glTextureParameteri(gl_tex_id, GL_TEXTURE_MIN_FILTER, min_filter);
glTextureParameteri(gl_tex_id, GL_TEXTURE_MAG_FILTER, mag_filter);
glBindTexture(GL_TEXTURE_2D, 0);
HydraTextureBuffer texture_buffer = {};
HydraID texture_id = _GetTextureID();
texture_buffer.texture_id = texture_id;
texture_buffer.format = format;
texture_buffer.internal_format = internal_format;
texture_buffer.width = width;
texture_buffer.height = height;
texture_buffer.gl_tex_id = gl_tex_id;
texture_buffer.mag_filter = mag_filter;
texture_buffer.min_filter = min_filter;
m_textures[texture_id] = texture_buffer;
m_texture_lookup.insert(std::pair<std::string, HydraID>(texture_name, texture_id));
return texture_id;
}
void HydraTextureBufferManager::BindTexture(HydraID texture_id)
{
if (texture_id >= MAX_TEXTURES)
{
return;
}
HydraTextureBuffer texture = m_textures[texture_id];
glBindTexture(GL_TEXTURE_2D, texture.gl_tex_id);
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_MIN_FILTER, texture.min_filter);
glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_MAG_FILTER, texture.mag_filter);
texture.texture_binding = glGetTextureHandleARB(texture.gl_tex_id);
glMakeTextureHandleResidentARB(texture.texture_binding);
m_bindless_texture_ids[texture_id] = texture.texture_binding;
}
void HydraTextureBufferManager::UnbindTexture(HydraID texture_id)
{
glMakeTextureHandleNonResidentARB(texture_id);
}
void HydraTextureBufferManager::DeleteTexture(HydraID texture_id)
{
if (m_bindless_texture_ids[texture_id] != 0)
{
UnbindTexture(m_bindless_texture_ids[texture_id]);
}
}
@@ -0,0 +1,42 @@
#ifndef HYDRATEXTUREBUFFERMANAGER
#define HYDRATEXTUREBUFFERMANAGER
#include "../engine/HydraObject.h"
#include "HydraTexureBuffer.h"
#include <vector>
#include <queue>
#include <unordered_map>
#include <GLMIncludes.h>
#include <stb_image.h>
#include <mutex>
#include <string>
#include "../GlewIncludes.h"
class HydraTextureBufferManager : public HydraObject
{
public:
void Intialise();
void Shutdown();
HydraID CreateTexture(std::string texture_name, uint32_t width, uint32_t height, uint32_t internal_format,
uint32_t min_filter, uint32_t mag_filter,
uint32_t format = GL_RGBA, uint32_t data_type = GL_UNSIGNED_BYTE, uint32_t mip_levels = 0, void* data = nullptr);
void BindTexture(HydraID texture_id);
void UnbindTexture(HydraID texture_id);
void DeleteTexture(HydraID texture_id);
HydraID LoadTexture(std::string texture_filename);
HydraID FindTexture(std::string texture_name);
void* GetTextureBuffer();
const HydraTextureBuffer& GetTexture(HydraID texture_id);
private:
HydraID _GetTextureID();
std::mutex m_mutex;
std::queue<HydraID> m_available_texture_ids;
std::vector<HydraTextureBuffer> m_textures;
std::vector<uint64_t> m_bindless_texture_ids;
std::unordered_map<std::string, HydraID> m_texture_lookup;
uint32_t m_gl_texture_id = 0;
};
#endif /* HYDRATEXTUREBUFFERMANAGER */
@@ -0,0 +1,18 @@
#ifndef HYDRATEXUREBUFFER
#define HYDRATEXUREBUFFER
struct HydraTextureBuffer
{
HydraID texture_id = INVALID_HYDRA_ID;
uint32_t width = 0;
uint32_t height = 0;
uint32_t format = 0;
uint32_t internal_format = 0;
uint32_t gl_tex_id;
uint64_t texture_binding = 0;
uint32_t mag_filter = 0;
uint32_t min_filter = 0;
};
#endif /* HYDRATEXUREBUFFER */
@@ -0,0 +1,18 @@
#ifndef HYDRAVERTEXBUFFER
#define HYDRAVERTEXBUFFER
#include "../HydraDefines.h"
struct HydraVertexBuffer
{
HydraID vertex_buffer_id;
uint32_t vao = 0;
uint32_t vbo = 0;
uint32_t ebo = 0;
uint32_t vertex_buffer_size_bytes = 0;
uint32_t index_buffer_size_bytes = 0;
uint32_t triangle_count = 0;
};
#endif /* HYDRAVERTEXBUFFER */
@@ -0,0 +1,127 @@
#include "HydraVertexBufferManager.h"
#include "../GlewIncludes.h"
#include "../mesh/StandardVertex.h"
void HydraVertexBufferManager::Initialise()
{
m_vertex_buffers.resize(MAX_BUFFERS);
for (uint32_t i = 0; i < MAX_BUFFERS; i++)
{
m_available_buffer_ids.push(i);
}
}
void HydraVertexBufferManager::Shutdown()
{
for (uint32_t i = 0; i < MAX_BUFFERS; i++)
{
if (m_vertex_buffers[i].vertex_buffer_id != INVALID_HYDRA_ID)
{
DeleteVertexBuffer(m_vertex_buffers[i].vertex_buffer_id);
}
}
}
HydraID HydraVertexBufferManager::CreateVertexBuffer(uint32_t vertex_buffer_size_bytes,
uint32_t index_buffer_size_bytes,
uint32_t triangle_count)
{
HydraID buffer_id = _GetBufferID();
HydraVertexBuffer buffer = {};
buffer.vertex_buffer_id = buffer_id;
buffer.vertex_buffer_size_bytes = vertex_buffer_size_bytes;
buffer.index_buffer_size_bytes = index_buffer_size_bytes;
buffer.triangle_count = triangle_count;
glGenVertexArrays(1, &buffer.vao);
glBindVertexArray(buffer.vao);
glGenBuffers(1, &buffer.vbo);
glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo);
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size_bytes, nullptr, GL_STATIC_DRAW);
glGenBuffers(1, &buffer.ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size_bytes, nullptr, GL_STATIC_DRAW);
// position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)0);
glEnableVertexAttribArray(0);
// texcoord01
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// chunkID
glVertexAttribIPointer(2, 3, GL_UNSIGNED_INT, sizeof(StandardVertex), (void *)(5 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(8 * sizeof(float)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(11 * sizeof(float)));
glEnableVertexAttribArray(4);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(14 * sizeof(float)));
glEnableVertexAttribArray(5);
glBindVertexArray(0);
m_vertex_buffers[buffer_id] = buffer;
return buffer_id;
}
void HydraVertexBufferManager::DeleteVertexBuffer(HydraID buffer_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (buffer_id < MAX_BUFFERS)
{
if (m_vertex_buffers[buffer_id].vertex_buffer_id != INVALID_HYDRA_ID)
{
glDeleteVertexArrays(1, &m_vertex_buffers[buffer_id].vao);
glDeleteBuffers(1, &m_vertex_buffers[buffer_id].vbo);
glDeleteBuffers(1, &m_vertex_buffers[buffer_id].ebo);
m_vertex_buffers[buffer_id].vertex_buffer_id = INVALID_HYDRA_ID;
m_available_buffer_ids.push(buffer_id);
}
}
}
void HydraVertexBufferManager::UpdateVertexBuffer(HydraID buffer_id, void *vertex_data, void *index_data)
{
if (buffer_id >= MAX_BUFFERS)
{
return;
}
if (m_vertex_buffers[buffer_id].vertex_buffer_id == INVALID_HYDRA_ID)
{
return;
}
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[buffer_id].vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_vertex_buffers[buffer_id].vertex_buffer_size_bytes, vertex_data);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vertex_buffers[buffer_id].ebo);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m_vertex_buffers[buffer_id].index_buffer_size_bytes, index_data);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
HydraVertexBuffer &HydraVertexBufferManager::GetVertexBuffer(HydraID buffer_id)
{
return m_vertex_buffers[buffer_id];
}
HydraID HydraVertexBufferManager::_GetBufferID()
{
HydraID buffer_id = INVALID_HYDRA_ID;
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_available_buffer_ids.size() == 0)
{
return INVALID_HYDRA_ID;
}
buffer_id = m_available_buffer_ids.front();
m_available_buffer_ids.pop();
}
return buffer_id;
}
@@ -0,0 +1,35 @@
#ifndef HYDRAVERTEXBUFFERMANAGER
#define HYDRAVERTEXBUFFERMANAGER
#include "../engine/HydraObject.h"
#include "HydraBuffer.h"
#include "HydraVertexBuffer.h"
#include <queue>
#include <vector>
#include <mutex>
class HydraVertexBufferManager : public HydraObject
{
public:
const uint32_t MAX_BUFFERS = 10000;
void Initialise();
void Shutdown();
HydraID CreateVertexBuffer(uint32_t vertex_buffer_size_bytes, uint32_t index_buffer_size_bytes, uint32_t triangle_count);
void DeleteVertexBuffer(HydraID buffer_id);
void UpdateVertexBuffer(HydraID buffer_id, void* vertex_data, void* index_data);
HydraVertexBuffer& GetVertexBuffer(HydraID buffer_id);
private:
std::mutex m_mutex;
std::queue<HydraID> m_available_buffer_ids;
std::vector<HydraVertexBuffer> m_vertex_buffers;
HydraID _GetBufferID();
};
#endif /* HYDRAVERTEXBUFFERMANAGER */
+77
View File
@@ -0,0 +1,77 @@
#include "HydraCamera.h"
#include "../engine/HydraEngine.h"
#include "../windowmanager/HydraRenderSettings.h"
#include "../actor/HydraActor.h"
#include "../actor/HydraActorManager.h"
glm::mat4x4 HydraCamera::GetView()
{
glm::dvec3 actor_pos = glm::dvec3(0,0,0);
glm::mat4 actor_rot = glm::mat4(1);
glm::vec3 actor_euler = glm::vec3(0);
if(m_attached_actor != INVALID_HYDRA_ID)
{
HydraActor* actor = GetEngine()->ActorManager()->GetActor(m_attached_actor);
if(actor != nullptr)
{
actor_pos = (GetEngine()->ActorManager()->GetActorPosition(m_attached_actor)) * glm::dvec3(-1, -1, -1);
actor_euler = GetEngine()->ActorManager()->GetActorOrientation(m_attached_actor);
actor_rot = glm::eulerAngleXYZ(actor_euler.x, actor_euler.y, actor_euler.z);
}
}
glm::mat4 trans = glm::translate(actor_pos);
glm::mat4 rot = actor_rot;// * glm::eulerAngleXYZ(EulerAngle.x, EulerAngle.y, EulerAngle.z);
glm::mat4 camera_transform = rot * trans;
return camera_transform;
}
glm::mat4x4 HydraCamera::GetProjection()
{
HydraRenderSettings render_settings = GetEngine()->RenderSettings();
float fovRad = glm::radians(render_settings.FOV);
//glm::mat4 projection = glm::perspectiveLH<float>(fovRad, (float)render_settings->ViewportWidth / (float)render_settings->ViewportHeight, render_settings->Near, render_settings->Far);
glm::mat4 projection = glm::perspectiveRH<float>(fovRad, (float)render_settings.ViewportWidth / (float)render_settings.ViewportHeight, render_settings.Near, render_settings.Far);
// glm::mat4 correction = {1, 0, 0, 0,
// 0,-1, 0, 0,
// 0, 0, 0.5f,0.5f,
// 0,0, 0, 1};
// projection = correction * projection;
return projection;
}
glm::mat4x4 HydraCamera::GetOrthoProjection()
{
HydraRenderSettings render_settings = GetEngine()->RenderSettings();
float fovRad = glm::radians(render_settings.FOV);
glm::mat4 projection = glm::ortho<float>(0.0f, render_settings.DisplayWidth, 0, render_settings.DisplayHeight, 0.0f, 1000.0f);
return projection;
}
glm::vec3 HydraCamera::GetPosition()
{
glm::dvec3 actor_pos = glm::dvec3(0,0,0);
if(m_attached_actor != INVALID_HYDRA_ID)
{
HydraActor* actor = GetEngine()->ActorManager()->GetActor(m_attached_actor);
if(actor != nullptr)
{
actor_pos = (GetEngine()->ActorManager()->GetActorPosition(m_attached_actor)) * glm::dvec3(1, 1, 1);
}
}
return actor_pos;
}
void HydraCamera::AttachToActor(HydraID actorID)
{
m_attached_actor = actorID;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef HYDRACAMERA
#define HYDRACAMERA
#include "../engine/HydraObject.h"
#include <GLMIncludes.h>
class CLASS_DEFINE HydraCamera : public HydraObject
{
private:
glm::vec4 m_right = glm::vec4(1, 0, 0, 1);
glm::vec4 m_up = glm::vec4(0, 1, 0, 1);
glm::vec4 m_forward = glm::vec4(0, 0, -1, 1);
HydraID m_attached_actor = INVALID_HYDRA_ID;
public:
glm::mat4x4 GetView();
glm::mat4x4 GetProjection();
glm::mat4x4 GetOrthoProjection();
HydraID GetAttachedActor() {return m_attached_actor;}
glm::vec3 GetPosition();
void AttachToActor(HydraID actorID);
};
#endif /* HYDRACAMERA */
@@ -0,0 +1,90 @@
#ifndef HYDRACOMPONENTARRAY
#define HYDRACOMPONENTARRAY
#include "../engine/HydraObject.h"
#include <array>
#include <unordered_map>
#include <mutex>
class IHydraComponentArray
{
public:
virtual ~IHydraComponentArray() = default;
virtual void EntityDeleted(HydraID entity_id) = 0;
};
template<typename T>
class HydraComponentArray : public IHydraComponentArray
{
private:
std::array<T, MAX_ACTORS> m_components;
std::unordered_map<HydraID, HydraID> m_entity_to_component;
std::unordered_map<HydraID, HydraID> m_component_to_entity;
std::mutex m_mutex;
uint32_t m_component_count = 0;
public:
void RemoveComponent(HydraID entity_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
assert(m_entity_to_component.find(entity_id) == m_entity_to_component.end() && "Trying to remove a component that doesnt exist");
HydraID component_index = m_entity_to_component[entity_id];
HydraID last_component_index = m_component_count -1;
HydraID last_entity_id = m_component_to_entity[last_component_index];
if(last_component_index != component_index)
{
m_components[component_index] = m_components[last_component_index];
m_entity_to_component[last_entity_id] = component_index;
m_components[last_component_index] = {};
}
else
{
m_components[component_index] = {};
}
m_entity_to_component.erase(entity_id);
m_component_to_entity.erase(component_index);
}
void AddComponent(HydraID entity_id, T component)
{
std::lock_guard<std::mutex> lock(m_mutex);
assert(m_entity_to_component.find(entity_id) == m_entity_to_component.end() && "Trying to add a component that already exist");
m_components[m_component_count] = component;
m_entity_to_component.insert({entity_id, m_component_count});
m_component_to_entity.insert({m_component_count, entity_id});
m_component_count++;
}
bool HasComponent(HydraID entity_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_entity_to_component.find(entity_id) != m_entity_to_component.end();
}
T& GetComponent(HydraID entity_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
assert(m_entity_to_component.find(entity_id) != m_entity_to_component.end() && "Trying to get a component that doesnt exist");
HydraID component_index = m_entity_to_component[entity_id];
return m_components[component_index];
}
void EntityDeleted(HydraID entity_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_entity_to_component.find(entity_id) != m_entity_to_component.end())
{
RemoveComponent(entity_id);
}
}
};
#endif /* HYDRACOMPONENTARRAY */
@@ -0,0 +1,83 @@
#ifndef HYDRAECSCOMPONENTMANAGER
#define HYDRAECSCOMPONENTMANAGER
#include "../engine/HydraObject.h"
#include "HydraComponentArray.h"
#include <unordered_map>
#include <memory>
using ComponentTypeID = uint8_t;
class HydraComponentManager :public HydraObject
{
private:
std::unordered_map<std::string, std::shared_ptr<IHydraComponentArray>> m_component_arrays;
std::unordered_map<std::string, ComponentTypeID> m_component_types;
ComponentTypeID m_current_component_type_id = 0;
template<typename T>
std::shared_ptr<HydraComponentArray<T>> _GetComponentArray()
{
std::string type_name = std::string(typeid(T).name());
assert(m_component_types.find(type_name) != m_component_types.end() && "Component type does not exist");
return std::static_pointer_cast<HydraComponentArray<T>>(m_component_arrays[type_name]);
}
public:
template<typename T>
ComponentTypeID RegisterComponentType()
{
std::string type_name = std::string(typeid(T).name());
assert(m_component_types.find(type_name) == m_component_types.end() && "Component name already in use");
m_component_types.insert({type_name, m_current_component_type_id});
m_component_arrays.insert({type_name, std::make_shared<HydraComponentArray<T>>()});
return m_current_component_type_id++;
}
template<typename T>
ComponentTypeID GetComponentTypeID()
{
std::string type_name = std::string(typeid(T).name());
assert(m_component_types.find(type_name) != m_component_types.end() && "Component type does not exist");
return m_component_types[type_name];
}
template<typename T>
void AddComponent(HydraID entity_id, T component)
{
_GetComponentArray<T>()->AddComponent(entity_id, component);
}
template<typename T>
T& GetComponent(HydraID entity_id)
{
return _GetComponentArray<T>()->GetComponent(entity_id);
}
template<typename T>
bool HasComponent(HydraID entity_id)
{
return _GetComponentArray<T>()->HasComponent(entity_id);
}
template<typename T>
void RemoveComponent(HydraID entity_id)
{
_GetComponentArray<T>()->RemoveComponent(entity_id);
}
void EntityDeleted(HydraID entity_id)
{
for(auto comp_array : m_component_arrays)
{
(*comp_array.second).EntityDeleted(entity_id);
}
}
};
#endif /* HYDRACOMPONENTMANAGER */
+17
View File
@@ -0,0 +1,17 @@
#include "HydraECS.h"
void HydraECS::Init()
{
m_component_manager = std::make_unique<HydraComponentManager>();
m_entity_manager = std::make_unique<HydraEntityManager>();
m_system_manager = std::make_unique<HydraSystemManager>();
}
void HydraECS::Shutdown()
{
m_system_manager->Shutdown();
m_component_manager.release();
m_entity_manager.release();
m_system_manager.release();
}
+105
View File
@@ -0,0 +1,105 @@
#ifndef HYDRAECS
#define HYDRAECS
#include "../engine/HydraObject.h"
#include "HydraComponentManager.h"
#include "HydraEntityManager.h"
#include "HydraSystemManager.h"
#include <memory>
class HydraECS : HydraObject
{
private:
std::unique_ptr<HydraEntityManager> m_entity_manager;
std::unique_ptr<HydraComponentManager> m_component_manager;
std::unique_ptr<HydraSystemManager> m_system_manager;
public:
void Init();
void Shutdown();
HydraID CreateEntity()
{
return m_entity_manager->CreateEntity();
}
void DestroyEntity(HydraID entity_id)
{
m_entity_manager->DeleteEntity(entity_id);
m_component_manager->EntityDeleted(entity_id);
m_system_manager->EntityDeleted(entity_id);
}
template <typename T>
void RegisterComponentType()
{
m_component_manager->RegisterComponentType<T>();
}
template <typename T>
HydraID GetComponentType()
{
return m_component_manager->GetComponentTypeID<T>();
}
template <typename T>
void AddComponent(HydraID entity_id, T component)
{
// Add teh component to the entity
m_component_manager->AddComponent<T>(entity_id, component);
// Get the current entity signature and update it to include
// the new component
auto signature = m_entity_manager->GetSignature(entity_id);
signature.set(m_component_manager->GetComponentTypeID<T>(), true);
m_entity_manager->SetSignature(entity_id, signature);
// Tell the sytem manager that the entities signature has changed
m_system_manager->EntitySignatureChanged(entity_id, signature);
}
template <typename T>
void RemoveComponent(HydraID entity_id)
{
// Remove the component from the entity
m_component_manager->RemoveComponent<T>(entity_id);
// Get the current signature, remove the component from it and update
auto signature = m_entity_manager->GetSignature(entity_id);
signature.set(m_component_manager->GetComponentTypeID<T>(), false);
m_entity_manager->SetSignature(entity_id, signature);
// Tell the system manager that the entitys signature has changed
m_system_manager->EntitySignatureChanged(entity_id, signature);
}
template <typename T>
bool HasComponent(HydraID entity_id)
{
return m_component_manager->HasComponent<T>(entity_id);
}
template <typename T>
T &GetComponent(HydraID entity_id)
{
return m_component_manager->GetComponent<T>(entity_id);
}
template <typename T>
std::shared_ptr<T> RegisterSystem()
{
return m_system_manager->RegisterSystem<T>();
}
template <typename T>
void SetSystemSignature(HydraSignature signature)
{
m_system_manager->SetSignature<T>(signature);
}
template <typename T>
std::shared_ptr<T> GetSystem()
{
return m_system_manager->GetSystem<T>();
}
void InitialiseComponents()
{
m_system_manager->InitialiseComponents();
}
};
#endif /* HYDRAECS */
+15
View File
@@ -0,0 +1,15 @@
#ifndef HYDRAENTITY
#define HYDRAENTITY
#include "../engine/HydraObject.h"
struct HydraEntity
{
HydraID entity_id = INVALID_HYDRA_ID;
HydraSignature signature;
};
#endif /* HYDRAENTITY */
@@ -0,0 +1,59 @@
#ifndef HYDRAENTITYMANAGER
#define HYDRAENTITYMANAGER
#include "../engine/HydraObject.h"
#include "HydraEntity.h"
#include <array>
#include <mutex>
#include <queue>
class HydraEntityManager : public HydraObject
{
private:
std::array<HydraSignature, MAX_ACTORS> m_entities;
std::mutex m_mutex;
std::queue<HydraID> m_available_entity_ids;
uint32_t m_entities_created;
public:
HydraEntityManager()
{
for(uint32_t i = 0; i < MAX_ACTORS; i ++)
{
m_available_entity_ids.push(i);
}
}
HydraID CreateEntity()
{
std::lock_guard<std::mutex> lock(m_mutex);
assert(m_entities_created < MAX_ACTORS && "Too many entities created");
HydraID entity_id = m_available_entity_ids.front();
m_available_entity_ids.pop();
m_entities_created++;
return entity_id;
}
void DeleteEntity(HydraID entity_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
assert(entity_id < MAX_ACTORS && "Entity ID out of range");
m_available_entity_ids.push(entity_id);
m_entities[entity_id].reset();
m_entities_created--;
}
void SetSignature(HydraID entity_id, HydraSignature signature)
{
assert(entity_id < MAX_ACTORS && "Invalid entity it");
m_entities[entity_id] = signature;
}
HydraSignature GetSignature(HydraID entity_id)
{
assert(entity_id < MAX_ACTORS && "Invalid entity it");
return m_entities[entity_id];
}
};
#endif /* HYDRAENTITYMANAGER */
+18
View File
@@ -0,0 +1,18 @@
#include "HydraSystem.h"
void HydraSystem::Update(float delta_t_seconds)
{
UpdateSystem(delta_t_seconds);
}
void HydraSystem::InitialiseComponents()
{
for(auto it = EntitiesToCreate.begin(); it != EntitiesToCreate.end(); ++it)
{
HydraID actor_id = *it;
InitialiseComponent(actor_id);
}
EntitiesToCreate.clear();
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef HYDRASYSTEM
#define HYDRASYSTEM
#include "../engine/HydraObject.h"
#include <set>
class HydraSystem : public HydraObject
{
public:
std::set<HydraID> Entities;
std::set<HydraID> EntitiesToCreate;
void Update(float delta_t_seconds);
void InitialiseComponents();
virtual void Shutdown() {};
virtual void Initialise(){};
protected:
virtual void UpdateSystem(float delta_t_seconds) = 0;
virtual void InitialiseComponent(HydraID actor_id) {};
};
#endif /* HYDRASYSTEM */
@@ -0,0 +1 @@
#include "HydraSystemManager.h"
+106
View File
@@ -0,0 +1,106 @@
#ifndef HYDRASYSTEMMANAGER
#define HYDRASYSTEMMANAGER
#include "../engine/HydraObject.h"
#include "HydraSystem.h"
#include "HydraEntity.h"
//#include "../ecssystems/HydraECSRenderSystem.h"
#include <memory>
#include <unordered_map>
class HydraSystemManager : public HydraObject
{
private:
std::unordered_map<std::string, HydraSignature> m_signatures{};
std::unordered_map<std::string, std::shared_ptr<HydraSystem>> m_systems{};
public:
void Shutdown()
{
for (auto const& pair : m_systems)
{
auto const& system = pair.second;
system->Shutdown();
}
}
template <typename T> std::shared_ptr<T> GetSystem()
{
std::string type_name = std::string(typeid(T).name());
auto it = m_systems.find(type_name);
assert(it!= m_systems.end() && "System not found.");
return std::static_pointer_cast<T>( it->second);
}
template <typename T>
std::shared_ptr<T> RegisterSystem()
{
std::string type_name = std::string(typeid(T).name());
assert(m_systems.find(type_name) == m_systems.end() && "Registering system more than once.");
// Create a pointer to the system and return it so it can be used externally
auto system = std::make_shared<T>();
system->Initialise();
m_systems.insert({type_name, system});
return system;
}
template<typename T> void SetSignature(HydraSignature signature)
{
std::string type_name = std::string(typeid(T).name());
assert(m_systems.find(type_name) != m_systems.end() && "System used before registered.");
// Set the signature for this system
m_signatures.insert({type_name, signature});
}
void EntitySignatureChanged(HydraID entity_id, HydraSignature signature)
{
// Notify each system that an entity's signature changed
for (auto const& pair : m_systems)
{
//auto const& type = pair.first;
std::string type = pair.first;
auto const& system = pair.second;
auto const& system_signature = m_signatures[type];
// Entity signature matches system signature - insert into set
if ((signature & system_signature) == system_signature)
{
system->EntitiesToCreate.insert(entity_id);
system->Entities.insert(entity_id);
}
// Entity signature does not match system signature - erase from set
else
{
system->Entities.erase(entity_id);
system->EntitiesToCreate.erase(entity_id);
}
}
}
void EntityDeleted(HydraID entity_id)
{
for (auto const& pair : m_systems)
{
auto const& system = pair.second;
system->Entities.erase(entity_id);
system->EntitiesToCreate.erase(entity_id);
}
}
void InitialiseComponents()
{
for (auto const& pair : m_systems)
{
auto const& system = pair.second;
system->InitialiseComponents();
}
}
};
#endif /* HYDRASYSTEMMANAGER */
@@ -0,0 +1,14 @@
#ifndef HYDRAECSLIGHTCOMPONENT
#define HYDRAECSLIGHTCOMPONENT
#include "../../engine/HydraEngine.h"
struct HydraLightComponent
{
glm::vec4 light_colour;
float light_intensity;
HydraID entity_id;
uint32_t light_type;
float padding[1];
};
#endif /* HYDRAECSLIGHTCOMPONENT */
@@ -0,0 +1,11 @@
#ifndef HYDRAECSMATERIALCOMPONENT
#define HYDRAECSMATERIALCOMPONENT
#include "../../engine/HydraEngine.h"
struct HydraMaterialComponent
{
HydraID material_id = INVALID_HYDRA_ID;
};
#endif /* HYDRAECSMATERIALCOMPONENT */
@@ -0,0 +1,17 @@
#ifndef HYDRAECSMESHCOMPONENT
#define HYDRAECSMESHCOMPONENT
#include "../../engine/HydraObject.h"
struct HydraMeshComponent
{
HydraID mesh_id = INVALID_HYDRA_ID;
HydraID vertex_buffer_id = INVALID_HYDRA_ID;
HYDRA_STATE mesh_state = HYDRA_STATE::Empty;
};
#endif /* HYDRAECSMESHCOMPONENT */
@@ -0,0 +1,18 @@
#ifndef HYDRAECSPHYSICSCOMPONENT
#define HYDRAECSPHYSICSCOMPONENT
#include "../engine/HydraEngine.h"
//#include "../physics/HydraPhysicsDefinition.h"
struct HydraPhysicsComponent
{
//
HYDRA_STATE physics_state = HYDRA_STATE::Empty;
// HydraPhysicsDefinitionStruct physics_definition;
};
#endif /* HYDRAECSPHYSICSCOMPONENT */
@@ -0,0 +1,16 @@
#ifndef HYDRAECSPOSITIONCOMPONENT
#define HYDRAECSPOSITIONCOMPONENT
struct HydraPositionComponent
{
glm::dvec3 position = {};
glm::vec3 orientation = {};
glm::vec3 scale = {1,1,1};
glm::vec3 velocity = {};
glm::mat4 transform = glm::mat4(1);
glm::mat4 parent_transform = glm::mat4(1);
bool needs_update = true;
};
#endif /* HYDRAECSPOSITIONCOMPONENT */
@@ -0,0 +1,10 @@
#ifndef HYDRAECSRENDERABLECOMPONENT
#define HYDRAECSRENDERABLECOMPONENT
#include "../../engine/HydraEngine.h"
struct HydraRenderableComponent
{
HydraSignature renderable_types;
};
#endif /* HYDRAECSRENDERABLECOMPONENT */
@@ -0,0 +1,18 @@
#ifndef HYDRAECSSHADOWCOMPONENT
#define HYDRAECSSHADOWCOMPONENT
//#include "../helper/VulkanHelper.h"
//#include "../buffer/HydraShadowMapTransform.h"
struct HydrahadowComponent
{
// HydraID shadow_map_id; //4
// HydraID shadow_map_index; //8
// float padding0; //12
// float padding1; //16
// HydraShadowMapTransform shadow_transforms[6]; //880 (144*6)
// float padding[20]; //960
};
#endif /* HYDRAECSSHADOWCOMPONENT */
@@ -0,0 +1,11 @@
#ifndef HYDRATEXTURECOMPONENT
#define HYDRATEXTURECOMPONENT
#include "../engine/HydraEngine.h"
struct HydraTextureComponent
{
HydraID diffuse_texture_id = INVALID_HYDRA_ID;
};
#endif /* HYDRATEXTURECOMPONENT */
@@ -0,0 +1,55 @@
#include "HydraLightSystem.h"
#include "../../engine/HydraEngine.h"
#include "../HydraECS.h"
#include "../components/HydraLightComponent.h"
#include "../components/HydraPositionComponent.h"
#include "../../buffer/HydraLightBufferManager.h"
#include "../../buffer/HydraLightBuffer.h"
#include "../../scheduler/HydraTaskScheduler.h"
#include "../../task/buffer/HydraCreateGPUBufferTask.hpp"
#include "../../task/buffer/HydraUpdatePartialGPUBufferTask.hpp"
#include "../../actor/HydraActorManager.h"
#include <GLMIncludes.h>
void HydraLightSystem::Initialise()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
task->Intialise("LightBuffer", 1, MAX_LIGHTS * sizeof(HydraLightComponent), &m_light_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
}
uint32_t HydraLightSystem::GetLightCount()
{
return m_lights.size();
}
void HydraLightSystem::InitialiseComponent(HydraID entity_id)
{
HydraLightBufferManager *light_man = GetEngine()->LightBufferManager();
uint32_t light_count = light_man->GetLightCount();
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(entity_id);
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
m_lights.push_back(light_comp);
}
void HydraLightSystem::UpdateSystem(float delta_t_seconds)
{
_WriteToGPU();
}
void HydraLightSystem::_WriteToGPU()
{
void *buffer = static_cast<void *>(m_lights.data());
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdatePartialGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdatePartialGPUBufferTask *task = static_cast<HydraUpdatePartialGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_light_buffer_id, 0, sizeof(HydraLightComponent) * m_lights.size(), buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
}
@@ -0,0 +1,27 @@
#ifndef HYDRALIGHTSYSTEM
#define HYDRALIGHTSYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include "../components/HydraLightComponent.h"
#include <GLMIncludes.h>
#include <queue>
#include <vector>
class HydraLightSystem : public HydraSystem
{
public:
void Initialise() override;
uint32_t GetLightCount();
protected:
void InitialiseComponent(HydraID entity_id) override;
virtual void UpdateSystem(float delta_t_seconds);
private:
void _WriteToGPU();
HydraID m_light_buffer_id = INVALID_HYDRA_ID;
std::vector<HydraLightComponent> m_lights;
};
#endif /* HYDRALIGHTSYSTEM */
@@ -0,0 +1,57 @@
#include "HydraMaterialSystem.h"
#include "../../engine/HydraEngine.h"
#include "../HydraECS.h"
#include "../components/HydraMaterialComponent.h"
#include "../../buffer/HydraMaterialBufferManager.h"
#include "../../buffer/HydraTextureBufferManager.h"
#include "../../scheduler/HydraTaskScheduler.h"
#include "../../task/buffer/HydraCreateGPUBufferTask.hpp"
#include "../../task/buffer/HydraUpdateWholeGPUBufferTask.hpp"
#include "../../actor/HydraActorManager.h"
void HydraMaterialSystem::Initialise()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
task->Intialise("MaterialBuffer", 1, MAX_MATERIALS * sizeof(HydraMaterialBuffer), &m_material_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
task->Intialise("TextureBuffer", 1, MAX_TEXTURES * sizeof(uint64_t), &m_texture_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
}
void HydraMaterialSystem::InitialiseComponent(HydraID entity_id)
{
}
void HydraMaterialSystem::UpdateSystem(float delta_t_seconds)
{
_WriteToGPU();
}
void HydraMaterialSystem::_WriteToGPU()
{
void* buffer = GetEngine()->MaterialBufferManager()->GetMaterialBuffer();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdateWholeGPUBufferTask *task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_material_buffer_id, buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
buffer = GetEngine()->TextureBufferManager()->GetTextureBuffer();
update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_texture_buffer_id, buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
}
@@ -0,0 +1,27 @@
#ifndef HYDRAMATERIALSYSTEM
#define HYDRAMATERIALSYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include <GLMIncludes.h>
#include <queue>
#include <vector>
class HydraMaterialSystem : public HydraSystem
{
public:
void Initialise() override;
protected:
void InitialiseComponent(HydraID entity_id) override;
virtual void UpdateSystem(float delta_t_seconds);
private:
void _WriteToGPU();
HydraID m_material_buffer_id = INVALID_HYDRA_ID;
HydraID m_texture_buffer_id = INVALID_HYDRA_ID;
};
#endif /* HYDRAMATERIALSYSTEM */
@@ -0,0 +1,44 @@
#include "HydraMeshSystem.h"
#include "../HydraECS.h"
#include "../../engine/HydraEngine.h"
#include "../components/HydraMeshComponent.h"
#include "../../buffer/HydraBufferManager.h"
#include "../../scheduler/HydraTaskScheduler.h"
#include "../../task/buffer/HydraCreateVertexBufferTask.hpp"
#include "../../task/buffer/HydraUpdateVertexBufferTask.hpp"
#include "../../mesh/HydraMeshManager.h"
void HydraMeshSystem::Initialise()
{
}
void HydraMeshSystem::InitialiseComponent(HydraID entity_id)
{
HydraECS* ecs = GetEngine()->ECS();
HydraBufferManager *buffer_manager = GetEngine()->BufferManager();
HydraMeshComponent& mesh_comp = ecs->GetComponent<HydraMeshComponent>(entity_id);
HydraMeshManager* mesh_man = GetEngine()->MeshManager();
HydraMesh* mesh = mesh_man->GetMesh(mesh_comp.mesh_id);
uint32_t vertex_buffer_size = sizeof(StandardVertex) * mesh->vertexes.size();
uint32_t index_buffer_size = sizeof(uint32_t) * mesh->indexes.size();
uint32_t triangle_count = mesh->indexes.size();// / 3;
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
//Create VAO and Vertex Buffer storage
HydraID create_vertex_task_id = task_scheduler->CreateTask<HydraCreateVertexBufferTask>(HydraThreadAffinity::Render);
HydraCreateVertexBufferTask *vertex_task = static_cast<HydraCreateVertexBufferTask *>(task_scheduler->GetTask(create_vertex_task_id));
vertex_task->Intialise(vertex_buffer_size, index_buffer_size, triangle_count, &mesh_comp.vertex_buffer_id);
task_scheduler->WaitForTask(create_vertex_task_id);
//Update vertex buffer
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateVertexBufferTask>(HydraThreadAffinity::Render);
HydraUpdateVertexBufferTask *vertex_update_task = static_cast<HydraUpdateVertexBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
vertex_update_task->Intialise(mesh_comp.vertex_buffer_id, &mesh->vertexes[0], &mesh->indexes[0]);
task_scheduler->WaitForTask(update_buffer_task_id);
}
@@ -0,0 +1,19 @@
#ifndef HYDRAMESHSYSTEM
#define HYDRAMESHSYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include <GLMIncludes.h>
#include <queue>
class HydraMeshSystem : public HydraSystem
{
public:
void Initialise() override;
protected:
void InitialiseComponent(HydraID entity_id) override;
virtual void UpdateSystem(float delta_t_seconds){}
};
#endif /* HYDRAMESHSYSTEM */
@@ -0,0 +1,6 @@
#include "HydraRenderSystem.h"
void HydraRenderSystem::Initialise()
{
}
@@ -0,0 +1,18 @@
#ifndef HYDRARENDERSYSTEM
#define HYDRARENDERSYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include <GLMIncludes.h>
#include <queue>
class HydraRenderSystem : public HydraSystem
{
public:
void Initialise() override;
protected:
virtual void UpdateSystem(float delta_t_seconds){}
};
#endif /* HYDRARENDERSYSTEM */
@@ -0,0 +1,93 @@
#include "HydraTransformSystem.h"
#include "../../engine/HydraEngine.h"
#include "../HydraECS.h"
#include "../components/HydraPositionComponent.h"
#include "../../scheduler/HydraTaskScheduler.h"
#include "../../task/buffer/HydraCreateGPUBufferTask.hpp"
#include "../../task/buffer/HydraUpdateWholeGPUBufferTask.hpp"
#include "../../actor/HydraActorManager.h"
void HydraTransformSystem::UpdateTransform(HydraID actor_id)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actor_id);
pos_comp.needs_update = true;
m_entities_to_update.push(actor_id);
}
void HydraTransformSystem::Initialise()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
task->Intialise("PositionsBuffer", 1, MAX_ACTORS * sizeof(glm::mat4),
&m_transform_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
m_model_matrix.resize(MAX_ACTORS);
}
void HydraTransformSystem::UpdateSystem(float delta_t_seconds)
{
HydraECS *ecs = GetEngine()->ECS();
while(m_entities_to_update.size() > 0)
{
HydraID actor_id = m_entities_to_update.front();
m_entities_to_update.pop();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actor_id);
if(pos_comp.needs_update)
{
HydraID parent_id = GetEngine()->ActorManager()->GetRoot(actor_id);
glm::mat4 identity = glm::mat4(1);
_UpdateChild(INVALID_HYDRA_ID, parent_id, identity);
}
}
_WriteToGPU();
}
void HydraTransformSystem::InitialiseComponent(HydraID actor_id)
{
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actor_id);
if (pos_comp.needs_update)
{
glm::mat4 identity = glm::mat4(1);
_UpdateChild(INVALID_HYDRA_ID, actor_id, identity);
}
}
void HydraTransformSystem::_UpdateChild(HydraID parent_id, HydraID actor_id, glm::mat4 parent_transform)
{
HydraECS *ecs = GetEngine()->ECS();
std::vector<HydraID> &child_ids = GetEngine()->ActorManager()->GetChildren(actor_id);
glm::mat4 trans = parent_transform;
if (ecs->HasComponent<HydraPositionComponent>(actor_id))
{
HydraPositionComponent &pos_comp = ecs->GetComponent<HydraPositionComponent>(actor_id);
glm::mat4 trans_matrix = glm::translate(glm::vec3(pos_comp.position.x, pos_comp.position.y, pos_comp.position.z));
glm::mat4 rot_matrix = glm::toMat4(glm::quat(pos_comp.orientation));
glm::mat4 scale_matrix = glm::scale(pos_comp.scale);
glm::mat4 model_matrix = trans_matrix * rot_matrix * scale_matrix;
pos_comp.transform = trans * model_matrix;
pos_comp.needs_update = false;
m_model_matrix[actor_id] = pos_comp.transform;
trans = pos_comp.transform;
}
for (uint32_t child_idx = 0; child_idx < child_ids.size(); child_idx++)
{
_UpdateChild(actor_id, child_ids[child_idx], trans);
}
}
void HydraTransformSystem::_WriteToGPU()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdateWholeGPUBufferTask *task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_transform_buffer_id, &m_model_matrix[0]);
task_scheduler->WaitForTask(update_buffer_task_id);
}
@@ -0,0 +1,27 @@
#ifndef HYDRAECSTRANSFORMSYSTEM
#define HYDRAECSTRANSFORMSYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include <GLMIncludes.h>
#include <queue>
class HydraTransformSystem : public HydraSystem
{
public:
void UpdateTransform(HydraID actor_id);
void Initialise() override;
protected:
virtual void UpdateSystem(float delta_t_seconds) override;
void InitialiseComponent(HydraID actor_id) override;
private:
void _UpdateChild(HydraID parent_id, HydraID actor_id, glm::mat4 parent_transform);
void _WriteToGPU();
HydraID m_transform_buffer_id = INVALID_HYDRA_ID;
std::queue<HydraID> m_entities_to_update;
std::vector<glm::mat4> m_model_matrix;
};
#endif /* HYDRAECSTRANSFORMSYSTEM */
+390
View File
@@ -0,0 +1,390 @@
#include "HydraEngine.h"
#include "HydraInputManager.h"
#include "../scheduler/HydraTaskScheduler.h"
#include "../scheduler/HydraTaskScheduler.h"
#include "../windowmanager/HydraWindowManager.h"
#include "../game/HydraGameProxy.h"
#include "../renderer/HydraRenderer.h"
#include "../buffer/HydraBufferManager.h"
#include "../buffer/HydraVertexBufferManager.h"
#include "../buffer/HydraTextureBufferManager.h"
#include "../buffer/HydraMaterialBufferManager.h"
#include "../buffer/HydraLightBufferManager.h"
#include "../ecs/HydraECS.h"
#include "../ecs/systems/HydraTransformSystem.h"
#include "../ecs/systems/HydraMeshSystem.h"
#include "../ecs/systems/HydraRenderSystem.h"
#include "../ecs/systems/HydraMaterialSystem.h"
#include "../ecs/systems/HydraLightSystem.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
#include "../ecs/components/HydraTextureComponent.h"
#include "../ecs/components/HydraMaterialComponent.h"
#include "../ecs/components/HydraLightComponent.h"
#include "../camera/HydraCamera.h"
#include "../actor/HydraActorManager.h"
#include "../pipeline/HydraPipeline.h"
#include "../pipeline/HydraForwardPipeline.h"
#include "../pipeline/HydraDeferredPipeline.h"
#include "../task/windowmanager/HydraInitialiseWindowManagerTask.hpp"
#include "../task/windowmanager/HydraShutdownWindowManagerTask.hpp"
#include "../task/windowmanager/HydraProcessInputTask.hpp"
#include "../task/renderer/HydraInitialiseRendererTask.hpp"
#include "../task/renderer/HydraRenderTask.hpp"
#include "../task/pipeline/HydraInitialisePipelineTask.hpp"
#include "../task/pipeline/HydraShutdownPipelineTask.hpp"
#include "../task/pipeline/HydraRenderPipelineTask.hpp"
#include "../task/ecs/HydraUpdateSystemTask.hpp"
#include "../task/ecs/HydraInitialiseComponentsTask.hpp"
#include "../task/buffer/HydraShutdownBufferManagerTask.hpp"
#include "../task/buffer/HydraInitialiseTextureManagerTask.hpp"
#include "../task/actor/HydraUpdatePlayerTask.h"
#include "../mesh/HydraMeshManager.h"
HydraTaskScheduler *const HydraEngine::TaskScheduler()
{
return m_task_scheduler;
}
void HydraEngine::InitialiseGame(HydraGameProxy *game)
{
m_game = game;
}
void HydraEngine::Start()
{
_CreateManagers();
_InitialiseManagers();
_InitialiseSystems();
m_game->Initialise();
_GameLoop();
_Shutdown();
}
HydraWindowManager *const HydraEngine::WindowManager()
{
return m_window_manager;
}
HydraRenderSettings HydraEngine::RenderSettings()
{
return m_render_settings;
}
HydraInputManager *const HydraEngine::InputManager()
{
return m_input_manager;
}
HydraRenderer *const HydraEngine::Renderer()
{
return m_renderer;
}
HydraECS *const HydraEngine::ECS()
{
return m_ecs;
}
HydraActorManager *const HydraEngine::ActorManager()
{
return m_actor_manager;
}
HydraCamera *const HydraEngine::Camera()
{
return m_camera;
}
HydraBufferManager *const HydraEngine::BufferManager()
{
return m_buffer_manager;
}
HydraVertexBufferManager *const HydraEngine::VertexBufferManager()
{
return m_vertex_buffer_manager;
}
HydraMeshManager *const HydraEngine::MeshManager()
{
return m_mesh_manager;
}
HydraPipeline *const HydraEngine::Pipeline()
{
return m_pipeline;
}
HydraTextureBufferManager *const HydraEngine::TextureBufferManager()
{
return m_texture_buffer_manager;
}
HydraMaterialBufferManager *const HydraEngine::MaterialBufferManager()
{
return m_material_buffer_manager;
}
HydraLightBufferManager *const HydraEngine::LightBufferManager()
{
return m_light_buffer_manager;
}
void HydraEngine::PossessPlayer(HydraID actor_id)
{
m_possessed_actor_id = actor_id;
}
HydraID HydraEngine::GetPossessedPlayer()
{
return m_possessed_actor_id;
}
float HydraEngine::GetDeltaT()
{
return m_delta_t;
}
uint32_t HydraEngine::GetLightCount()
{
return m_light_system->GetLightCount();
}
void HydraEngine::_CreateManagers()
{
m_camera = new HydraCamera();
m_task_scheduler = new HydraTaskScheduler();
m_window_manager = new HydraWindowManager();
m_input_manager = new HydraInputManager();
m_renderer = new HydraRenderer();
m_ecs = new HydraECS();
m_actor_manager = new HydraActorManager();
m_buffer_manager = new HydraBufferManager();
m_vertex_buffer_manager = new HydraVertexBufferManager();
m_mesh_manager = new HydraMeshManager();
m_pipeline = new HydraForwardPipeline();
m_deferred_pipeline = new HydraDeferredPipeline();
m_texture_buffer_manager = new HydraTextureBufferManager();
m_material_buffer_manager = new HydraMaterialBufferManager();
m_light_buffer_manager = new HydraLightBufferManager();
}
void HydraEngine::_InitialiseManagers()
{
m_task_scheduler->Initialise(1);
HydraID create_window_task_id = m_task_scheduler->CreateTask<HydraInitialiseWindowManagerTask>(HydraThreadAffinity::Render);
m_task_scheduler->WaitForTask(create_window_task_id);
HydraID create_renderer_task_id = m_task_scheduler->CreateTask<HydraInitialiseRendererTask>(HydraThreadAffinity::Render);
m_task_scheduler->WaitForTask(create_renderer_task_id);
m_mesh_manager->Initialise();
m_ecs->Init();
m_actor_manager->Initialise(MAX_ACTORS);
m_buffer_manager->Initialise();
m_vertex_buffer_manager->Initialise();
m_texture_buffer_manager->Intialise();
m_material_buffer_manager->Intialise();
m_light_buffer_manager->Initialise();
}
void HydraEngine::_InitialiseSystems()
{
m_ecs->RegisterComponentType<HydraPositionComponent>();
m_ecs->RegisterComponentType<HydraMeshComponent>();
m_ecs->RegisterComponentType<HydraRenderableComponent>();
m_ecs->RegisterComponentType<HydraTextureComponent>();
m_ecs->RegisterComponentType<HydraMaterialComponent>();
m_ecs->RegisterComponentType<HydraLightComponent>();
m_mesh_system = m_ecs->RegisterSystem<HydraMeshSystem>();
m_transform_system = m_ecs->RegisterSystem<HydraTransformSystem>();
m_render_system = m_ecs->RegisterSystem<HydraRenderSystem>();
m_material_system = m_ecs->RegisterSystem<HydraMaterialSystem>();
m_light_system = m_ecs->RegisterSystem<HydraLightSystem>();
HydraSignature mesh_sig;
HydraSignature trans_sig;
HydraSignature render_sig;
HydraSignature material_sig;
HydraSignature light_sig;
mesh_sig.set(m_ecs->GetComponentType<HydraMeshComponent>(),true);
trans_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(),true);
render_sig.set(m_ecs->GetComponentType<HydraRenderableComponent>(),true);
material_sig.set(m_ecs->GetComponentType<HydraMaterialComponent>(),true);
light_sig.set(m_ecs->GetComponentType<HydraLightComponent>(), true);
m_ecs->SetSystemSignature<HydraMeshSystem>(mesh_sig);
m_ecs->SetSystemSignature<HydraTransformSystem>(trans_sig);
m_ecs->SetSystemSignature<HydraRenderSystem>(render_sig);
m_ecs->SetSystemSignature<HydraMaterialSystem>(material_sig);
m_ecs->SetSystemSignature<HydraLightSystem>(light_sig);
}
void HydraEngine::_UpdateSystems()
{
HydraID posUpdateBarrierID = m_task_scheduler->CreateBarrier();
HydraID update_trans_id = m_task_scheduler->CreateTask<HydraUpdateSystemTask>(HydraThreadAffinity::General, posUpdateBarrierID);
HydraUpdateSystemTask* update_trans_task = static_cast<HydraUpdateSystemTask*>(m_task_scheduler->GetTask(update_trans_id));
update_trans_task->Initialise(m_delta_t, m_transform_system);
HydraID update_mat_id = m_task_scheduler->CreateTask<HydraUpdateSystemTask>(HydraThreadAffinity::General, posUpdateBarrierID);
HydraUpdateSystemTask* update_mat_task = static_cast<HydraUpdateSystemTask*>(m_task_scheduler->GetTask(update_mat_id));
update_mat_task->Initialise(m_delta_t, m_material_system);
m_task_scheduler->StartTask(update_trans_id);
m_task_scheduler->StartTask(update_mat_id);
m_task_scheduler->WaitForBarrier(posUpdateBarrierID);
HydraID update_light_id = m_task_scheduler->CreateTask<HydraUpdateSystemTask>(HydraThreadAffinity::General);
HydraUpdateSystemTask* update_light_task = static_cast<HydraUpdateSystemTask*>(m_task_scheduler->GetTask(update_light_id));
update_light_task->Initialise(m_delta_t, m_light_system);
m_task_scheduler->WaitForTask(update_light_id);
}
void HydraEngine::_GameLoop()
{
// game loop
std::chrono::steady_clock clock;
int fpsFrameCount = 0;
int fpsHighLowCount = 0;
float fpsLow = 99999;
float fpsHigh = 0;
float totalTime = 0.0f;
bool fixed_tick = false;
std::chrono::time_point<std::chrono::steady_clock> last_tick = clock.now();
std::chrono::time_point<std::chrono::steady_clock> last_fixed_tick = clock.now();
// m_fps_label_id = UIManager()->CreateWidget<HydraUILabelWidget>();
// HydraUILabelWidget* label = (HydraUILabelWidget*)UIManager()->GetWidget(m_fps_label_id);
// label->SetText("FPS");
// label->Position = glm::vec3(0, 200, 0);
// label->SetFont("Calibri", 10.0f);
HydraID initialise_pipeline_task_id = m_task_scheduler->CreateTask<HydraInitialisePipelineTask>(HydraThreadAffinity::Render);
HydraInitialisePipelineTask *pipeline_task = static_cast<HydraInitialisePipelineTask*>(m_task_scheduler->GetTask(initialise_pipeline_task_id));
pipeline_task->Initialise(m_pipeline);
m_task_scheduler->WaitForTask(initialise_pipeline_task_id);
HydraID initialise_def_pipeline_task_id = m_task_scheduler->CreateTask<HydraInitialisePipelineTask>(HydraThreadAffinity::Render);
HydraInitialisePipelineTask *pipeline_def_task = static_cast<HydraInitialisePipelineTask*>(m_task_scheduler->GetTask(initialise_def_pipeline_task_id));
pipeline_def_task->Initialise(m_deferred_pipeline);
m_task_scheduler->WaitForTask(initialise_def_pipeline_task_id);
while (m_running)
{
HydraID barrierID = m_task_scheduler->CreateBarrier();
std::chrono::time_point<std::chrono::steady_clock> this_tick = clock.now();
std::chrono::duration<float> diff = this_tick - last_tick;
std::chrono::duration<float> fixed_diff = this_tick - last_fixed_tick;
totalTime = totalTime += diff.count();
m_delta_t = diff.count();
float fixed_delta_t = fixed_diff.count();
if (fixed_delta_t > 0.016666666666f)
{
m_fixed_delta_t = fixed_diff.count();
last_fixed_tick = this_tick;
fixed_tick = true;
HydraID processInputID = m_task_scheduler->CreateTask<HydraProcessInputTask>(HydraThreadAffinity::Render, barrierID);
m_task_scheduler->StartTask(processInputID);
//Physics here
}
if (fpsFrameCount >= 15)
{
float fps = 1.0f / (totalTime / fpsFrameCount);
// m_fps_label->SetText("FPS: " + std::to_string(fps));
// label->SetText("FPS: " + std::to_string(fps));
fpsFrameCount = 0;
totalTime = 0.0f;
}
last_tick = this_tick;
fpsFrameCount++;
HydraID initialise_components_id = m_task_scheduler->CreateTask<HydraInitialiseComponentsTask>(HydraThreadAffinity::General, barrierID);
HydraID update_player_task_id = m_task_scheduler->CreateTask<HydraUpdatePlayerTask>(HydraThreadAffinity::General, barrierID);
m_task_scheduler->StartTask(initialise_components_id);
m_task_scheduler->StartTask(update_player_task_id);
m_task_scheduler->WaitForBarrier(barrierID);
m_game->Update(m_delta_t);
_UpdateSystems();
// HydraID render_task_id = m_task_scheduler->CreateTask<HydraRenderPipelineTask>(HydraThreadAffinity::Render);
// HydraRenderPipelineTask* render_task = static_cast<HydraRenderPipelineTask*>(m_task_scheduler->GetTask(render_task_id));
// render_task->Initialise(m_pipeline);
// m_task_scheduler->WaitForTask(render_task_id);
HydraID render_def_task_id = m_task_scheduler->CreateTask<HydraRenderPipelineTask>(HydraThreadAffinity::Render);
HydraRenderPipelineTask* render_def_task = static_cast<HydraRenderPipelineTask*>(m_task_scheduler->GetTask(render_def_task_id));
render_def_task->Initialise(m_deferred_pipeline);
m_task_scheduler->WaitForTask(render_def_task_id);
}
}
void HydraEngine::_Shutdown()
{
m_actor_manager->Shutdown();
m_ecs->Shutdown();
//Shutdown the buffer and vertex buffer managers
HydraID shutdown_buffer_mgr_id = m_task_scheduler->CreateTask<HydraShutdownBufferManagerTask>(HydraThreadAffinity::Render);
m_task_scheduler->WaitForTask(shutdown_buffer_mgr_id);
HydraID shutdown_pipeline_id = m_task_scheduler->CreateTask<HydraShutdownPipelineTask>(HydraThreadAffinity::Render);
HydraShutdownPipelineTask *pipeline_task = static_cast<HydraShutdownPipelineTask*>(m_task_scheduler->GetTask(shutdown_pipeline_id));
pipeline_task->Initialise(m_pipeline);
m_task_scheduler->WaitForTask(shutdown_pipeline_id);
m_task_scheduler->Shutdown();
delete m_actor_manager;
delete m_ecs;
delete m_input_manager;
delete m_window_manager;
delete m_task_scheduler;
delete m_buffer_manager;
delete m_vertex_buffer_manager;
delete m_pipeline;
delete m_texture_buffer_manager;
delete m_material_buffer_manager;
delete m_light_buffer_manager;
}
bool HydraEngine::KeyPressed(HYDRA_KEY_CODES key)
{
return m_input_manager->KeyPressed(key);
}
glm::vec2 HydraEngine::MouseChange()
{
return m_input_manager->MouseChange();
}
void HydraEngine::Exit()
{
m_running = false;
}
+102
View File
@@ -0,0 +1,102 @@
#ifndef HYDRAENGINE
#define HYDRAENGINE
#include "HydraObject.h"
#include "../windowmanager/HydraRenderSettings.h"
#include <GLMIncludes.h>
class HydraTaskScheduler;
class HydraGameProxy;
class HydraWindowManager;
class HydraInputManager;
class HydraRenderer;
class HydraECS;
class HydraActorManager;
class HydraCamera;
class HydraBufferManager;
class HydraVertexBufferManager;
class HydraMeshManager;
class HydraMeshSystem;
class HydraRenderSystem;
class HydraTransformSystem;
class HydraMaterialSystem;
class HydraPipeline;
class HydraTextureBufferManager;
class HydraMaterialBufferManager;
class HydraLightBufferManager;
class HydraLightSystem;
class CLASS_DEFINE HydraEngine : public HydraObject
{
public:
static HydraEngine *GetInstance()
{
static HydraEngine instance;
return &instance;
}
HydraTaskScheduler* const TaskScheduler();
void InitialiseGame(HydraGameProxy* game);
void Start();
bool KeyPressed(HYDRA_KEY_CODES key);
glm::vec2 MouseChange();
void Exit();
HydraWindowManager* const WindowManager();
HydraRenderSettings RenderSettings();
HydraInputManager* const InputManager();
HydraRenderer* const Renderer();
HydraECS* const ECS();
HydraActorManager* const ActorManager();
HydraCamera* const Camera();
HydraBufferManager* const BufferManager();
HydraVertexBufferManager* const VertexBufferManager();
HydraMeshManager* const MeshManager();
HydraPipeline* const Pipeline();
HydraTextureBufferManager* const TextureBufferManager();
HydraMaterialBufferManager* const MaterialBufferManager();
HydraLightBufferManager* const LightBufferManager();
void PossessPlayer(HydraID actor_id);
HydraID GetPossessedPlayer();
float GetDeltaT();
uint32_t GetLightCount();
private:
void _CreateManagers();
void _InitialiseManagers();
void _InitialiseSystems();
void _UpdateSystems();
void _GameLoop();
void _Shutdown();
class HydraGameProxy* m_game = nullptr;
HydraTaskScheduler* m_task_scheduler = nullptr;
HydraWindowManager* m_window_manager = nullptr;
HydraInputManager* m_input_manager = nullptr;
HydraRenderer* m_renderer = nullptr;
HydraECS* m_ecs = nullptr;
HydraActorManager* m_actor_manager = nullptr;
HydraCamera* m_camera = nullptr;
HydraBufferManager* m_buffer_manager = nullptr;
HydraVertexBufferManager* m_vertex_buffer_manager = nullptr;
HydraMeshManager* m_mesh_manager = nullptr;
HydraRenderSettings m_render_settings;
HydraPipeline* m_pipeline = nullptr;
HydraPipeline* m_deferred_pipeline = nullptr;
HydraTextureBufferManager* m_texture_buffer_manager = nullptr;
HydraMaterialBufferManager* m_material_buffer_manager = nullptr;
HydraLightBufferManager* m_light_buffer_manager = nullptr;
std::shared_ptr<HydraMeshSystem> m_mesh_system;
std::shared_ptr<HydraTransformSystem> m_transform_system;
std::shared_ptr<HydraRenderSystem> m_render_system;
std::shared_ptr<HydraMaterialSystem> m_material_system;
std::shared_ptr<HydraLightSystem> m_light_system;
bool m_running = true;
float m_delta_t = 0.0f;
float m_fixed_delta_t = 0.0f;
HydraID m_possessed_actor_id = INVALID_HYDRA_ID;
};
#endif /* HYDRAENGINE */
@@ -0,0 +1,82 @@
#include "HydraInputManager.h"
#include "../windowmanager/HydraWindowManager.h"
void HydraInputManager::ProcessInput()
{
bool quit = false;
m_mouse_change = glm::vec2();
m_key_down.clear();
m_key_up.clear();
while (!quit)
{
HydraKeyPressStuct key_press;
if (HydraWindowManager::GetKeyPress(key_press))
{
//DebugLog("Got Key " + std::to_string(key_press.key_code));
m_key_presses.push_back(key_press);
if ((key_press.key_code >= 0) && (key_press.key_code < 512))
{
if (key_press.key_action == KEY_PRESS_ACTIONS::HYDRA_KEY_PRESSED)
{
m_keys[key_press.key_code] = 1;
m_key_up.push_back(key_press.key_code);
}
else
{
m_keys[key_press.key_code] = 0;
m_key_down.push_back(key_press.key_code);
}
}
if (m_key_presses.size() > 10000)
{
m_key_presses.pop_back();
}
}
else
{
quit = true;
}
}
quit = false;
bool new_mouse_movement = false;
while (!quit)
{
HydraMouseMoveStruct mouse_move;
if (HydraWindowManager::GetMouseMove(mouse_move))
{
m_mouse_moves.push(glm::vec2(mouse_move.x, mouse_move.y));
new_mouse_movement = true;
if (m_mouse_moves.size() > 10000)
{
m_mouse_moves.pop();
}
}
else
{
quit = true;
}
}
if (m_mouse_moves.size() > 0)
{
if (!m_mouse_reset)
{
m_mouse_change = m_last_mouse - m_mouse_moves.back();
m_last_mouse = m_mouse_moves.back();
}
else
{
m_mouse_change = glm::vec2(0);
m_last_mouse = m_mouse_moves.back();
m_mouse_reset = false;
}
}
}
bool HydraInputManager::KeyPressed(HYDRA_KEY_CODES key)
{
return m_keys[(unsigned int)key] == 1;
}
@@ -0,0 +1,32 @@
#ifndef HYDRAINPUTMANAGER
#define HYDRAINPUTMANAGER
#include "HydraObject.h"
#include <vector>
#include <queue>
#include <glm/glm.hpp>
class HydraInputManager : public HydraObject
{
private:
int m_keys[512] = { };
std::vector<int> m_key_down;
std::vector<int> m_key_up;
glm::vec2 m_last_mouse = glm::vec2(0, 0);
glm::vec2 m_mouse_change = glm::vec2(0, 0);
glm::vec2 m_mouse_pos = glm::vec2(0, 0);
std::vector<HydraKeyPressStuct> m_key_presses;
std::queue<glm::vec2> m_mouse_moves;
bool m_mouse_reset = true;
friend class HydraEngine;
public:
void ProcessInput();
bool KeyPressed(HYDRA_KEY_CODES key);
glm::vec2 MouseChange() {return m_mouse_change;}
};
#endif /* HYDRAINPUTMANAGER */
+17
View File
@@ -0,0 +1,17 @@
#include "HydraObject.h"
#include "HydraEngine.h"
HydraEngine *const HydraObject::GetEngine()
{
return HydraEngine::GetInstance();
}
void HydraObject::DebugLog(std::string log_entry)
{
std::cout << log_entry + "\r\n";
}
void HydraObject::ClearLog()
{
std::cout << "\x1B[2J\x1B[H";
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef HYDRAOBJECT
#define HYDRAOBJECT
#include "../HydraDefines.h"
//#include "HydraEngine.h"
#include <string>
#include <iostream>
#include <assert.h>
class HydraEngine;
class CLASS_DEFINE HydraObject
{
private:
public:
class HydraEngine* const GetEngine();
void DebugLog(std::string log_entry);
void ClearLog();
};
#endif /* HYDRAOBJECT */
@@ -0,0 +1,296 @@
#include "HydraGLTFLoader.h"
#include "../actor/HydraActorManager.h"
#include "../actor/HydraActorManager.h"
#include "../actor/HydraGLTFActor.h"
#include "../engine/HydraEngine.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
#include "../ecs/components/HydraMaterialComponent.h"
#include "../mesh/HydraMesh.h"
#include "../mesh/HydraMeshManager.h"
#include "../mesh/StandardVertex.h"
#include "../buffer/HydraTextureBufferManager.h"
#include "../buffer/HydraMaterialBufferManager.h"
#include "../buffer/HydraMaterialBuffer.h"
HydraID HydraGLTFLoader::LoadGLTFFile(std::string filename)
{
HydraID actor_id = INVALID_HYDRA_ID;
HydraActorManager *actor_manager = GetEngine()->ActorManager();
actor_id = actor_manager->CreateActor<HydraGLTFActor>();
// Create an instance of the Importer class
Assimp::Importer importer;
// And have it read the given file with some example postprocessing
// Usually - if speed is not the most important aspect for you - you'll
// probably to request more postprocessing than we do in this example.
const aiScene *scene = importer.ReadFile(filename,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType |
aiProcess_FlipUVs);
std::vector<uint32_t> texture_lookup;
std::vector<uint32_t> material_lookup;
assert(scene != nullptr && "Failed to load file");
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent position_component = {};
ecs->AddComponent<HydraPositionComponent>(actor_id, position_component);
_ProcessGLTFTextures(scene, texture_lookup, actor_id);
_ProcessGLTFMaterials(scene, texture_lookup, material_lookup, filename);
HydraID root_id = _ProcessGLTFNode(scene, scene->mRootNode, material_lookup);
actor_manager->SetRelationship(actor_id, root_id);
return root_id;
}
HydraID HydraGLTFLoader::_ProcessGLTFNode(aiScene const *scene, aiNode *parent_node, std::vector<uint32_t> material_lookup)
{
HydraActorManager *actor_manager = GetEngine()->ActorManager();
HydraID parent_actor_id = actor_manager->CreateActor<HydraGLTFActor>();
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent position_component;
aiVector3D tmp_scaling = {};
aiQuaternion tmp_rotation = {};
aiVector3D tmp_position = {};
parent_node->mTransformation.Decompose(tmp_scaling, tmp_rotation, tmp_position);
glm::dvec3 scaling = glm::dvec3(tmp_scaling.x, tmp_scaling.y, tmp_scaling.z);
glm::quat rotation = glm::quat(tmp_rotation.w, tmp_rotation.x, tmp_rotation.y, tmp_rotation.z);
glm::dvec3 position = glm::dvec3(tmp_position.x, tmp_position.y, tmp_position.z);
glm::vec3 euler_angle = glm::eulerAngles(rotation);
ecs->AddComponent<HydraPositionComponent>(parent_actor_id, position_component);
actor_manager->SetScale(parent_actor_id, scaling);
actor_manager->SetPosition(parent_actor_id, position);
actor_manager->SetOrientation(parent_actor_id, euler_angle.x, euler_angle.y, euler_angle.z);
for (uint32_t i_mesh = 0; i_mesh < parent_node->mNumMeshes; i_mesh++)
{
aiMesh *mesh = scene->mMeshes[parent_node->mMeshes[i_mesh]];
_ProcessGLTFMesh(scene, parent_actor_id, mesh, material_lookup);
}
for (uint32_t i_node = 0; i_node < parent_node->mNumChildren; i_node++)
{
HydraID child_actor_id = _ProcessGLTFNode(scene, parent_node->mChildren[i_node], material_lookup);
actor_manager->SetRelationship(parent_actor_id, child_actor_id);
}
return parent_actor_id;
}
void HydraGLTFLoader::_ProcessGLTFMesh(aiScene const *scene, HydraID parent_actor_id, aiMesh *mesh, std::vector<uint32_t> material_lookup)
{
HydraActorManager *actor_manager = GetEngine()->ActorManager();
HydraID mesh_actor_id = actor_manager->CreateActor<HydraGLTFActor>();
aiMaterial *mat = scene->mMaterials[mesh->mMaterialIndex];
std::vector<StandardVertex> vertexes;
std::vector<uint32_t> indexes;
HydraECS *ecs = GetEngine()->ECS();
HydraPositionComponent position_component = {};
HydraMeshManager *mesh_manager = GetEngine()->MeshManager();
HydraID mesh_id = mesh_manager->CreateMesh();
ecs->AddComponent<HydraPositionComponent>(mesh_actor_id, position_component);
HydraID material_id = material_lookup[mesh->mMaterialIndex];
if(material_id != INVALID_HYDRA_ID)
{
HydraMaterialComponent mat_comp;
mat_comp.material_id = material_id;
ecs->AddComponent<HydraMaterialComponent>(mesh_actor_id, mat_comp);
}
HydraMesh *hydra_mesh = mesh_manager->GetMesh(mesh_id);
for (uint32_t i_face = 0; i_face < mesh->mNumFaces; i_face++)
{
aiFace face = mesh->mFaces[i_face];
for (uint32_t i_index = 0; i_index < face.mNumIndices; i_index++)
{
hydra_mesh->indexes.push_back(face.mIndices[i_index]);
}
}
for (uint32_t i_verts = 0; i_verts < mesh->mNumVertices; i_verts++)
{
StandardVertex vert = {};
if (mesh->HasPositions())
{
vert.position[0] = mesh->mVertices[i_verts].x;
vert.position[1] = mesh->mVertices[i_verts].y;
vert.position[2] = mesh->mVertices[i_verts].z;
}
if (mesh->HasNormals())
{
vert.normal[0] = mesh->mNormals[i_verts].x;
vert.normal[1] = mesh->mNormals[i_verts].y;
vert.normal[2] = mesh->mNormals[i_verts].z;
}
if(mesh->HasTangentsAndBitangents())
{
vert.bitanget[0] = mesh->mBitangents[i_verts].x;
vert.bitanget[1] = mesh->mBitangents[i_verts].y;
vert.bitanget[2] = mesh->mBitangents[i_verts].z;
vert.tangent[0] = mesh->mTangents[i_verts].x;
vert.tangent[1] = mesh->mTangents[i_verts].y;
vert.tangent[2] = mesh->mTangents[i_verts].z;
}
if (mesh->HasTextureCoords(0))
{
vert.text_coord0[0] = mesh->mTextureCoords[0][i_verts].x;
vert.text_coord0[1] = mesh->mTextureCoords[0][i_verts].y;
}
vert.chunk_id[0] = mesh_actor_id;
vert.chunk_id[1] = material_id;
hydra_mesh->vertexes.push_back(vert);
}
HydraMeshComponent mesh_comp;
mesh_comp.mesh_id = mesh_id;
mesh_comp.mesh_state = HYDRA_STATE::Waiting;
ecs->AddComponent<HydraMeshComponent>(mesh_actor_id, mesh_comp);
aiString mat_name;
mat->Get(AI_MATKEY_NAME, mat_name);
// Add renderable component
HydraRenderableComponent render_comp;
render_comp.renderable_types.set((uint32_t)HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR, true);
ecs->AddComponent<HydraRenderableComponent>(mesh_actor_id, render_comp);
actor_manager->SetRelationship(parent_actor_id, mesh_actor_id);
}
void HydraGLTFLoader::_ProcessGLTFMaterials(aiScene const *scene,
std::vector<uint32_t> &texture_lookup,
std::vector<uint32_t> &material_lookup,
std::string filename)
{
material_lookup.resize(scene->mNumMaterials);
HydraTextureBufferManager *texture_manager = GetEngine()->TextureBufferManager();
for (uint32_t i_mat = 0; i_mat < scene->mNumMaterials; i_mat++)
{
HydraMaterialBuffer material;
aiMaterial *mat = scene->mMaterials[i_mat];
aiColor3D color(0.f, 0.f, 0.f);
aiString name;
mat->Get(AI_MATKEY_COLOR_DIFFUSE, color);
std::string mat_name = filename + std::to_string(i_mat);
aiTexture diffuse_tex;
uint32_t diffuse_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_DIFFUSE);
uint32_t metal_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_METALNESS);
uint32_t metalrough_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_GLTF_METALLIC_ROUGHNESS);
uint32_t normal_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_NORMALS);
uint32_t rough_tex_count = mat->GetTextureCount(aiTextureType::aiTextureType_DIFFUSE_ROUGHNESS);
// have to do something here for multiple diffuse textures at some point.
aiString texture_path;
aiTextureMapping texture_mapping;
uint32_t uv_index;
if (diffuse_tex_count > 0)
{
mat->GetTexture(aiTextureType::aiTextureType_DIFFUSE, 0, &texture_path, &texture_mapping, &uv_index);
std::string path = std::string(texture_path.C_Str());
uint32_t texture_index = atoi(path.substr(1).c_str());
HydraID texture_id = texture_lookup[texture_index];
material.diffuse_texture_id = texture_id;
}
if(metalrough_tex_count > 0)
{
mat->GetTexture(aiTextureType::aiTextureType_GLTF_METALLIC_ROUGHNESS, 0, &texture_path, &texture_mapping, &uv_index);
std::string path = std::string(texture_path.C_Str());
uint32_t texture_index = atoi(path.substr(1).c_str());
HydraID texture_id = texture_lookup[texture_index];
material.metallic_rough_texture_id = texture_id;
}
if(normal_tex_count > 0)
{
mat->GetTexture(aiTextureType::aiTextureType_NORMALS, 0, &texture_path, &texture_mapping, &uv_index);
std::string path = std::string(texture_path.C_Str());
uint32_t texture_index = atoi(path.substr(1).c_str());
HydraID texture_id = texture_lookup[texture_index];
material.normal_texture_id = texture_id;
}
material.diffuse_colour[0] = color.r;
material.diffuse_colour[1] = color.g;
material.diffuse_colour[2] = color.b;
material.diffuse_colour[3] = 1.0f;
HydraID material_id = GetEngine()->MaterialBufferManager()->CreateMaterial(material);
material_lookup[i_mat] = material_id;
if (material_id == INVALID_HYDRA_ID)
{
throw std::runtime_error("Could not create material");
}
}
}
/// @brief Load all of the scene textures
/// @param scene containing scene
/// @param texture_lookup index of texture in the scene to the Hydra texture ID
void HydraGLTFLoader::_ProcessGLTFTextures(aiScene const *scene, std::vector<uint32_t> &texture_lookup, HydraID actor_id)
{
HydraTextureBufferManager *texture_manager = GetEngine()->TextureBufferManager();
// Make space for the texture lookups
texture_lookup.resize(scene->mNumTextures);
for (uint32_t i_tex = 0; i_tex < scene->mNumTextures; i_tex++)
{
std::string texture_name = std::to_string(actor_id) + "_" + std::to_string(i_tex);
aiTexture *tex = scene->mTextures[i_tex];
// Create a holder for the texture
int32_t width = 0;
int32_t height = 0;
int32_t channels = 0;
//stbi_set_flip_vertically_on_load(1);
stbi_uc* data = stbi_load_from_memory(reinterpret_cast<stbi_uc*>(tex->pcData), tex->mWidth, &width, &height, &channels, 4);
HydraID texture_id = texture_manager->CreateTexture(texture_name,
width,
height,
GL_RGBA8,
GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR,
GL_RGBA,
GL_UNSIGNED_BYTE,
5,
data);
texture_manager->BindTexture(texture_id);
// store the texture id against the scene index for the texture. Materials will have *n where n is the index
texture_lookup[i_tex] = texture_id;
}
}
@@ -0,0 +1,21 @@
#ifndef HYDRAGLTFLOADER
#define HYDRAGLTFLOADER
#include "../engine/HydraObject.h"
#include <string>
#include <assimp/Importer.hpp> // C++ importer interface
#include <assimp/scene.h> // Output data structure
#include <assimp/postprocess.h> // Post processing flags
class HydraGLTFLoader : public HydraObject
{
public:
HydraID LoadGLTFFile(std::string filename);
private:
void _ProcessGLTFTextures(aiScene const *scene, std::vector<uint32_t> &texture_lookup, HydraID actor_id);
void _ProcessGLTFMaterials(aiScene const *scene, std::vector<uint32_t>& texture_lookup, std::vector<uint32_t>& material_lookup, std::string filename);
HydraID _ProcessGLTFNode(aiScene const *scene, aiNode *parent_node, std::vector<uint32_t>material_lookup);
void _ProcessGLTFMesh(aiScene const *scene, HydraID parent_actor_id, aiMesh *mesh, std::vector<uint32_t>material_lookup);
};
#endif /* HYDRAGLTFLOADER */
@@ -0,0 +1,7 @@
#include "HydraGameProxy.h"
bool HydraGameProxy::Initialise()
{
return false;
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef HYDRAGAMEPROXY
#define HYDRAGAMEPROXY
#include "../engine/HydraObject.h"
class CLASS_DEFINE HydraGameProxy : public HydraObject
{
private:
public:
virtual bool Initialise() = 0;
virtual void Update(float delta_t_seconds) {};
};
#endif /* HYDRAGAMEPROXY */
+13
View File
@@ -0,0 +1,13 @@
#ifndef HYDRAMESH
#define HYDRAMESH
#include "../HydraDefines.h"
#include "StandardVertex.h"
struct HydraMesh
{
HydraID mesh_id = INVALID_HYDRA_ID;
std::vector<StandardVertex> vertexes;
std::vector<uint32_t> indexes;
};
#endif /* HYDRAMESH */
@@ -0,0 +1,106 @@
#include "HydraMeshManager.h"
#include <GLMIncludes.h>
void HydraMeshManager::Initialise()
{
m_meshes.resize(MAX_ACTORS);
for(uint32_t mesh_idx = 0; mesh_idx < MAX_ACTORS; mesh_idx++)
{
m_available_mesh_ids.push(mesh_idx);
}
}
void HydraMeshManager::Shutdown()
{
for(uint32_t mesh_idx = 0; mesh_idx < MAX_ACTORS; mesh_idx++)
{
if(m_meshes[mesh_idx].mesh_id != INVALID_HYDRA_ID)
{
DeleteMesh(m_meshes[mesh_idx].mesh_id);
}
}
m_meshes.clear();
}
HydraID HydraMeshManager::CreateMesh()
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_mesh_ids.size() > 0)
{
HydraID mesh_id = m_available_mesh_ids.front();
m_available_mesh_ids.pop();
m_meshes[mesh_id].mesh_id = mesh_id;
return mesh_id;
}
return INVALID_HYDRA_ID;
}
HydraMesh * const HydraMeshManager::GetMesh(HydraID mesh_id)
{
// TODO: insert return statement here
if(mesh_id < m_meshes.size())
{
return &m_meshes[mesh_id];
}
return nullptr;
}
void HydraMeshManager::DeleteMesh(HydraID mesh_id)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(mesh_id < m_meshes.size())
{
m_meshes[mesh_id].vertexes.clear();
m_meshes[mesh_id].mesh_id = INVALID_HYDRA_ID;
}
}
void HydraMeshManager::CalculateNormals(HydraID mesh_id)
{
HydraMesh mesh = m_meshes[mesh_id];
for (int i = 0; i < mesh.indexes.size(); i += 3)
{
uint32_t idx0 = mesh.indexes[i+0];
uint32_t idx1 = mesh.indexes[i+1];
uint32_t idx2 = mesh.indexes[i+2];
glm::vec3 vec0 = glm::normalize(glm::vec3(mesh.vertexes[idx0].position[0], mesh.vertexes[idx0].position[1], mesh.vertexes[idx0].position[2]));
glm::vec3 vec1 = glm::normalize(glm::vec3(mesh.vertexes[idx1].position[0], mesh.vertexes[idx1].position[1], mesh.vertexes[idx1].position[2]));
glm::vec3 vec2 = glm::normalize(glm::vec3(mesh.vertexes[idx2].position[0], mesh.vertexes[idx2].position[1], mesh.vertexes[idx2].position[2]));
glm::vec3 normal = glm::triangleNormal(vec0, vec1, vec2);
m_meshes[mesh_id].vertexes[idx0].normal[0] = normal[0];
m_meshes[mesh_id].vertexes[idx0].normal[1] = normal[1];
m_meshes[mesh_id].vertexes[idx0].normal[2] = normal[2];
m_meshes[mesh_id].vertexes[idx1].normal[0] = normal[0];
m_meshes[mesh_id].vertexes[idx1].normal[1] = normal[1];
m_meshes[mesh_id].vertexes[idx1].normal[2] = normal[2];
m_meshes[mesh_id].vertexes[idx2].normal[0] = normal[0];
m_meshes[mesh_id].vertexes[idx2].normal[1] = normal[1];
m_meshes[mesh_id].vertexes[idx2].normal[2] = normal[2];
// glm::vec3 vec0 = glm::vec3(mesh.vertexes[mesh.indexes[i]], mesh.vertexes[mesh.indexes[i] + 1], mesh.vertexes[mesh.indexes[i] + 2]);
// glm::vec3 vec1 = glm::vec3(Vertexes[Indexes[i+1]], Vertexes[Indexes[i+1] + 1], Vertexes[Indexes[i+1] + 2]);
// glm::vec3 vec2 = glm::vec3(Vertexes[Indexes[i+2]], Vertexes[Indexes[i+2] + 1], Vertexes[Indexes[i+2] + 2]);
// glm::vec3 normal = glm::triangleNormal(vec0, vec1, vec2);
// Normals[Indexes[i]] = normal.x;
// Normals[Indexes[i]+1] = normal.y;
// Normals[Indexes[i]+2] = normal.z;
// Normals[Indexes[i+1]] = normal.x;
// Normals[Indexes[i+1] + 1] = normal.y;
// Normals[Indexes[i+1] + 2] = normal.z;
// Normals[Indexes[i + 2]] = normal.x;
// Normals[Indexes[i + 2] + 1] = normal.y;
// Normals[Indexes[i + 2] + 2] = normal.z;
}
}
@@ -0,0 +1,25 @@
#ifndef HYDRAMESHMANAGER
#define HYDRAMESHMANAGER
#include "HydraMesh.h"
#include "../engine/HydraObject.h"
#include <queue>
#include <vector>
#include <mutex>
class HydraMeshManager : public HydraObject
{
public:
void Initialise();
void Shutdown();
HydraID CreateMesh();
HydraMesh* const GetMesh(HydraID mesh_id);
void DeleteMesh(HydraID mesh_id);
void CalculateNormals(HydraID mesh_id);
private:
std::mutex m_mutex;
std::vector<HydraMesh> m_meshes;
std::queue<HydraID> m_available_mesh_ids;
};
#endif /* HYDRAMESHMANAGER */
+15
View File
@@ -0,0 +1,15 @@
#ifndef STANDARDVERTEX
#define STANDARDVERTEX
#include <vector>
struct StandardVertex
{
float position[3];
float text_coord0[2];
uint32_t chunk_id[3];
float normal[3];
float bitanget[3];
float tangent[3];
};
#endif /* STANDARDVERTEX */
@@ -0,0 +1,270 @@
#include "HydraDeferredPipeline.h"
#include "HydraRenderStage.h"
#include "../engine/HydraEngine.h"
#include "../buffer/HydraBufferManager.h"
#include "../buffer/HydraTextureBufferManager.h"
#include "../buffer/HydraLightBufferManager.h"
#include "PerFrameUBO.hpp"
#include "../camera/HydraCamera.h"
#include "../renderer/HydraRenderer.h"
#include "../ecs/HydraECS.h"
#include "../ecs/systems/HydraRenderSystem.h"
#include "../mesh/StandardVertex.h"
#include "../actor/HydraActorManager.h"
#include "../actor/HydraOutputActor.h"
void HydraDeferredPipeline::Initialise()
{
_CreateUBOs();
//already on the render thread so dont neet another job
_CreateOutputActor();
_CreateFrameBuffer();
_CreateColourRenderStage();
_CreateOutputRenderStage();
}
void HydraDeferredPipeline::Shutdown()
{
for(uint32_t rs_idx =0; rs_idx <m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->ShutDown();
delete m_render_stages[rs_idx];
}
glDeleteFramebuffers(1, &m_frame_buffer_id);
}
void HydraDeferredPipeline::Render()
{
_UpdateUBO();
glBindFramebuffer(GL_FRAMEBUFFER, m_frame_buffer_id);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // we're not using the stencil buffer now
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
HydraECS* ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
GetEngine()->Renderer()->BeginFrame();
for(uint32_t rs_idx = 0; rs_idx <m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->Render(render_system->Entities);
}
GetEngine()->Renderer()->EndFrame();
}
void HydraDeferredPipeline::_UpdateUBO()
{
HydraCamera* camera = GetEngine()->Camera();
PerFrameUBO ubo = {};
uint32_t light_count = GetEngine()->GetLightCount();
ubo.view = camera->GetView();
ubo.proj = camera->GetProjection();
ubo.viewer_pos = camera->GetPosition();
ubo.light_count = light_count;
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
buffer_manager->UpdateWholeBuffer(m_per_frame_ubo, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, m_per_frame_ubo);
PerFrameUBO output_ubo = {};
output_ubo.view = glm::mat4(1);
output_ubo.proj = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f);
output_ubo.viewer_pos = camera->GetPosition();
output_ubo.light_count = light_count;
buffer_manager->UpdateWholeBuffer(m_per_frame_output_ubo, &output_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, m_per_frame_output_ubo);
}
void HydraDeferredPipeline::_CreateFrameBuffer()
{
HydraEngine* engine = GetEngine();
HydraTextureBufferManager* tex_buffer_manager = engine->TextureBufferManager();
HydraRenderSettings render_settings = engine->RenderSettings();
glGenFramebuffers(1, &m_frame_buffer_id);
glBindFramebuffer(GL_FRAMEBUFFER, m_frame_buffer_id);
HydraOutputActor* actor = static_cast<HydraOutputActor*>(GetEngine()->ActorManager()->GetActor(m_output_actor_id));
HydraTextureBuffer depth_texture = tex_buffer_manager->GetTexture(actor->texture_buffers[0]);
HydraTextureBuffer buffer_0_texture = tex_buffer_manager->GetTexture(actor->texture_buffers[1]);
HydraTextureBuffer metal_rough_texture = tex_buffer_manager->GetTexture(actor->texture_buffers[2]);
HydraTextureBuffer normal_texture = tex_buffer_manager->GetTexture(actor->texture_buffers[3]);
HydraTextureBuffer position_texture = tex_buffer_manager->GetTexture(actor->texture_buffers[4]);
glBindTexture(GL_TEXTURE_2D, buffer_0_texture.gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer_0_texture.gl_tex_id, 0);
glBindTexture(GL_TEXTURE_2D, metal_rough_texture.gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, metal_rough_texture.gl_tex_id, 0);
glBindTexture(GL_TEXTURE_2D, normal_texture.gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normal_texture.gl_tex_id, 0);
glBindTexture(GL_TEXTURE_2D, position_texture.gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, position_texture.gl_tex_id, 0);
glBindTexture(GL_TEXTURE_2D, depth_texture.gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture.gl_tex_id, 0);
GLenum draw_buffers[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffers(4, draw_buffers);
glBindTexture(GL_TEXTURE_2D, 0);
tex_buffer_manager->BindTexture(depth_texture.texture_id);
tex_buffer_manager->BindTexture(buffer_0_texture.texture_id);
tex_buffer_manager->BindTexture(metal_rough_texture.texture_id);
tex_buffer_manager->BindTexture(normal_texture.texture_id);
tex_buffer_manager->BindTexture(position_texture.texture_id);
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
buffer_manager->UpdateWholeBuffer(m_output_texture_ubo, &actor->texture_buffers[0]);
glBindBuffer(GL_UNIFORM_BUFFER, m_output_texture_ubo);
}
void HydraDeferredPipeline::_CreateColourRenderStage()
{
HydraRenderStage* render_stage = new HydraRenderStage();
std::string shader_path = std::string(shader_base);
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
HydraID pos_buffer_id = buffer_manager->FindBuffer("PositionsBuffer");
HydraID mat_buffer_id = buffer_manager->FindBuffer("MaterialBuffer");
HydraID tex_buffer_id = buffer_manager->FindBuffer("TextureBuffer");
HydraID per_frame_buffer_id = buffer_manager->FindBuffer("DeferredPerFrameUBO");
HydraShaderBinding shader_binding = {};
shader_binding.block_name.push_back("PositionsBuffer");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(pos_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("MaterialBuffer");
shader_binding.binding_point.push_back(2);
shader_binding.buffer_id.push_back(mat_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("TextureBuffer");
shader_binding.binding_point.push_back(3);
shader_binding.buffer_id.push_back(tex_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("uniform_per_frame");
shader_binding.binding_point.push_back(0);
shader_binding.buffer_id.push_back(per_frame_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
std::vector<uint32_t> textures;
render_stage->Initialise(shader_path + "deferred_shader.vert",
shader_path + "deferred_shader.frag",
shader_binding,
m_frame_buffer_id,
textures,
true,
HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
m_render_stages.push_back(render_stage);
}
void HydraDeferredPipeline::_CreateOutputRenderStage()
{
HydraRenderStage* render_stage = new HydraRenderStage();
std::string shader_path = std::string(shader_base);
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
std::vector<uint32_t> textures;
GetEngine()->ActorManager()->InitialiseActor(m_output_actor_id);
HydraOutputActor* actor = static_cast<HydraOutputActor*>(GetEngine()->ActorManager()->GetActor(m_output_actor_id));
HydraTextureBufferManager* tex_buf_manager = GetEngine()->TextureBufferManager();
HydraID pos_buffer_id = buffer_manager->FindBuffer("PositionsBuffer");
HydraID per_frame_buffer_id = buffer_manager->FindBuffer("DeferredOutputPerFrameUBO");
HydraID tex_buffer_id = buffer_manager->FindBuffer("TextureBuffer");
HydraID output_texture_buffer_id = buffer_manager->FindBuffer("DeferredOutputTextureUBO");
HydraID light_buffer_id = buffer_manager->FindBuffer("LightBuffer");
HydraShaderBinding shader_binding = {};
shader_binding.block_name.push_back("PositionsBuffer");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(pos_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("TextureBuffer");
shader_binding.binding_point.push_back(3);
shader_binding.buffer_id.push_back(tex_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("uniform_per_frame");
shader_binding.binding_point.push_back(0);
shader_binding.buffer_id.push_back(per_frame_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
shader_binding.block_name.push_back("uniform_output_textures");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(output_texture_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
shader_binding.block_name.push_back("LightBuffer");
shader_binding.binding_point.push_back(4);
shader_binding.buffer_id.push_back(light_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
render_stage->Initialise(shader_path + "deferred_output_shader.vert",
shader_path + "deferred_output_shader.frag",
shader_binding,
0,
textures,
false,
HYDRA_RENDERABLE_TYPE::HYDRA_OUTPUT);
m_render_stages.push_back(render_stage);
}
void HydraDeferredPipeline::_CreateOutputActor()
{
m_output_actor_id = GetEngine()->ActorManager()->CreateActor<HydraOutputActor>();
GetEngine()->ActorManager()->InitialiseActor(m_output_actor_id);
HydraOutputActor* actor = static_cast<HydraOutputActor*>(GetEngine()->ActorManager()->GetActor(m_output_actor_id));
}
void HydraDeferredPipeline::_CreateUBOs()
{
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
m_per_frame_ubo = buffer_manager->CreateGPUBuffer("DeferredPerFrameUBO",
sizeof(PerFrameUBO), 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
m_per_frame_output_ubo = buffer_manager->CreateGPUBuffer("DeferredOutputPerFrameUBO",
sizeof(PerFrameUBO), 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
m_output_texture_ubo = buffer_manager->CreateGPUBuffer("DeferredOutputTextureUBO",
sizeof(uint32_t)*16, 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
}
@@ -0,0 +1,41 @@
#ifndef HYDRADEFERREDPIPELINE
#define HYDRADEFERREDPIPELINE
#include "../engine/HydraObject.h"
#include "../windowmanager/HydraRenderSettings.h"
#include "HydraPipeline.h"
#include "HydraRenderStage.h"
#include <vector>
class HydraRenderStage;
class HydraDeferredPipeline : public HydraPipeline
{
public:
virtual void Initialise() override;
virtual void Shutdown() override;
virtual void Render() override;
private:
HydraID m_per_frame_ubo = INVALID_HYDRA_ID;
HydraID m_per_frame_output_ubo = INVALID_HYDRA_ID;
HydraID m_material_buffer = INVALID_HYDRA_ID;
HydraID m_buffer_0 = INVALID_HYDRA_ID; //Frame buffer 0;
HydraID m_depth = INVALID_HYDRA_ID;
HydraID m_output_actor_id = INVALID_HYDRA_ID;
HydraID m_output_texture_ubo = INVALID_HYDRA_ID;
HydraID m_output_light_ubo = INVALID_HYDRA_ID;
uint32_t m_frame_buffer_id;
void _UpdateUBO();
void _CreateFrameBuffer();
void _CreateColourRenderStage();
void _CreateOutputRenderStage();
void _CreateOutputActor();
void _CreateUBOs();
};
#endif /* HYDRADEFERREDPIPELINE */
@@ -0,0 +1,101 @@
#include "HydraForwardPipeline.h"
#include "HydraRenderStage.h"
#include "../engine/HydraEngine.h"
#include "../buffer/HydraBufferManager.h"
#include "PerFrameUBO.hpp"
#include "../camera/HydraCamera.h"
#include "../renderer/HydraRenderer.h"
#include "../ecs/HydraECS.h"
#include "../ecs/systems/HydraRenderSystem.h"
#include "../mesh/StandardVertex.h"
void HydraForwardPipeline::Initialise()
{
_EnableVertexAttributes();
HydraRenderStage* render_stage = new HydraRenderStage();
std::string shader_path = std::string(shader_base);
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
HydraID pos_buffer_id = buffer_manager->FindBuffer("PositionsBuffer");
HydraID mat_buffer_id = buffer_manager->FindBuffer("MaterialBuffer");
HydraID tex_buffer_id = buffer_manager->FindBuffer("TextureBuffer");
HydraShaderBinding shader_binding = {};
shader_binding.block_name.push_back("PositionsBuffer");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(pos_buffer_id);
shader_binding.block_name.push_back("MaterialBuffer");
shader_binding.binding_point.push_back(2);
shader_binding.buffer_id.push_back(mat_buffer_id);
shader_binding.block_name.push_back("TextureBuffer");
shader_binding.binding_point.push_back(3);
shader_binding.buffer_id.push_back(tex_buffer_id);
std::vector<uint32_t> textures;
std::vector<uint32_t> rb_attachments;
render_stage->Initialise(shader_path + "forward_shader.vert", shader_path + "forward_shader.frag", shader_binding, 0, textures, true, HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
m_render_stages.push_back(render_stage);
m_per_frame_ubo = buffer_manager->CreateGPUBuffer("PerFrameUBO",
sizeof(PerFrameUBO), 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
}
void HydraForwardPipeline::Shutdown()
{
for(uint32_t rs_idx =0; rs_idx <m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->ShutDown();
delete m_render_stages[rs_idx];
}
}
void HydraForwardPipeline::Render()
{
_UpdateUBO();
HydraECS* ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
GetEngine()->Renderer()->BeginFrame();
for(uint32_t rs_idx = 0; rs_idx <m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->Render(render_system->Entities);
}
GetEngine()->Renderer()->EndFrame();
}
void HydraForwardPipeline::_UpdateUBO()
{
HydraCamera* camera = GetEngine()->Camera();
PerFrameUBO ubo = {};
ubo.view = camera->GetView();
ubo.proj = camera->GetProjection();
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
buffer_manager->UpdateWholeBuffer(m_per_frame_ubo, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, m_per_frame_ubo);
}
void HydraForwardPipeline::_EnableVertexAttributes()
{
//already on the render thread so dont neet another job
// position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)0);
glEnableVertexAttribArray(0);
// texcoord01
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(StandardVertex), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// chunkID
glVertexAttribIPointer(2, 3, GL_UNSIGNED_INT, sizeof(StandardVertex), (void *)(5 * sizeof(float)));
glEnableVertexAttribArray(2);
}
@@ -0,0 +1,28 @@
#ifndef HYDRAFORWARDPIPELINE
#define HYDRAFORWARDPIPELINE
#include "../engine/HydraObject.h"
#include "../windowmanager/HydraRenderSettings.h"
#include "HydraPipeline.h"
#include "HydraRenderStage.h"
#include <vector>
class HydraRenderStage;
class HydraForwardPipeline : public HydraPipeline
{
public:
virtual void Initialise() override;
virtual void Shutdown() override;
virtual void Render() override;
private:
HydraID m_per_frame_ubo = INVALID_HYDRA_ID;
HydraID m_texture_buffer = INVALID_HYDRA_ID;
HydraID m_material_buffer = INVALID_HYDRA_ID;
void _UpdateUBO();
void _EnableVertexAttributes();
};
#endif /* HYDRAFORWARDPIPELINE */
@@ -0,0 +1,14 @@
#ifndef HYDRAFRAMEBUFFER
#define HYDRAFRAMEBUFFER
#include "../engine/HydraObject.h"
#include "../buffer/HydraTexureBuffer.h"
#include <vector>
struct HydraFrameBuffer
{
std::vector<HydraID> colour_attachements;
HydraID depth_attachment;
};
#endif /* HYDRAFRAMEBUFFER */
@@ -0,0 +1,20 @@
#ifndef HYDRAPIPELINE
#define HYDRAPIPELINE
#include "../engine/HydraObject.h"
#include "../windowmanager/HydraRenderSettings.h"
#include <vector>
class HydraRenderStage;
class HydraPipeline : public HydraObject
{
public:
virtual void Initialise() = 0;
virtual void Shutdown() = 0;
virtual void Render() = 0;
protected:
std::vector<HydraRenderStage*> m_render_stages;
};
#endif /* HYDRAPIPELINE */
@@ -0,0 +1,163 @@
#include "HydraRenderStage.h"
#include "../ecs/HydraECS.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
#include "../engine/HydraEngine.h"
#include "../buffer/HydraVertexBufferManager.h"
#include "../buffer/HydraBufferManager.h"
#include <set>
#include <fstream>
#include <sstream>
#include <iostream>
#include <GLMIncludes.h>
void HydraRenderStage::Initialise(std::string vertex_shader_file,
std::string fragment_shader_file,
HydraShaderBinding shader_binding,
uint32_t framebuffer_id,
std::vector<uint32_t> textures,
bool enable_culling,
HYDRA_RENDERABLE_TYPE renderable_type)
{
m_framebuffer_id = framebuffer_id;
m_renderable_type = static_cast<uint32_t>(renderable_type);
m_shader_binding = shader_binding;
m_textures = textures;
m_cull = enable_culling;
if(vertex_shader_file.length() > 0)
{
m_vertex_shader = _LoadShader(vertex_shader_file, GL_VERTEX_SHADER);
}
if(fragment_shader_file.length() > 0)
{
m_fragment_shader = _LoadShader(fragment_shader_file, GL_FRAGMENT_SHADER);
}
m_program = glCreateProgram();
glAttachShader(m_program, m_vertex_shader);
glAttachShader(m_program, m_fragment_shader);
glLinkProgram(m_program);
}
void HydraRenderStage::ShutDown()
{
glDeleteShader(m_vertex_shader);
glDeleteShader(m_fragment_shader);
glDeleteProgram(m_program);
}
void HydraRenderStage::Render(std::set<HydraID>& entities)
{
HydraECS* ecs = GetEngine()->ECS();
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer_id);
//glDrawBuffers(m_rb_attachments.size(), &m_rb_attachments[0]);
HydraVertexBufferManager* vert_buffer_mananger = GetEngine()->VertexBufferManager();
glUseProgram(m_program);
_BindBuffers();
_BindTextures();
HydraSignature signature = {};
signature.set(m_renderable_type, true);
if(m_cull)
{
glEnable(GL_CULL_FACE);
}
else
{
glDisable(GL_CULL_FACE);
}
for(const auto& entity_id : entities )
{
HydraRenderableComponent render_comp = ecs->GetComponent<HydraRenderableComponent>(entity_id);
if((render_comp.renderable_types & signature) == signature)
{
HydraMeshComponent mesh_comp = ecs->GetComponent<HydraMeshComponent>(entity_id);
HydraVertexBuffer& vertex_buffer = vert_buffer_mananger->GetVertexBuffer(mesh_comp.vertex_buffer_id);
glBindVertexArray(vertex_buffer.vao);
glDrawElements(GL_TRIANGLES, vertex_buffer.triangle_count, GL_UNSIGNED_INT, (void*)0 );
glBindVertexArray(0);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
uint32_t HydraRenderStage::_LoadShader(std::string filename, uint32_t shader_type)
{
std::string shader_source = _LoadShaderSource(filename);
const char* src = shader_source.c_str();
GLuint shader = glCreateShader(shader_type);
int length = shader_source.length();
int success;
char infoLog[512];
glShaderSource(shader, 1, &src, &length);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
};
return shader;
}
std::string HydraRenderStage::_LoadShaderSource(std::string filename)
{
std::ifstream file(filename);
if (!file.is_open()) {
std::cerr << "Failed to open shader file: " << filename << std::endl;
return "";
}
std::stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
void HydraRenderStage::_BindBuffers()
{
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
for(uint32_t bind_idx = 0; bind_idx <m_shader_binding.block_name.size(); bind_idx++)
{
HydraBuffer buffer = buffer_manager->GetBuffer(m_shader_binding.buffer_id[bind_idx]);
switch(m_shader_binding.buffer_type[bind_idx])
{
case HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER:
{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, m_shader_binding.binding_point[bind_idx], buffer.gpu_buffer_id);
break;
}
case HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER:
{
glBindBufferBase(GL_UNIFORM_BUFFER, m_shader_binding.binding_point[bind_idx], buffer.gpu_buffer_id);
break;
}
}
}
}
void HydraRenderStage::_BindTextures()
{
uint32_t active_texture = 0;
for(auto texture:m_textures)
{
glBindTexture(GL_TEXTURE_2D, texture);
glActiveTexture(GL_TEXTURE0 + active_texture);
glBindTexture(GL_TEXTURE_2D, 0);
active_texture++;
}
}
@@ -0,0 +1,38 @@
#ifndef HYDRARENDERSTAGE
#define HYDRARENDERSTAGE
#include "../engine/HydraObject.h"
#include "../windowmanager/HydraRenderSettings.h"
#include "HydraShaderBinding.hpp"
#include "../GlewIncludes.h"
#include <vector>
#include <set>
class HydraRenderStage : public HydraObject
{
public:
void Initialise(std::string vertex_shader_file,
std::string fragment_shader_file,
HydraShaderBinding shader_binding,
uint32_t framebuffer_id,
std::vector<uint32_t> textures,
bool enable_culling,
HYDRA_RENDERABLE_TYPE renderable_type);
void ShutDown();
void Render(std::set<HydraID>& entities);
private:
uint32_t _LoadShader(std::string filename, uint32_t shader_type);
std::string _LoadShaderSource(std::string filename);
void _BindBuffers();
void _BindTextures();
HydraShaderBinding m_shader_binding;
uint32_t m_vertex_shader = GL_INVALID_VALUE;
uint32_t m_fragment_shader = GL_INVALID_VALUE;
uint32_t m_program = GL_INVALID_VALUE;
uint32_t m_renderable_type;
uint32_t m_framebuffer_id = 0;
bool m_cull = false;
std::vector<uint32_t> m_textures;
};
#endif /* HYDRARENDERSTAGE */
@@ -0,0 +1,13 @@
#ifndef HYDRASHADERBINDING
#define HYDRASHADERBINDING
#include <string>
#include <vector>
struct HydraShaderBinding
{
std::vector<HYDRA_BUFFER_TYPE> buffer_type;
std::vector<std::string> block_name;
std::vector<uint32_t> binding_point;
std::vector<uint32_t> buffer_id;
};
#endif /* HYDRASHADERBINDING */
@@ -0,0 +1,13 @@
#ifndef PERFRAMEUBO
#define PERFRAMEUBO
#include <GLMIncludes.h>
struct PerFrameUBO
{
glm::mat4 view;
glm::mat4 proj;
glm::vec3 viewer_pos = {0,0,0};
uint32_t light_count = 0;
};
#endif /* PERFRAMEUBO */
@@ -0,0 +1,52 @@
#include "HydraRenderer.h"
#include "../GlewIncludes.h"
#include "../windowmanager/HydraWindowManager.h"
#include "../engine/HydraEngine.h"
#include <GLMIncludes.h>
void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
{
std::cout << "[OpenGL Error](" << type << ") " << message << std::endl;
}
void HydraRenderer::Initialise(HydraRenderSettings render_settings)
{
m_render_settings = render_settings;
glewExperimental = GL_TRUE;
GLenum res = glewInit();
if (res != GLEW_OK)
{
}
else
{
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_DEBUG_OUTPUT);
glfwSwapInterval(1);
glDebugMessageCallback(MessageCallback, 0);
}
}
void HydraRenderer::BeginFrame()
{
glViewport(0, 0, m_render_settings.ViewportWidth, m_render_settings.ViewportHeight);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f, 0.5f, 0.7f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void HydraRenderer::EndFrame()
{
HydraWindowManager* window_manager = GetEngine()->WindowManager();
window_manager->Swap();
}
@@ -0,0 +1,20 @@
#ifndef HYDRARENDERER
#define HYDRARENDERER
#include "../engine/HydraObject.h"
#include "../windowmanager/HydraRenderSettings.h"
class HydraRenderer : public HydraObject
{
public:
void Initialise(HydraRenderSettings render_settings);
void BeginFrame();
void EndFrame();
private:
HydraRenderSettings m_render_settings = {};
};
#endif /* HYDRARENDERER */
@@ -0,0 +1,22 @@
#ifndef HYDRATASKBARRIER
#define HYDRATASKBARRIER
#include "../engine/HydraObject.h"
#include <vector>
#include <mutex>
#include <thread>
class CLASS_DEFINE HydraTaskBarrier : public HydraObject
{
private:
protected:
public:
int reference_count = 0;
HydraID barrier_id = INVALID_HYDRA_ID;
std::vector<HydraID> task_ids;
bool waiting = false;
};
#endif /* HYDRATASKBARRIER */
@@ -0,0 +1,475 @@
#include "HydraTaskScheduler.h"
#include "HydraThread.h"
#include "../task/HydraTask.h"
void HydraTaskScheduler::Initialise(int thread_count)
{
std::lock_guard<std::mutex> lock(m_mutex);
HydraID id = 0;
for (int i = 0; i < MAX_TASKS; i++)
{
m_available_barrier_ids.push(id);
id++;
}
m_barriers.resize(MAX_TASKS);
for (int i = 0; i < thread_count; i++)
{
HydraThread *pthread = new HydraThread();
pthread->ThreadName = "THREAD_" + std::to_string(i);
m_general_thread.push_back(pthread);
}
HydraThread *render_thread = new HydraThread();
render_thread->ThreadName = "RENDER";
render_thread->ThreadAffinity = HydraThreadAffinity::Render;
m_general_thread.push_back(render_thread);
HydraThread *physics_thread = new HydraThread();
physics_thread->ThreadName = "PHYSICS";
physics_thread->ThreadAffinity = HydraThreadAffinity::Physics;
m_general_thread.push_back(physics_thread);
HydraThread *main_thread = new HydraThread();
main_thread->ThreadAffinity = HydraThreadAffinity::General;
main_thread->ThreadID = std::this_thread::get_id();
main_thread->ThreadName = "MAIN";
m_general_thread.push_back(main_thread);
m_tasks.resize(MAX_TASKS);
m_task_ids_waiting_for_children.resize(MAX_TASKS);
for (size_t i = 0; i < MAX_TASKS; i++)
{
m_avaialble_task_ids.push_back(i);
}
render_thread->Start();
physics_thread->Start();
for (int i = 0; i < thread_count; i++)
{
m_general_thread[i]->Start();
}
}
void HydraTaskScheduler::Shutdown()
{
std::lock_guard<std::mutex> lock(m_mutex);
for (int i = 0; i < m_general_thread.size(); i++)
{
m_general_thread[i]->Stop();
}
}
HydraID HydraTaskScheduler::_SaveTask(HydraTask *task)
{
if (m_avaialble_task_ids.size() > 0)
{
HydraID id = m_avaialble_task_ids.front();
m_avaialble_task_ids.pop_front();
if(id > m_tasks.size())
{
DebugLog("INVALID TASK");
}
task->m_taskID = id;
m_tasks[id] = task;
return id;
}
else
{
DebugLog("Create Task Fail");
}
return INVALID_HYDRA_ID;
}
void HydraTaskScheduler::_DeleteTask(HydraID taskID)
{
if ((taskID <= MAX_TASKS) && (taskID != INVALID_HYDRA_ID))
{
if (m_tasks[taskID]->m_notifyThread)
{
_NotifyThread(m_tasks[taskID]->m_notifyID);
}
delete m_tasks[taskID];
m_tasks[taskID] = nullptr;
m_avaialble_task_ids.push_back(taskID);
}
}
void HydraTaskScheduler::ProcessTask()
{
HydraThread *thread = nullptr;
for (int i = 0; i < m_general_thread.size(); i++)
{
if (m_general_thread[i]->ThreadID == std::this_thread::get_id())
{
thread = m_general_thread[i];
break;
}
}
if (thread != nullptr)
{
HydraID taskID = INVALID_HYDRA_ID;
{
std::lock_guard<std::mutex> lock(m_mutex);
taskID = _GetTaskReadyToRun(thread->ThreadAffinity);
}
if (taskID != INVALID_HYDRA_ID)
{
HydraTask *task = GetTask(taskID);
if (task != nullptr)
{
task->_RunTask();
}
}
}
}
void HydraTaskScheduler::_NotifyThread(std::thread::id thread_id)
{
HydraThread *thread = nullptr;
for (int i = 0; i < m_general_thread.size(); i++)
{
if (m_general_thread[i]->ThreadID == thread_id)
{
thread = m_general_thread[i];
break;
}
}
thread->WaitCondition.notify_one();
}
HydraTask *const HydraTaskScheduler::_GetTask(HydraID taskID)
{
if (taskID <= MAX_TASKS)
{
if (m_tasks[taskID] != nullptr)
{
return m_tasks[taskID];
}
}
return nullptr;
}
HydraTask *const HydraTaskScheduler::GetTask(HydraID taskID)
{
return _GetTask(taskID);
}
void HydraTaskScheduler::StartTask(HydraID taskID)
{
std::lock_guard<std::mutex> lock(m_mutex);
_StartTask(taskID);
}
void HydraTaskScheduler::_StartTask(HydraID taskID, bool notifyThread)
{
if ((taskID <= MAX_TASKS) && (taskID != INVALID_HYDRA_ID))
{
HydraTask *task = m_tasks[taskID];
task->m_notifyThread = true;
task->m_notifyID = std::this_thread::get_id();
if (task != nullptr)
{
if (task->ThreadAffinity == HydraThreadAffinity::General)
{
m_general_tasks_ready_to_run.push_back(taskID);
}
else if (task->ThreadAffinity == HydraThreadAffinity::Render)
{
m_render_tasks_ready_to_run.push_back(taskID);
}
else if (task->ThreadAffinity == HydraThreadAffinity::Physics)
{
m_physics_tasks_ready_to_run.push_back(taskID);
}
}
}
}
/// @brief Tell the task scheduler that the thread is about to start processing. This allows the task to perform any setup if required.
/// @param taskID
void HydraTaskScheduler::NotifyStart(HydraID taskID)
{
std::lock_guard<std::mutex> lock(m_mutex);
}
void HydraTaskScheduler::NotifyComplete(HydraID taskID)
{
m_mutex.lock();
if (taskID != INVALID_HYDRA_ID)
{
if (taskID < MAX_TASKS)
{
if (m_tasks[taskID] != nullptr)
{
HydraTask *task = m_tasks[taskID];
if (task->m_child_tasks != 0)
{
m_task_ids_waiting_for_children[taskID] = taskID;
m_mutex.unlock();
return;
}
else
{
m_mutex.unlock();
task->Complete();
m_mutex.lock();
}
HydraID parentTaskID = task->m_dependant_task;
if (task->m_barrierID != INVALID_HYDRA_ID)
{
_DecrementBarrier(task->m_taskID, task->m_barrierID);
}
_DeleteTask(taskID);
if (parentTaskID != INVALID_HYDRA_ID)
{
_UpdateDependantTaskComplete(parentTaskID);
}
}
}
}
m_mutex.unlock();
}
void HydraTaskScheduler::_UpdateDependantTaskComplete(HydraID taskID)
{
if ((taskID <= MAX_TASKS) && (taskID != INVALID_HYDRA_ID))
{
if (m_tasks[taskID] != nullptr)
{
m_tasks[taskID]->m_child_tasks--;
if (m_tasks[taskID]->m_child_tasks == 0)
{
m_tasks[taskID]->Notify();
if (m_tasks[taskID]->m_dependant_task != INVALID_HYDRA_ID)
{
_UpdateDependantTaskComplete(m_tasks[taskID]->m_dependant_task);
}
m_task_ids_waiting_for_children[taskID] = INVALID_HYDRA_ID;
if (m_tasks[taskID]->m_barrierID != INVALID_HYDRA_ID)
{
_DecrementBarrier(m_tasks[taskID]->m_taskID, m_tasks[taskID]->m_barrierID);
}
_DeleteTask(taskID);
}
}
}
}
HydraID HydraTaskScheduler::_GetRenderTaskReadyToRun()
{
if (m_render_tasks_ready_to_run.size() > 0)
{
HydraID taskID = m_render_tasks_ready_to_run.front();
m_render_tasks_ready_to_run.pop_front();
return taskID;
}
return INVALID_HYDRA_ID;
}
HydraID HydraTaskScheduler::_GetPhysicsTaskReadyToRun()
{
if (m_physics_tasks_ready_to_run.size() > 0)
{
HydraID taskID = m_physics_tasks_ready_to_run.front();
m_physics_tasks_ready_to_run.pop_front();
return taskID;
}
return INVALID_HYDRA_ID;
}
HydraID HydraTaskScheduler::_GetTaskReadyToRun(HydraThreadAffinity thread_affinity)
{
HydraID taskID = INVALID_HYDRA_ID;
if (thread_affinity == HydraThreadAffinity::Render)
{
if (m_render_tasks_ready_to_run.size() > 0)
{
taskID = m_render_tasks_ready_to_run.front();
m_render_tasks_ready_to_run.pop_front();
}
}
else if (thread_affinity == HydraThreadAffinity::Physics)
{
if (m_physics_tasks_ready_to_run.size() > 0)
{
taskID = m_physics_tasks_ready_to_run.front();
m_physics_tasks_ready_to_run.pop_front();
}
}
else
{
if (taskID == INVALID_HYDRA_ID)
{
if (m_general_tasks_ready_to_run.size() > 0)
{
taskID = m_general_tasks_ready_to_run.front();
m_general_tasks_ready_to_run.pop_front();
}
}
}
return taskID;
}
/* @brief The calling thread will execute the specified task and will not
return until the
@param taskID*/
void HydraTaskScheduler::WaitForTask(HydraID taskID)
{
HydraTask *task = nullptr;
{
std::lock_guard<std::mutex> lock(m_mutex);
task = GetTask(taskID);
if (task->m_barrierID == INVALID_HYDRA_ID)
{
HydraID barrierID = _CreateBarrier();
_AddTaskToBarrier(taskID, barrierID);
}
_StartTask(taskID);
}
//HydraTask *task = GetTask(taskID);
if(task != nullptr)
{
WaitForBarrier(task->m_barrierID);
}
else
{
DebugLog("Invlalid Task");
}
}
HydraID HydraTaskScheduler::_CreateBarrier()
{
if (m_available_barrier_ids.size() > 0)
{
HydraID id = m_available_barrier_ids.front();
m_available_barrier_ids.pop();
m_barriers[id] = new HydraTaskBarrier();
m_barriers[id]->barrier_id = id;
m_barriers[id]->reference_count = 0;
m_barriers[id]->task_ids.clear();
m_barriers[id]->waiting = false;
return id;
}
else
{
DebugLog("Barrier Fail");
}
return INVALID_HYDRA_ID;
}
HydraID HydraTaskScheduler::CreateBarrier()
{
return _CreateBarrier();
}
/// @brief Include the task identified by taskID in the barrier identified by barrierID
/// @param taskID
/// @param barrierID
void HydraTaskScheduler::_AddTaskToBarrier(HydraID taskID, HydraID barrierID)
{
if ((barrierID < m_barriers.size()) && (taskID < m_tasks.size()))
{
if (m_barriers[barrierID]->waiting)
{
DebugLog("Barrier already locked");
}
else
{
m_barriers[barrierID]->task_ids.push_back(barrierID);
m_barriers[barrierID]->reference_count++;
HydraTask *task = _GetTask(taskID);
task->m_barrierID = barrierID;
}
}
}
/// @brief Include the task identified by taskID in the barrier identified by barrierID
/// @param taskID
/// @param barrierID
void HydraTaskScheduler::AddTaskToBarrier(HydraID taskID, HydraID barrierID)
{
std::lock_guard<std::mutex> lock(m_mutex);
_AddTaskToBarrier(taskID, barrierID);
}
/// @brief The calling thread will not return from this method until all of the tasks in the barrier are complete.
/// @brief The thread will continue to process tasks from the task pool
/// @param barrierID
void HydraTaskScheduler::WaitForBarrier(HydraID barrierID)
{
if (barrierID < m_barriers.size())
{
if(m_barriers[barrierID] != nullptr)
{
bool quit = false;
while (!quit)
{
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_barriers[barrierID] == nullptr)
{
return;
}
if(m_barriers[barrierID]->reference_count == 0)
{
_CompleteBarrier(barrierID);
return;
}
}
ProcessTask();
}
}
}
}
void HydraTaskScheduler::_CompleteBarrier(uint32_t barrierID)
{
// std::lock_guard<std::mutex> lock(m_mutex);
m_barriers[barrierID]->reference_count = 0;
m_barriers[barrierID]->task_ids.clear();
m_barriers[barrierID]->waiting = false;
delete m_barriers[barrierID];
m_barriers[barrierID] = nullptr;
m_available_barrier_ids.push(barrierID);
}
/// @brief Decremenet the barrier reference. If a process is waiting for the barrier and the reference reaches 0, the process will continue.
/// @param taskID
/// @param barrierID
void HydraTaskScheduler::DecrementBarrier(HydraID taskID, HydraID barrierID)
{
std::lock_guard<std::mutex> lock(m_mutex);
_DecrementBarrier(taskID, barrierID);
}
/// @brief Decremenet the barrier reference. If a process is waiting for the barrier and the reference reaches 0, the process will continue.
/// @param taskID
/// @param barrierID
void HydraTaskScheduler::_DecrementBarrier(HydraID taskID, HydraID barrierID)
{
if ((barrierID < m_barriers.size()) && (taskID < m_tasks.size()))
{
m_barriers[barrierID]->reference_count--;
}
}
@@ -0,0 +1,117 @@
#ifndef HYDRATASKSCHEDULER
#define HYDRATASKSCHEDULER
#include "../engine/HydraObject.h"
#include "HydraTaskBarrier.h"
#include "../task/HydraTask.h"
#include <vector>
#include <deque>
#include <mutex>
#include <queue>
#include <thread>
class HydraThread;
class HydraWorkItem;
// class HydraTask;
class CLASS_DEFINE HydraTaskScheduler : public HydraObject
{
private:
std::vector<HydraTaskBarrier *> m_barriers;
std::queue<HydraID> m_available_barrier_ids;
std::mutex m_mutex;
bool m_waiting = false;
bool m_running = true;
HydraID m_waiting_id = INVALID_HYDRA_ID;
std::vector<HydraThread *> m_general_thread;
HydraThread *m_render_thread = nullptr;
HydraThread *m_physics_thread = nullptr;
std::vector<HydraTask *> m_tasks;
std::vector<HydraID> m_task_ids_waiting_for_children;
std::deque<HydraID> m_avaialble_task_ids;
std::deque<HydraID> m_general_tasks_ready_to_run;
std::deque<HydraID> m_render_tasks_ready_to_run;
std::deque<HydraID> m_physics_tasks_ready_to_run;
HydraID _SaveTask(HydraTask *taskItem);
HydraID _GetRenderTaskReadyToRun();
HydraID _GetPhysicsTaskReadyToRun();
void _DecrementBarrier(HydraID taskID, HydraID barrierID);
void _UpdateDependantTaskComplete(HydraID taskID);
void _DeleteTask(HydraID taskID);
void _AddTaskToBarrier(HydraID taskID, HydraID barrierID);
void _StartTask(HydraID taskID, bool notifyThread = false);
void _NotifyThread(std::thread::id thread_id);
HydraID _CreateBarrier();
HydraTask *const _GetTask(HydraID taskID);
HydraID _GetTaskReadyToRun(HydraThreadAffinity thread_affinity);
void _CompleteBarrier(uint32_t barrierID);
protected:
public:
template <class T>
HydraID CreateTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID = INVALID_HYDRA_ID);
template <class T>
HydraID CreateAndStartTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID = INVALID_HYDRA_ID);
HydraTask *const GetTask(HydraID taskID);
void StartTask(HydraID taskID);
void WaitForTask(HydraID taskID);
HydraID CreateBarrier();
void AddTaskToBarrier(HydraID taskID, HydraID barrierID);
void WaitForBarrier(HydraID barrierID);
void DecrementBarrier(HydraID taskID, HydraID barrierID);
void Initialise(int thread_count);
void Shutdown();
void NotifyStart(HydraID taskID);
void NotifyComplete(HydraID taskID);
void ProcessTask();
void DeleteTask(HydraID taskID);
};
template <class T>
inline HydraID HydraTaskScheduler::CreateTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID)
{
std::lock_guard<std::mutex> lock(m_mutex);
T *taskType = new T();
HydraTask *task = dynamic_cast<HydraTask *>(taskType);
if (task != nullptr)
{
task->m_barrierID = barrierID;
task->ThreadAffinity = ThreadAffinity;
HydraID id = _SaveTask(task);
if (id != INVALID_HYDRA_ID)
{
_AddTaskToBarrier(id, barrierID);
}
else
{
delete taskType;
}
return id;
}
else
{
delete taskType;
return INVALID_HYDRA_ID;
}
};
template <class T>
inline HydraID HydraTaskScheduler::CreateAndStartTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID)
{
HydraID taskID = CreateTask<T>(ThreadAffinity, barrierID);
if (taskID != INVALID_HYDRA_ID)
{
StartTask(taskID);
}
return taskID;
};
#endif /* HYDRATASKSCHEDULER */
@@ -0,0 +1,36 @@
#include "HydraThread.h"
#include "../engine/HydraEngine.h"
#include "HydraTaskScheduler.h"
#include "../task/HydraTask.h"
void HydraThread::RunLoop()
{
Initialise();
while(m_running)
{
Process();
}
}
void HydraThread::Process()
{
GetEngine()->TaskScheduler()->ProcessTask();
}
void HydraThread::Start()
{
if(!m_running)
{
m_running = true;
m_thread = std::thread(&HydraThread::RunLoop, this);
ThreadID = m_thread.get_id(); //m_thread.detach();
}
}
void HydraThread::Stop()
{
if(m_running)
{
m_running = false;
}
}
@@ -0,0 +1,32 @@
#ifndef HYDRATHREAD
#define HYDRATHREAD
#include "../engine/HydraObject.h"
#include <thread>
#include <string>
#include <mutex>
#include <condition_variable>
class CLASS_DEFINE HydraThread : public HydraObject
{
private:
std::thread m_thread;
bool m_running = false;
protected:
virtual void Initialise() {};
virtual void Process();
public:
std::string ThreadName = "";
std::mutex ThreadLock;
std::condition_variable WaitCondition;
std::thread::id ThreadID;
HydraThreadAffinity ThreadAffinity = HydraThreadAffinity::General;
void RunLoop();
void Start();
void Stop();
};
#endif /* HYDRATHREAD */

Some files were not shown because too many files have changed in this diff Show More