initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
#ifndef GLEWINCLUDES
|
||||
#define GLEWINCLUDES
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#endif /* GLEWINCLUDES */
|
||||
@@ -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];
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "HydraActor.h"
|
||||
#include "HydraActorManager.h"
|
||||
#include "../engine/HydraEngine.h"
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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"
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
Reference in New Issue
Block a user