entity system!
This commit is contained in:
@@ -1 +0,0 @@
|
||||
dependency/
|
||||
@@ -23,6 +23,9 @@ struct GameData
|
||||
{
|
||||
void* PermanentStorage = nullptr;
|
||||
uint64_t PermanentStorageSize = 0;
|
||||
|
||||
void* EntityStorage = nullptr;
|
||||
uint64_t EntityStorageSize = 0;
|
||||
};
|
||||
|
||||
struct SharedData
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cwchar>
|
||||
#include <fileapi.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <synchapi.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
@@ -258,6 +259,10 @@ int main()
|
||||
HANDLE shaderThread = CreateThread(NULL, 0, FileWatcherThread, &DevData.FileWatcher.ShaderWatcher, 0, &fileWatcherThreadId);
|
||||
HANDLE compiledShaderThread = CreateThread(NULL, 0, FileWatcherThread, &DevData.FileWatcher.CompiledShaderWatcher, 0, &fileWatcherThreadId);
|
||||
|
||||
Shared.Game.PermanentStorageSize = 1024*1024;
|
||||
Shared.Game.PermanentStorage = VirtualAllocEx(GetCurrentProcess(), NULL, Shared.Game.PermanentStorageSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
Shared.Game.EntityStorageSize = 1024*1024;
|
||||
Shared.Game.EntityStorage = VirtualAllocEx(GetCurrentProcess(), NULL, Shared.Game.EntityStorageSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
StartupFunc(Shared);
|
||||
|
||||
bool isRunning = true;
|
||||
|
||||
@@ -3,15 +3,52 @@
|
||||
|
||||
struct SharedData;
|
||||
|
||||
struct IVec2
|
||||
{
|
||||
int32_t X = 0;
|
||||
int32_t Y = 0;
|
||||
};
|
||||
|
||||
struct IVec3
|
||||
{
|
||||
int32_t X = 0;
|
||||
int32_t Y = 0;
|
||||
};
|
||||
|
||||
struct Vec2
|
||||
{
|
||||
float X = 0.0f;
|
||||
float Y = 0.0f;
|
||||
};
|
||||
|
||||
struct Vec3
|
||||
{
|
||||
float X = 0.0f;
|
||||
float Y = 0.0f;
|
||||
float Z = 0.0f;
|
||||
};
|
||||
|
||||
struct Quat
|
||||
{
|
||||
float X = 0.0f;
|
||||
float Y = 0.0f;
|
||||
float Z = 0.0f;
|
||||
float W = 1.0f;
|
||||
};
|
||||
|
||||
struct Mat4
|
||||
{
|
||||
float M[16] {
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
};
|
||||
};
|
||||
|
||||
namespace Game
|
||||
{
|
||||
struct GameInstance
|
||||
{
|
||||
bool IsInitialized = false;
|
||||
uint64_t Size = sizeof(GameInstance);
|
||||
uint32_t FrameCounter = 0;
|
||||
int64_t StartTime = 0;
|
||||
};
|
||||
struct GameInstance;
|
||||
|
||||
SharedData& GetShared();
|
||||
void SetShared(SharedData& instance);
|
||||
|
||||
17
src/game/Instance.h
Normal file
17
src/game/Instance.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Level.h"
|
||||
|
||||
namespace Game
|
||||
{
|
||||
struct GameInstance
|
||||
{
|
||||
bool IsInitialized = false;
|
||||
uint64_t Size = sizeof(GameInstance);
|
||||
uint32_t FrameCounter = 0;
|
||||
int64_t StartTime = 0;
|
||||
double Now = 0.0;
|
||||
Level GameLevel;
|
||||
};
|
||||
}
|
||||
57
src/game/Level.cpp
Normal file
57
src/game/Level.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "Level.h"
|
||||
#include "Log.h"
|
||||
#include "Global.h"
|
||||
#include "Instance.h"
|
||||
#include <bx/math.h>
|
||||
#include <bgfx/bgfx.h>
|
||||
|
||||
namespace Game
|
||||
{
|
||||
void Level::Setup(GameData& data)
|
||||
{
|
||||
Log("Level setup");
|
||||
Cubes.Setup(data.EntityStorage);
|
||||
if (Cubes.Count == 0)
|
||||
{
|
||||
uint64_t state = 0
|
||||
| BGFX_STATE_WRITE_RGB
|
||||
| BGFX_STATE_WRITE_A
|
||||
| BGFX_STATE_WRITE_Z
|
||||
| BGFX_STATE_DEPTH_TEST_LESS
|
||||
| BGFX_STATE_CULL_CW
|
||||
| BGFX_STATE_MSAA;
|
||||
|
||||
for (uint32_t yy = 0; yy < 11; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < 11; ++xx)
|
||||
{
|
||||
Cube* c = Cubes.New();
|
||||
if (c)
|
||||
{
|
||||
c->TestX = xx;
|
||||
c->TestY = yy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Level::Update()
|
||||
{
|
||||
Cubes.Update();
|
||||
}
|
||||
|
||||
void Cube::Setup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cube::Update()
|
||||
{
|
||||
double time = GetInstance().Now;
|
||||
bx::mtxRotateXY(Transform.M, time + TestX * 0.1f, time * 2 + TestY * .37f);
|
||||
Transform.M[12] = -15.0f + float(TestX) * 3.0f;
|
||||
Transform.M[13] = -15.0f + float(TestY) * 3.0f;
|
||||
Transform.M[14] = 0.0f;
|
||||
}
|
||||
}
|
||||
91
src/game/Level.h
Normal file
91
src/game/Level.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
#include "../engine/Shared.h"
|
||||
#include "Log.h"
|
||||
#include <bgfx/bgfx.h>
|
||||
|
||||
namespace Game
|
||||
{
|
||||
|
||||
typedef uint16_t CubeHandle;
|
||||
|
||||
struct Cube
|
||||
{
|
||||
int32_t TestX = 0;
|
||||
int32_t TestY = 0;
|
||||
Mat4 Transform;
|
||||
uint16_t MaterialIdx = 0;
|
||||
uint16_t ModelIdx = 0;
|
||||
|
||||
void Setup();
|
||||
void Update();
|
||||
};
|
||||
|
||||
template<typename T, uint32_t C>
|
||||
class EntityManager
|
||||
{
|
||||
public:
|
||||
uint16_t Count = 0;
|
||||
T* Data = nullptr;
|
||||
uint32_t EntitySize = 0;
|
||||
|
||||
public:
|
||||
uint64_t Setup(void* ptr)
|
||||
{
|
||||
if (EntitySize != sizeof(T))
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
EntitySize = sizeof(T);
|
||||
Data = reinterpret_cast<T*>(ptr);
|
||||
return C*sizeof(T);
|
||||
}
|
||||
|
||||
T* New()
|
||||
{
|
||||
if (Data == nullptr)
|
||||
{
|
||||
Log("Accessed EntityManager before setup!");
|
||||
return nullptr;
|
||||
}
|
||||
if (Count >= C)
|
||||
{
|
||||
Log("Too many entities!");
|
||||
return nullptr;
|
||||
}
|
||||
Data[Count] = {};
|
||||
Data[Count].Setup();
|
||||
T* result = &Data[Count];
|
||||
++Count;
|
||||
return result;
|
||||
}
|
||||
|
||||
T* Get(uint16_t idx)
|
||||
{
|
||||
if (idx > Count)
|
||||
{
|
||||
Log("OOB Access!");
|
||||
return nullptr;
|
||||
}
|
||||
return &Data[idx];
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
for (uint32_t i = 0; i < Count; ++i)
|
||||
{
|
||||
Data[i].Update();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Level
|
||||
{
|
||||
public:
|
||||
EntityManager<Cube, 1024> Cubes;
|
||||
|
||||
public:
|
||||
void Setup(GameData& data);
|
||||
void Update();
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "Setup.h"
|
||||
#include "Log.h"
|
||||
#include "bx/timer.h"
|
||||
#include "rendering/Rendering.h"
|
||||
#include "Global.h"
|
||||
#include "Instance.h"
|
||||
|
||||
namespace Game
|
||||
{
|
||||
@@ -20,7 +22,22 @@ namespace Game
|
||||
{
|
||||
Log("Game Setup Start!");
|
||||
|
||||
GameInstance& instance = *reinterpret_cast<GameInstance*>(&shared.Game.PermanentStorage);
|
||||
if (shared.Game.PermanentStorage == nullptr)
|
||||
{
|
||||
Log("Game memory not initialized!!");
|
||||
return;
|
||||
}
|
||||
if (shared.Game.EntityStorage == nullptr)
|
||||
{
|
||||
Log("Entity memory not initialized!");
|
||||
return;
|
||||
}
|
||||
if (shared.Game.PermanentStorageSize < sizeof(GameInstance))
|
||||
{
|
||||
Log("Game memory too small! %u < %u", shared.Game.PermanentStorageSize, sizeof(GameInstance));
|
||||
return;
|
||||
}
|
||||
GameInstance& instance = *reinterpret_cast<GameInstance*>(shared.Game.PermanentStorage);
|
||||
if (sizeof(GameInstance) != instance.Size)
|
||||
{
|
||||
Log("Game instance size changed, resetting!");
|
||||
@@ -29,11 +46,14 @@ namespace Game
|
||||
SetShared(shared);
|
||||
SetInstance(instance);
|
||||
SetupInstance.Rendering.Setup();
|
||||
instance.GameLevel.Setup(shared.Game);
|
||||
instance.IsInitialized = true;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
++GetInstance().FrameCounter;
|
||||
GetInstance().Now = (bx::getHPCounter() - GetInstance().StartTime) / (double)(bx::getHPFrequency());
|
||||
SetupInstance.Rendering.Update();
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,6 +2,7 @@
|
||||
#include "../Log.h"
|
||||
#include "../../engine/Shared.h"
|
||||
#include "../Global.h"
|
||||
#include "../Instance.h"
|
||||
#include "bgfx/defines.h"
|
||||
#include "bx/timer.h"
|
||||
#include <bx/file.h>
|
||||
@@ -18,18 +19,20 @@ namespace Game
|
||||
float y;
|
||||
float z;
|
||||
uint32_t abgr;
|
||||
float uv_x;
|
||||
float uv_y;
|
||||
};
|
||||
|
||||
static PosColorVertex cubeVertices[] =
|
||||
{
|
||||
{-1.0f, 1.0f, 1.0f, 0xff000000 },
|
||||
{ 1.0f, 1.0f, 1.0f, 0xff0000ff },
|
||||
{-1.0f, -1.0f, 1.0f, 0xff00ff00 },
|
||||
{ 1.0f, -1.0f, 1.0f, 0xff00ffff },
|
||||
{-1.0f, 1.0f, -1.0f, 0xffff0000 },
|
||||
{ 1.0f, 1.0f, -1.0f, 0xffff00ff },
|
||||
{-1.0f, -1.0f, -1.0f, 0xffffff00 },
|
||||
{ 1.0f, -1.0f, -1.0f, 0xffffffff },
|
||||
{-1.0f, 1.0f, 1.0f, 0xff000000, 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 0xff0000ff, 0.0f, 0.0f },
|
||||
{-1.0f, -1.0f, 1.0f, 0xff00ff00, 0.0f, 0.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 0xff00ffff, 0.0f, 0.0f },
|
||||
{-1.0f, 1.0f, -1.0f, 0xffff0000, 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, -1.0f, 0xffff00ff, 0.0f, 0.0f },
|
||||
{-1.0f, -1.0f, -1.0f, 0xffffff00, 0.0f, 0.0f },
|
||||
{ 1.0f, -1.0f, -1.0f, 0xffffffff, 0.0f, 0.0f },
|
||||
};
|
||||
|
||||
static const uint16_t cubeTriList[] =
|
||||
@@ -147,20 +150,28 @@ namespace Game
|
||||
bgfx::setDebug(BGFX_DEBUG_TEXT);
|
||||
bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0);
|
||||
|
||||
VertLayout.begin()
|
||||
Models[0].VertLayout.begin()
|
||||
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
|
||||
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
|
||||
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
|
||||
.end();
|
||||
|
||||
VertexBuffer = bgfx::createVertexBuffer(bgfx::makeRef(cubeVertices, sizeof(cubeVertices)), VertLayout);
|
||||
IndexBuffer = bgfx::createIndexBuffer(bgfx::makeRef(cubeTriList, sizeof(cubeTriList)));
|
||||
Models[0].VertexBuffer = bgfx::createVertexBuffer(bgfx::makeRef(cubeVertices, sizeof(cubeVertices)), Models[0].VertLayout);
|
||||
Models[0].IndexBuffer = bgfx::createIndexBuffer(bgfx::makeRef(cubeTriList, sizeof(cubeTriList)));
|
||||
bgfx::ShaderHandle vertexShader = loadShader("vert");
|
||||
bgfx::ShaderHandle fragmentShader = loadShader("frag");
|
||||
Shader = bgfx::createProgram(vertexShader, fragmentShader, true);
|
||||
|
||||
Materials[0].Shader = bgfx::createProgram(vertexShader, fragmentShader, true);
|
||||
Materials[0].State = 0
|
||||
| BGFX_STATE_WRITE_RGB
|
||||
| BGFX_STATE_WRITE_A
|
||||
| BGFX_STATE_WRITE_Z
|
||||
| BGFX_STATE_DEPTH_TEST_LESS
|
||||
| BGFX_STATE_CULL_CW
|
||||
| BGFX_STATE_MSAA;
|
||||
|
||||
if (!GetInstance().IsInitialized)
|
||||
{
|
||||
GetInstance().IsInitialized = true;
|
||||
GetInstance().StartTime = bx::getHPCounter();
|
||||
}
|
||||
}
|
||||
@@ -169,6 +180,7 @@ namespace Game
|
||||
{
|
||||
SharedData& shared = GetShared();
|
||||
|
||||
// Reload shaders if necessary
|
||||
FileChangeNotification* shaderChange = nullptr;
|
||||
if (shared.Dev.ChangedShaderCount > 0)
|
||||
{
|
||||
@@ -183,7 +195,7 @@ namespace Game
|
||||
bgfx::ProgramHandle newProgram = bgfx::createProgram(vertexShader, fragmentShader, true);
|
||||
if (isValid(newProgram))
|
||||
{
|
||||
Shader = newProgram;
|
||||
Materials[0].Shader = newProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -192,8 +204,7 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
int64_t tickDelta = bx::getHPCounter() - GetInstance().StartTime;
|
||||
double time = tickDelta / double(bx::getHPFrequency());
|
||||
GetInstance().GameLevel.Update();
|
||||
|
||||
const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
|
||||
const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f };
|
||||
@@ -215,43 +226,25 @@ namespace Game
|
||||
// if no other draw calls are submitted to view 0.
|
||||
bgfx::touch(0);
|
||||
|
||||
bgfx::IndexBufferHandle ibh = IndexBuffer;
|
||||
uint64_t state = 0
|
||||
| BGFX_STATE_WRITE_RGB
|
||||
| BGFX_STATE_WRITE_A
|
||||
| BGFX_STATE_WRITE_Z
|
||||
| BGFX_STATE_DEPTH_TEST_LESS
|
||||
| BGFX_STATE_CULL_CW
|
||||
| BGFX_STATE_MSAA
|
||||
;
|
||||
|
||||
// Submit 11x11 cubes.
|
||||
for (uint32_t yy = 0; yy < 11; ++yy)
|
||||
for (int32_t i = 0; i < GetInstance().GameLevel.Cubes.Count; ++i)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < 11; ++xx)
|
||||
Cube* c = GetInstance().GameLevel.Cubes.Get(i);
|
||||
if (c)
|
||||
{
|
||||
float mtx[16];
|
||||
bx::mtxRotateXY(mtx, time + xx * 0.21f, time + yy * 0.37f);
|
||||
mtx[12] = -15.0f + float(xx) * 3.0f;
|
||||
mtx[13] = -15.0f + float(yy) * 3.0f;
|
||||
mtx[14] = 0.0f;
|
||||
bgfx::setTransform(c->Transform.M);
|
||||
|
||||
// Set model matrix for rendering.
|
||||
bgfx::setTransform(mtx);
|
||||
|
||||
// Set vertex and index buffer.
|
||||
bgfx::setVertexBuffer(0, VertexBuffer);
|
||||
bgfx::setIndexBuffer(ibh);
|
||||
|
||||
// Set render states.
|
||||
bgfx::setState(state);
|
||||
Model& currentModel = Models[c->ModelIdx];
|
||||
Material& currentMaterial = Materials[c->MaterialIdx];
|
||||
bgfx::setVertexBuffer(0, currentModel.VertexBuffer);
|
||||
bgfx::setIndexBuffer(currentModel.IndexBuffer);
|
||||
bgfx::setState(currentMaterial.State);
|
||||
|
||||
// Submit primitive for rendering to view 0.
|
||||
bgfx::submit(0, Shader);
|
||||
bgfx::submit(0, currentMaterial.Shader);
|
||||
}
|
||||
}
|
||||
|
||||
bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", time);
|
||||
bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", GetInstance().Now);
|
||||
bgfx::dbgTextPrintf(1, 2, 0x0f, "Frame: %u", GetInstance().FrameCounter);
|
||||
|
||||
bgfx::frame();
|
||||
|
||||
@@ -77,19 +77,25 @@ namespace Game
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderState
|
||||
struct Model
|
||||
{
|
||||
bgfx::VertexBufferHandle VertexBuffer;
|
||||
bgfx::IndexBufferHandle IndexBuffer;
|
||||
bgfx::VertexLayout VertLayout;
|
||||
};
|
||||
|
||||
struct Material
|
||||
{
|
||||
bgfx::ProgramHandle Shader;
|
||||
uint64_t State = 0;
|
||||
};
|
||||
|
||||
class GameRendering
|
||||
{
|
||||
private:
|
||||
bgfx::VertexLayout VertLayout;
|
||||
bgfx::VertexBufferHandle VertexBuffer;
|
||||
bgfx::IndexBufferHandle IndexBuffer;
|
||||
bgfx::ProgramHandle Shader;
|
||||
Material Materials[8];
|
||||
Model Models[8];
|
||||
BgfxCallback Callback;
|
||||
RenderState State;
|
||||
public:
|
||||
void Setup();
|
||||
void Update();
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
$input v_color0
|
||||
$input v_uv0
|
||||
|
||||
#include "common.sh"
|
||||
|
||||
float circle(vec2 uv, vec2 center, float size)
|
||||
{
|
||||
vec2 relPos = uv - center;
|
||||
vec2 distSq = relPos.x * relPos.x + relPos.y * relPos.y;
|
||||
return sqrt(distSq) <= size ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = v_color0;
|
||||
gl_FragColor = circle(v_uv0, vec2(0.5, 0.5), 0.5);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
vec4 v_color0 : COLOR0 = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
vec2 v_uv0 : TEXCOORD0 = vec2(0.0, 0.0);
|
||||
|
||||
vec3 a_position : POSITION;
|
||||
vec4 a_color0 : COLOR0;
|
||||
vec2 a_texcoord0 : TEXCOORD0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
$input a_position, a_color0
|
||||
$output v_color0
|
||||
$input a_position, a_color0, a_texcoord0
|
||||
$output v_color0, v_uv0
|
||||
|
||||
#include "common.sh"
|
||||
|
||||
@@ -7,4 +7,5 @@ void main()
|
||||
{
|
||||
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
|
||||
v_color0 = a_color0;
|
||||
v_uv0 = a_texcoord0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user