made a lot of changes, to get the render pipeline working

This commit is contained in:
2026-02-21 13:52:07 +01:00
parent 45501f153d
commit 769bbd4261
26 changed files with 546 additions and 150 deletions

View File

@@ -1,6 +1,7 @@
#include "Camera.hpp"
#include "elements/Transformable.hpp"
#include "interfaces/IRenderer.hpp"
#include "uuid.h"
TSE::Camera* TSE::Camera::mainCamera = nullptr;
TSE::ICameraHelper* TSE::Camera::helper = nullptr;
@@ -30,6 +31,11 @@ float TSE::Camera::GetFov() const
return fov;
}
const TSE::Vector2 &TSE::Camera::GetRenderTargetSize() const
{
return lastRtSize;
}
TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos)
{
float x = 2.0f * screenPos.x / lastRtSize.x -1.0f;

View File

@@ -8,6 +8,7 @@
#include "Vector3.hpp"
#include "interfaces/IRenderTarget.hpp"
#include "elements/BehaviourScript.hpp"
#include "uuid.h"
namespace TSE
{
@@ -31,16 +32,17 @@ namespace TSE
ProjectionType projection = ProjectionType::Orthographic;
Matrix4x4* projectionMatrix = nullptr;
Matrix4x4 viewMatrix;
float nearClippingPlane = 0;
float farClippingPlane = 100;
//perspective
float fov = 60;
Vector2 lastRtSize = {0, 0};
public:
std::vector<uuids::uuid> layersNotToRender;
static ICameraHelper* helper;
static Camera* mainCamera;
@@ -50,6 +52,7 @@ namespace TSE
float GetNearClippingPlane() const;
float GetFarClippingPlane() const;
float GetFov() const;
const Vector2& GetRenderTargetSize() const;
// Setter
Vector3 SceenPositionToGamePosition(Vector2 screenPos);

View File

@@ -7,9 +7,14 @@ TSE::TileMapChunk::TileMapChunk(int _chunksize, const Vector2 &_pos, SortingOrde
order = _order;
}
void TSE::TileMapChunk::SetTile(const Vector2& p, const Vector2& Spriteindex, TileSet* set)
void TSE::TileMapChunk::SetTile(const Vector2& p, const Vector2& Spriteindex, const Vector2& Normalindex, TileSet* set)
{
sprites[p] = set->GetSpriteIdAt(Spriteindex.x, Spriteindex.y);
int normalid = -1;
if(Normalindex != Vector2(-1,-1))
normalid = set->GetSpriteIdAt(Normalindex.x, Normalindex.y);
sprites[p] = {set->GetSpriteIdAt(Spriteindex.x, Spriteindex.y), normalid};
dirtyPositions = true;
dirtySpriteIds = true;
}
void TSE::TileMapChunk::RemoveTile(Vector2 p)
@@ -22,118 +27,130 @@ void TSE::TileMapChunk::SetOrdering(SortingOrder _order)
order = _order;
}
void TSE::TileMapChunk::GetOrderedPositions(Vector2 *array)
const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
{
switch (order)
if(dirtyPositions)
{
case TopLeft:
for (int y = 0; y < chunksize; y++)
orderedPositions.clear();
switch (order)
{
Vector2 offset = nextLine * y;
for (int x = 0; x < chunksize; x++)
case TopLeft:
for (int y = 0; y < chunksize; y++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->first - offset;
Vector2 offset = nextLine * y;
for (int x = 0; x < chunksize; x++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first - offset);
}
}
}
break;
case TopRight:
for (int y = 0; y < chunksize; y++)
{
Vector2 offset = nextLine * y;
for (int x = chunksize - 1; x >= 0; x--)
break;
case TopRight:
for (int y = 0; y < chunksize; y++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->first - offset;
Vector2 offset = nextLine * y;
for (int x = chunksize - 1; x >= 0; x--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first - offset);
}
}
}
break;
case BottomLeft:
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 offset = nextLine * y;
for (int x = 0; x < chunksize; x++)
break;
case BottomLeft:
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->first - offset;
Vector2 offset = nextLine * y;
for (int x = 0; x < chunksize; x++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first - offset);
}
}
}
break;
case BottomRight:
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 offset = nextLine * y;
for (int x = chunksize - 1; x >= 0; x--)
break;
case BottomRight:
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->first - offset;
Vector2 offset = nextLine * y;
for (int x = chunksize - 1; x >= 0; x--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first - offset);
}
}
break;
}
break;
dirtyPositions = false;
}
return &orderedPositions;
}
void TSE::TileMapChunk::GetOrderedSpriteIds(int *array)
const std::vector<TSE::Vector2i>* TSE::TileMapChunk::GetOrderedSpriteIds()
{
switch (order)
if(dirtySpriteIds)
{
case TopLeft:
for (int y = 0; y < chunksize; y++)
orderedSpriteIDs.clear();
switch (order)
{
for (int x = 0; x < chunksize; x++)
case TopLeft:
for (int y = 0; y < chunksize; y++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->second;
for (int x = 0; x < chunksize; x++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
}
}
break;
case TopRight:
for (int y = 0; y < chunksize; y++)
{
for (int x = chunksize - 1; x >= 0; x--)
break;
case TopRight:
for (int y = 0; y < chunksize; y++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->second;
for (int x = chunksize - 1; x >= 0; x--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
}
}
break;
case BottomLeft:
for (int y = chunksize - 1; y >= 0; y--)
{
for (int x = 0; x < chunksize; x++)
break;
case BottomLeft:
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->second;
for (int x = 0; x < chunksize; x++)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
}
}
break;
case BottomRight:
for (int y = chunksize - 1; y >= 0; y--)
{
for (int x = chunksize - 1; x >= 0; x--)
break;
case BottomRight:
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
*array++ = v->second;
for (int x = chunksize - 1; x >= 0; x--)
{
Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
}
break;
}
break;
dirtySpriteIds = false;
}
return &orderedSpriteIDs;
}
int TSE::TileMapChunk::GetChunksize()
@@ -154,17 +171,18 @@ void TSE::TileMap::RemoveTile(Vector2 p)
chunks[chunkIndex].RemoveTile(chunkInnerPos);
}
void TSE::TileMap::SetTile(Vector2 p, Vector2 Spriteindex)
void TSE::TileMap::SetTile(Vector2 p, Vector2 Spriteindex, Vector2 Normalindex)
{
Vector2 chunkInnerPos = LocalToChunkPos(p);
Vector2 chunkIndex = p - chunkInnerPos;
if(!chunks.contains(chunkIndex))
{
dirty = true;
chunks[chunkIndex] = TileMapChunk(chunkSize, chunkIndex, order);
chunks[chunkIndex].nextLine = nextLine;
CheckBounds(chunkIndex);
}
chunks[chunkIndex].SetTile(chunkInnerPos, Spriteindex, set);
chunks[chunkIndex].SetTile(chunkInnerPos, Spriteindex, Normalindex, set);
}
TSE::TileMapChunk* TSE::TileMap::GetChunk(const Vector2 &pos)
@@ -175,60 +193,65 @@ TSE::TileMapChunk* TSE::TileMap::GetChunk(const Vector2 &pos)
return &chunks[pos];
}
void TSE::TileMap::GetChunkPositionsInOrder(Vector2 *arr)
const std::vector<TSE::Vector2>* TSE::TileMap::GetChunkPositionsInOrder()
{
switch (order)
if(dirty)
{
case TopLeft:
for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++)
orderedChunks.clear();
switch (order)
{
for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
case TopLeft:
for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
*arr++ = v->first;
for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
}
}
break;
case TopRight:
for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++)
{
for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
break;
case TopRight:
for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
*arr++ = v->first;
for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
}
}
break;
case BottomLeft:
for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
{
for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
break;
case BottomLeft:
for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
*arr++ = v->first;
for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
}
}
break;
case BottomRight:
for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
{
for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
break;
case BottomRight:
for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
*arr++ = v->first;
for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
{
Vector2 p(x,y);
auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
}
break;
}
break;
dirty = false;
}
return &orderedChunks;
}
int TSE::TileMap::GetChunkCount()

View File

@@ -5,6 +5,7 @@
#include <unordered_map>
#include "elements/BehaviourScript.hpp"
#include "Vector2.hpp"
#include "Vector2i.hpp"
#include "elements/Sprite.hpp"
#include "elements/TileSet.hpp"
@@ -21,19 +22,23 @@ namespace TSE
struct TileMapChunk
{
private:
bool dirtyPositions = true;
bool dirtySpriteIds = true;
std::vector<Vector2> orderedPositions;
std::vector<Vector2i> orderedSpriteIDs;
SortingOrder order;
int chunksize;
std::unordered_map<Vector2, int> sprites;
std::unordered_map<Vector2, Vector2i> sprites;
public:
Vector2 nextLine;
Vector2 pos;
TileMapChunk(int _chunksize = 16, const Vector2& _pos = {0,0}, SortingOrder _order = TopRight);
void SetTile(const Vector2& p, const Vector2& Spriteindex, TileSet* set);
void SetTile(const Vector2& p, const Vector2& Spriteindex, const Vector2& Normalindex, TileSet* set);
void RemoveTile(Vector2 p);
void SetOrdering(SortingOrder _order);
void GetOrderedPositions(Vector2* array);
void GetOrderedSpriteIds(int* array);
const std::vector<Vector2>* GetOrderedPositions();
const std::vector<Vector2i>* GetOrderedSpriteIds();
int GetChunksize();
int GetSpriteCount();
@@ -42,6 +47,8 @@ namespace TSE
class TileMap : public BehaviourScript
{
private:
bool dirty = true;
std::vector<Vector2> orderedChunks;
Rect bounds = Rect(0,0,0,0);
Vector2 nextLine = Vector2(-0.5f, 1.25f);
public:
@@ -52,9 +59,9 @@ namespace TSE
std::unordered_map<Vector2, TileMapChunk> chunks;
void RemoveTile(Vector2 p);
void SetTile(Vector2 p, Vector2 Spriteindex);
void SetTile(Vector2 p, Vector2 Spriteindex, Vector2 Normalindex = {-1,-1});
TileMapChunk* GetChunk(const Vector2& pos);
void GetChunkPositionsInOrder(Vector2* arr);
const std::vector<Vector2>* GetChunkPositionsInOrder();
int GetChunkCount();
TileSet* GetTileSet();
const Rect& GetBounds() const { return bounds; }

View File

@@ -1,6 +1,7 @@
#include "Layer.hpp"
#include "BehaviourScripts/Renderable.hpp"
#include "elements/BehaviourScript.hpp"
#include "IdGenerator.hpp"
void HandleObject(TSE::Transformable* trans, TSE::TransformationStack& stack, TSE::IRenderer& rnd)
{
@@ -24,6 +25,7 @@ void HandleObject(TSE::Transformable* trans, TSE::TransformationStack& stack, TS
TSE::Layer::Layer(const string &n)
{
ID = GenerateRandomUUID();
name = n;
}
@@ -94,3 +96,13 @@ void TSE::Layer::Update()
trans->Update();
}
}
void TSE::Layer::SetNonVisual(bool v)
{
nonVisual = v;
}
bool TSE::Layer::IsVisual()
{
return !nonVisual;
}

View File

@@ -4,14 +4,16 @@
#include "Types.hpp"
#include "interfaces/IRenderer.hpp"
#include <vector>
#include "interfaces/IIdentifyable.hpp"
namespace TSE
{
class Layer
class Layer : public IIdentifyable
{
private:
string name;
std::vector<Transformable*> objectsToRender;
bool nonVisual = false;
public:
Layer(const string& name);
@@ -27,5 +29,7 @@ namespace TSE
void SetName(const string& name);
std::vector<Transformable*>& GetAllObjects();
void Update();
void SetNonVisual(bool v);
bool IsVisual();
};
} // namespace TSE

View File

@@ -60,6 +60,7 @@ namespace TSE
}
template void Material::SetValue<int>(const string&, const int&);
template void Material::SetValue<uint>(const string&, const uint&);
template void Material::SetValue<float>(const string&, const float&);
template void Material::SetValue<Vector2>(const string&, const Vector2&);
template void Material::SetValue<Vector3>(const string&, const Vector3&);
@@ -70,6 +71,7 @@ namespace TSE
template void Material::SetValue<ITexture>(const string&, const ITexture*);
template int Material::GetValue<int>(const string&) const;
template uint Material::GetValue<uint>(const string&) const;
template float Material::GetValue<float>(const string&) const;
template Vector2 Material::GetValue<Vector2>(const string&) const;
template Vector3 Material::GetValue<Vector3>(const string&) const;

View File

@@ -1,10 +1,25 @@
#include "Scene.hpp"
#include "BehaviourScripts/Camera.hpp"
#include <algorithm>
#include "Debug.hpp"
void TSE::Scene::Render(IRenderer &rnd, const IWindow &wnd)
{
auto camerasBackup = std::vector<Camera*>(IRenderer::camerasToRenderWith);
int counter = 1;
for(auto l : layers)
{
IRenderer::camerasToRenderWith.clear();
if(!l.second->IsVisual()) continue;
for(auto camera : camerasBackup)
{
auto it = std::find(camera->layersNotToRender.begin(), camera->layersNotToRender.end(), l.second->GetID());
if(it == camera->layersNotToRender.end())
{
IRenderer::camerasToRenderWith.push_back(camera);
}
}
l.second->Render(rnd);
if(counter++ != layers.size())
{

View File

@@ -0,0 +1,13 @@
#pragma once
#include "uuid.h"
namespace TSE
{
class IIdentifyable
{
protected:
uuids::uuid ID;
public:
inline const uuids::uuid& GetID() { return ID;};
};
} // namespace TSE

View File

@@ -0,0 +1,35 @@
#pragma once
#include "IObserver.hpp"
#include <vector>
#include <algorithm>
namespace TSE
{
class IObservable
{
private:
std::vector<IObserver*> objectsToNotify;
public:
inline void Observe(IObserver* observer)
{
objectsToNotify.push_back(observer);
};
inline void StopObserve(IObserver* observer)
{
auto it = std::find(objectsToNotify.begin(), objectsToNotify.end(), observer);
if(it != objectsToNotify.end())
objectsToNotify.erase(it);
};
protected:
inline void TriggerObserver(void* data)
{
for (auto &&observer : objectsToNotify)
{
observer->OnObserved(data);
}
};
};
} // namespace TSE

View File

@@ -0,0 +1,10 @@
#pragma once
namespace TSE
{
class IObserver
{
public:
virtual void OnObserved(void* data) = 0;
};
} // namespace TSE

View File

@@ -5,6 +5,7 @@
#include "version.h"
#include "IInputManager.hpp"
#include "elements/AudioEngine.hpp"
#include "IdGenerator.hpp"
#define FREEIMAGE_LIB
#include "FI/FreeImage.h"

View File

@@ -18,6 +18,7 @@ namespace TSE
virtual void Clear() const = 0;
virtual void ClearDepthBuffer() const = 0;
virtual bool ShouldClose() const = 0;
virtual void DoneSetup() = 0;
bool BaseInit() const;
void BaseUpdate() const;