11 Commits

198 changed files with 87685 additions and 779 deletions

View File

@@ -1,9 +1,21 @@
#include "IdGenerator.hpp" #include "IdGenerator.hpp"
std::mt19937 rnd = std::mt19937(); bool init = false;
std::mt19937 rnd;
auto gen = uuids::uuid_random_generator(rnd); auto gen = uuids::uuid_random_generator(rnd);
uuids::uuid TSE::GenerateRandomUUID() uuids::uuid TSE::GenerateRandomUUID()
{ {
if(!init)
{
InitRandomIDs();
init = true;
}
return gen(); return gen();
} }
void TSE::InitRandomIDs()
{
rnd = std::mt19937();
gen = uuids::uuid_random_generator(rnd);
}

View File

@@ -5,4 +5,5 @@
namespace TSE namespace TSE
{ {
uuids::uuid GenerateRandomUUID(); uuids::uuid GenerateRandomUUID();
void InitRandomIDs();
} // namespace TSE } // namespace TSE

View File

@@ -1,6 +1,7 @@
#include "Camera.hpp" #include "Camera.hpp"
#include "elements/Transformable.hpp" #include "elements/Transformable.hpp"
#include "interfaces/IRenderer.hpp" #include "interfaces/IRenderer.hpp"
#include "uuid.h"
TSE::Camera* TSE::Camera::mainCamera = nullptr; TSE::Camera* TSE::Camera::mainCamera = nullptr;
TSE::ICameraHelper* TSE::Camera::helper = nullptr; TSE::ICameraHelper* TSE::Camera::helper = nullptr;
@@ -30,6 +31,11 @@ float TSE::Camera::GetFov() const
return fov; return fov;
} }
const TSE::Vector2 &TSE::Camera::GetRenderTargetSize() const
{
return lastRtSize;
}
TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos) TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos)
{ {
float x = 2.0f * screenPos.x / lastRtSize.x -1.0f; float x = 2.0f * screenPos.x / lastRtSize.x -1.0f;
@@ -95,7 +101,11 @@ void TSE::Camera::SetRenderTarget(IRenderTarget *target)
if(target != nullptr) if(target != nullptr)
target->AddResizeNotifiable(this); target->AddResizeNotifiable(this);
rt = target; rt = target;
RecalculateProjMatrix(); if(lastRtSize != rt->GetRawIResizableSize())
{
lastRtSize = rt->GetRawIResizableSize();
RecalculateProjMatrix();
}
} }
TSE::IRenderTarget *TSE::Camera::GetRenderTarget() TSE::IRenderTarget *TSE::Camera::GetRenderTarget()
@@ -176,14 +186,36 @@ TSE::Matrix4x4 BuildView_Zplus_RH(const TSE::Matrix4x4& world)
void TSE::Camera::PreDraw(IShader *shader) void TSE::Camera::PreDraw(IShader *shader)
{ {
rt->Bind(); rt->Bind();
shader->SetUniform("prMatrix", projectionMatrix); // shader->SetUniform("prMatrix", projectionMatrix);
auto worlmatrix = baseObject->GetGlobalMatrix(); // auto worlmatrix = baseObject->GetGlobalMatrix();
viewMatrix = BuildView_Zplus_RH(worlmatrix); // viewMatrix = BuildView_Zplus_RH(worlmatrix);
shader->SetUniform("camMatrix", &viewMatrix); // shader->SetUniform("camMatrix", &viewMatrix);
helper->OnRenderTargetChanged(lastRtSize.x, lastRtSize.y); // helper->OnRenderTargetChanged(lastRtSize.x, lastRtSize.y);
Vector3 pos = baseObject->GetGlobalPosition();
Vector3 right = baseObject->LocalToGlobalPosition(Vector3::right) - pos;
Vector3 up = baseObject->LocalToGlobalPosition(Vector3::up) - pos;
Vector3 forward = baseObject->LocalToGlobalPosition(Vector3::forward) - pos;
forward.Normalize();
shader->SetUniform("CamPos", &pos);
shader->SetUniform("CamRight", &right);
shader->SetUniform("CamUp", &up);
shader->SetUniform("CamForward", &forward);
float x = lastRtSize.x / RenderScale;
float y = lastRtSize.y / RenderScale;
float mx = -x;
float my = -y;
shader->SetUniform("OrthoLeft", mx);
shader->SetUniform("OrthoRight", x);
shader->SetUniform("OrthoBottom", my);
shader->SetUniform("OrthoTop", y);
shader->SetUniform("NearPlane", nearClippingPlane);
shader->SetUniform("FarPlane", farClippingPlane);
} }
void TSE::Camera::PostDraw() void TSE::Camera::PostDraw()

View File

@@ -8,6 +8,7 @@
#include "Vector3.hpp" #include "Vector3.hpp"
#include "interfaces/IRenderTarget.hpp" #include "interfaces/IRenderTarget.hpp"
#include "elements/BehaviourScript.hpp" #include "elements/BehaviourScript.hpp"
#include "uuid.h"
namespace TSE namespace TSE
{ {
@@ -41,6 +42,7 @@ namespace TSE
Vector2 lastRtSize = {0, 0}; Vector2 lastRtSize = {0, 0};
public: public:
std::vector<uuids::uuid> layersNotToRender;
static ICameraHelper* helper; static ICameraHelper* helper;
static Camera* mainCamera; static Camera* mainCamera;
@@ -50,6 +52,7 @@ namespace TSE
float GetNearClippingPlane() const; float GetNearClippingPlane() const;
float GetFarClippingPlane() const; float GetFarClippingPlane() const;
float GetFov() const; float GetFov() const;
const Vector2& GetRenderTargetSize() const;
// Setter // Setter
Vector3 SceenPositionToGamePosition(Vector2 screenPos); Vector3 SceenPositionToGamePosition(Vector2 screenPos);

View File

@@ -0,0 +1,252 @@
#include "OrdererSpriteSet.hpp"
#include <algorithm>
#include <tuple>
#include "Debug.hpp"
TSE::OrdererSpriteSetChunk::OrdererSpriteSetChunk(int _chunksize, const Vector2 &_pos, SortingOrder _order)
{
chunksize = _chunksize;
pos = _pos;
order = _order;
}
void TSE::OrdererSpriteSetChunk::SetSprite(const Vector2 &p, const Vector2 &Spriteindex, const Vector2 &Normalindex, TileSet *set, float height, Vector2& scale)
{
int normalid = -1;
if(Normalindex != Vector2(-1,-1))
normalid = set->GetSpriteIdAt(Normalindex.x, Normalindex.y);
sprites[Vector3(p.x, p.y, height)] = {set->GetSpriteIdAt(Spriteindex.x, Spriteindex.y), normalid};
spriteScales[Vector3(p.x, p.y, height)] = scale;
dirtyPositions = true;
dirtySpriteIds = true;
dirtyScales = true;
}
void TSE::OrdererSpriteSetChunk::RemoveSprite(Vector2 p, float height)
{
sprites.erase(Vector3(p.x, p.y, height));
}
void TSE::OrdererSpriteSetChunk::SetOrdering(SortingOrder _order)
{
order = _order;
dirtyPositions = true;
dirtySpriteIds = true;
}
const std::vector<TSE::Vector3> *TSE::OrdererSpriteSetChunk::GetOrderedPositions()
{
if(dirtyPositions)
{
orderedPositions.clear();
for(auto pos : sprites)
{
orderedPositions.push_back(pos.first);
}
switch (order)
{
case TopLeft:
std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b)
{
return std::tie(a.y, a.x) > std::tie(b.y, b.x);
});
break;
case TopRight:
std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b)
{
if (a.y != b.y)
return a.y > b.y;
return a.x > b.x;
});
break;
case BottomLeft:
std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b)
{
return std::tie(a.y, a.x) < std::tie(b.y, b.x);
});
break;
case BottomRight:
std::sort(orderedPositions.begin(), orderedPositions.end(), [](const Vector3& a, const Vector3& b)
{
if (a.y != b.y)
return a.y < b.y;
return a.x > b.x;
});
break;
}
dirtyPositions = false;
}
return &orderedPositions;
}
const std::vector<TSE::Vector2i> *TSE::OrdererSpriteSetChunk::GetOrderedSpriteIds()
{
if(dirtySpriteIds)
{
orderedSpriteIDs.clear();
auto tmp = GetOrderedPositions();
for(auto& pos : *tmp)
{
auto v = sprites.find(pos);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
else
orderedSpriteIDs.push_back({0,0});
}
dirtySpriteIds = false;
}
return &orderedSpriteIDs;
}
const std::vector<TSE::Vector2> *TSE::OrdererSpriteSetChunk::GetOrderedScales()
{
if(dirtyScales)
{
orderedScales.clear();
auto tmp = GetOrderedPositions();
for(auto& pos : *tmp)
{
auto v = spriteScales.find(pos);
if(v != spriteScales.end())
orderedScales.push_back(v->second);
else
orderedScales.push_back({1,1});
}
dirtyScales = false;
}
return &orderedScales;
}
int TSE::OrdererSpriteSetChunk::GetChunksize()
{
return chunksize;
}
int TSE::OrdererSpriteSetChunk::GetSpriteCount()
{
return sprites.size();
}
void TSE::OrdererSpriteSet::RemoveSprite(Vector2 p, float height)
{
Vector2 chunkInnerPos = LocalToChunkPos(p);
Vector2 chunkIndex = p - chunkInnerPos;
if(chunks.contains(chunkIndex))
chunks[chunkIndex].RemoveSprite(chunkInnerPos, height);
}
void TSE::OrdererSpriteSet::SetSprite(Vector2 p, Vector2 Spriteindex, float height, Vector2 scale, Vector2 Normalindex)
{
Vector2 chunkInnerPos = LocalToChunkPos(p);
Vector2 chunkIndex = p - chunkInnerPos;
// Vector2 p2 = Vector2((int)p.x % chunkSize, (int)p.y % chunkSize);
// Vector2 chunkIndex = p - p2;
if(!chunks.contains(chunkIndex))
{
dirty = true;
chunks[chunkIndex] = OrdererSpriteSetChunk(chunkSize, chunkIndex, order);
}
chunks[chunkIndex].SetSprite(chunkInnerPos, Spriteindex, Normalindex, set, height, scale);
}
TSE::OrdererSpriteSetChunk *TSE::OrdererSpriteSet::GetChunk(const Vector2 &pos)
{
auto chunk = chunks.find(pos);
if(chunk == chunks.end())
return nullptr;
return &chunks[pos];
}
const std::vector<TSE::Vector2> *TSE::OrdererSpriteSet::GetChunkPositionsInOrder()
{
if(dirty)
{
orderedChunks.clear();
for(auto pos : chunks)
{
orderedChunks.push_back(pos.first);
}
switch (order)
{
case TopLeft:
std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b)
{
if (a.y != b.y)
return a.y > b.y;
return a.x < b.x;
});
break;
case TopRight:
std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b)
{
if (a.y != b.y)
return a.y > b.y;
return a.x > b.x;
});
break;
case BottomLeft:
std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b)
{
if (a.y != b.y)
return a.y < b.y;
return a.x < b.x;
});
break;
case BottomRight:
std::sort(orderedChunks.begin(), orderedChunks.end(), [](const Vector2& a, const Vector2& b)
{
if (a.y != b.y)
return a.y < b.y;
return a.x > b.x;
});
break;
}
dirty = false;
string poses = "[";
for(auto pos : orderedChunks)
{
poses += pos.ToString() + ",";
}
poses.erase(poses.end() - 1);
poses += "]";
TSE_LOG("orderedPositions: " + poses);
}
return &orderedChunks;
}
int TSE::OrdererSpriteSet::GetChunkCount()
{
return chunks.size();
}
TSE::TileSet *TSE::OrdererSpriteSet::GetTileSet()
{
return set;
}
void TSE::OrdererSpriteSet::DirtyAll()
{
dirty = true;
for(auto& chunk : chunks)
{
chunk.second.dirtyPositions = true;
chunk.second.dirtySpriteIds = true;
chunk.second.dirtyScales = true;
}
}
TSE::Vector2 TSE::OrdererSpriteSet::LocalToChunkPos(const Vector2 &v)
{
Vector2 p = Vector2((int)v.x % chunkSize, (int)v.y % chunkSize);
if(p.x < 0) p.x += chunkSize;
if(p.y < 0) p.y += chunkSize;
return p;
}

View File

@@ -0,0 +1,74 @@
#pragma once
#define ORDERERSPRITESET typeid(OrdererSpriteSet).name()
#include "elements/BehaviourScript.hpp"
#include "elements/Transformable.hpp"
#include "Types.hpp"
#include "enums/SortingOrder.hpp"
#include "Vector2.hpp"
#include "Vector2i.hpp"
#include <unordered_map>
#include "elements/Sprite.hpp"
#include "elements/TileSet.hpp"
namespace TSE
{
struct OrdererSpriteSetChunk
{
private:
std::vector<Vector3> orderedPositions;
std::vector<Vector2i> orderedSpriteIDs;
std::vector<Vector2> orderedScales;
SortingOrder order;
int chunksize;
std::unordered_map<Vector3, Vector2i> sprites;
std::unordered_map<Vector3, Vector2> spriteScales;
public:
bool dirtyPositions = true;
bool dirtySpriteIds = true;
bool dirtyScales = true;
Vector2 pos;
OrdererSpriteSetChunk(int _chunksize = 16, const Vector2& _pos = {0,0}, SortingOrder _order = TopRight);
void SetSprite(const Vector2& p, const Vector2& Spriteindex, const Vector2& Normalindex, TileSet* set, float height, Vector2& scale);
void RemoveSprite(Vector2 p, float height);
void SetOrdering(SortingOrder _order);
const std::vector<Vector3>* GetOrderedPositions();
const std::vector<Vector2i>* GetOrderedSpriteIds();
const std::vector<Vector2>* GetOrderedScales();
int GetChunksize();
int GetSpriteCount();
};
class OrdererSpriteSet : public TSE::BehaviourScript
{
private:
bool dirty = true;
std::vector<Vector2> orderedChunks;
Rect bounds = Rect(0,0,0,0);
public:
int chunkSize = 16;
SortingOrder order = TopRight;
TileSet* set;
std::unordered_map<Vector2, OrdererSpriteSetChunk> chunks;
void RemoveSprite(Vector2 p, float height);
void SetSprite(Vector2 p, Vector2 Spriteindex, float height, Vector2 scale, Vector2 Normalindex = {-1,-1});
OrdererSpriteSetChunk* GetChunk(const Vector2& pos);
const std::vector<Vector2>* GetChunkPositionsInOrder();
int GetChunkCount();
TileSet* GetTileSet();
void DirtyAll();
inline const char* GetName() override
{
return "Orderer Sprite Set";
}
private:
Vector2 LocalToChunkPos(const Vector2& v);
};
} // namespace TSE

View File

@@ -7,9 +7,14 @@ TSE::TileMapChunk::TileMapChunk(int _chunksize, const Vector2 &_pos, SortingOrde
order = _order; 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) void TSE::TileMapChunk::RemoveTile(Vector2 p)
@@ -20,120 +25,134 @@ void TSE::TileMapChunk::RemoveTile(Vector2 p)
void TSE::TileMapChunk::SetOrdering(SortingOrder _order) void TSE::TileMapChunk::SetOrdering(SortingOrder _order)
{ {
order = _order; order = _order;
dirtyPositions = true;
dirtySpriteIds = true;
} }
void TSE::TileMapChunk::GetOrderedPositions(Vector2 *array) const std::vector<TSE::Vector2>* TSE::TileMapChunk::GetOrderedPositions()
{ {
switch (order) if(dirtyPositions)
{ {
case TopLeft: orderedPositions.clear();
for (int y = 0; y < chunksize; y++) switch (order)
{ {
Vector2 offset = nextLine * y; case TopLeft:
for (int x = 0; x < chunksize; x++) for (int y = 0; y < chunksize; y++)
{ {
Vector2 p(x,y); Vector2 offset = nextLine * y;
auto v = sprites.find(p); for (int x = 0; x < chunksize; x++)
if(v != sprites.end()) {
*array++ = v->first - offset; Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
}
} }
} break;
break; case TopRight:
case TopRight: for (int y = 0; y < chunksize; y++)
for (int y = 0; y < chunksize; y++)
{
Vector2 offset = nextLine * y;
for (int x = chunksize - 1; x >= 0; x--)
{ {
Vector2 p(x,y); Vector2 offset = nextLine * y;
auto v = sprites.find(p); for (int x = chunksize - 1; x >= 0; x--)
if(v != sprites.end()) {
*array++ = v->first - offset; Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
}
} }
} break;
break; case BottomLeft:
case BottomLeft: for (int y = chunksize - 1; y >= 0; y--)
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 offset = nextLine * y;
for (int x = 0; x < chunksize; x++)
{ {
Vector2 p(x,y); Vector2 offset = nextLine * y;
auto v = sprites.find(p); for (int x = 0; x < chunksize; x++)
if(v != sprites.end()) {
*array++ = v->first - offset; Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
}
} }
} break;
break; case BottomRight:
case BottomRight: for (int y = chunksize - 1; y >= 0; y--)
for (int y = chunksize - 1; y >= 0; y--)
{
Vector2 offset = nextLine * y;
for (int x = chunksize - 1; x >= 0; x--)
{ {
Vector2 p(x,y); Vector2 offset = nextLine * y;
auto v = sprites.find(p); for (int x = chunksize - 1; x >= 0; x--)
if(v != sprites.end()) {
*array++ = v->first - offset; Vector2 p(x,y);
auto v = sprites.find(p);
if(v != sprites.end())
orderedPositions.push_back(v->first * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * y, nextLine.y * 0.5f * x));
}
} }
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: orderedSpriteIDs.clear();
for (int y = 0; y < chunksize; y++) switch (order)
{ {
for (int x = 0; x < chunksize; x++) case TopLeft:
for (int y = 0; y < chunksize; y++)
{ {
Vector2 p(x,y); for (int x = 0; x < chunksize; x++)
auto v = sprites.find(p); {
if(v != sprites.end()) Vector2 p(x,y);
*array++ = v->second; auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
} }
} break;
break; case TopRight:
case TopRight: for (int y = 0; y < chunksize; y++)
for (int y = 0; y < chunksize; y++)
{
for (int x = chunksize - 1; x >= 0; x--)
{ {
Vector2 p(x,y); for (int x = chunksize - 1; x >= 0; x--)
auto v = sprites.find(p); {
if(v != sprites.end()) Vector2 p(x,y);
*array++ = v->second; auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
} }
} break;
break; case BottomLeft:
case BottomLeft: for (int y = chunksize - 1; y >= 0; y--)
for (int y = chunksize - 1; y >= 0; y--)
{
for (int x = 0; x < chunksize; x++)
{ {
Vector2 p(x,y); for (int x = 0; x < chunksize; x++)
auto v = sprites.find(p); {
if(v != sprites.end()) Vector2 p(x,y);
*array++ = v->second; auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
} }
} break;
break; case BottomRight:
case BottomRight: for (int y = chunksize - 1; y >= 0; y--)
for (int y = chunksize - 1; y >= 0; y--)
{
for (int x = chunksize - 1; x >= 0; x--)
{ {
Vector2 p(x,y); for (int x = chunksize - 1; x >= 0; x--)
auto v = sprites.find(p); {
if(v != sprites.end()) Vector2 p(x,y);
*array++ = v->second; auto v = sprites.find(p);
if(v != sprites.end())
orderedSpriteIDs.push_back(v->second);
}
} }
break;
} }
break; dirtySpriteIds = false;
} }
return &orderedSpriteIDs;
} }
int TSE::TileMapChunk::GetChunksize() int TSE::TileMapChunk::GetChunksize()
@@ -154,17 +173,18 @@ void TSE::TileMap::RemoveTile(Vector2 p)
chunks[chunkIndex].RemoveTile(chunkInnerPos); 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 chunkInnerPos = LocalToChunkPos(p);
Vector2 chunkIndex = p - chunkInnerPos; Vector2 chunkIndex = p - chunkInnerPos;
if(!chunks.contains(chunkIndex)) if(!chunks.contains(chunkIndex))
{ {
dirty = true;
chunks[chunkIndex] = TileMapChunk(chunkSize, chunkIndex, order); chunks[chunkIndex] = TileMapChunk(chunkSize, chunkIndex, order);
chunks[chunkIndex].nextLine = nextLine; chunks[chunkIndex].nextLine = nextLine;
CheckBounds(chunkIndex); CheckBounds(chunkIndex);
} }
chunks[chunkIndex].SetTile(chunkInnerPos, Spriteindex, set); chunks[chunkIndex].SetTile(chunkInnerPos, Spriteindex, Normalindex, set);
} }
TSE::TileMapChunk* TSE::TileMap::GetChunk(const Vector2 &pos) TSE::TileMapChunk* TSE::TileMap::GetChunk(const Vector2 &pos)
@@ -175,60 +195,65 @@ TSE::TileMapChunk* TSE::TileMap::GetChunk(const Vector2 &pos)
return &chunks[pos]; return &chunks[pos];
} }
void TSE::TileMap::GetChunkPositionsInOrder(Vector2 *arr) const std::vector<TSE::Vector2>* TSE::TileMap::GetChunkPositionsInOrder()
{ {
if(dirty)
switch (order)
{ {
case TopLeft: orderedChunks.clear();
for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++) 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); for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
auto v = chunks.find(p); {
if(v != chunks.end()) Vector2 p(x,y);
*arr++ = v->first; auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
} }
} break;
break; case TopRight:
case TopRight: for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++)
for (int y = bounds.p1.y; y < bounds.p2.y + 1; y++)
{
for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
{ {
Vector2 p(x,y); for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
auto v = chunks.find(p); {
if(v != chunks.end()) Vector2 p(x,y);
*arr++ = v->first; auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
} }
} break;
break; case BottomLeft:
case BottomLeft: for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
{
for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
{ {
Vector2 p(x,y); for (int x = bounds.p1.x; x < bounds.p2.x + 1; x++)
auto v = chunks.find(p); {
if(v != chunks.end()) Vector2 p(x,y);
*arr++ = v->first; auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
} }
} break;
break; case BottomRight:
case BottomRight: for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
for (int y = bounds.p2.y; y > bounds.p1.y - 1; y--)
{
for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
{ {
Vector2 p(x,y); for (int x = bounds.p2.x; x > bounds.p1.x - 1; x--)
auto v = chunks.find(p); {
if(v != chunks.end()) Vector2 p(x,y);
*arr++ = v->first; auto v = chunks.find(p);
if(v != chunks.end())
orderedChunks.push_back(v->first);
}
} }
break;
} }
break; dirty = false;
} }
return &orderedChunks;
} }
int TSE::TileMap::GetChunkCount() int TSE::TileMap::GetChunkCount()
@@ -248,6 +273,7 @@ void TSE::TileMap::SetNextLineOffset(const Vector2 &offset)
{ {
chunk.nextLine = offset; chunk.nextLine = offset;
} }
DirtyAll();
} }
TSE::Vector2 TSE::TileMap::GetNextLineOffset() TSE::Vector2 TSE::TileMap::GetNextLineOffset()
@@ -255,6 +281,16 @@ TSE::Vector2 TSE::TileMap::GetNextLineOffset()
return nextLine; return nextLine;
} }
void TSE::TileMap::DirtyAll()
{
dirty = true;
for(auto& chunk : chunks)
{
chunk.second.dirtyPositions = true;
chunk.second.dirtySpriteIds = true;
}
}
void TSE::TileMap::CheckBounds(Vector2 pos) void TSE::TileMap::CheckBounds(Vector2 pos)
{ {
if(pos.x > bounds.p2.x) if(pos.x > bounds.p2.x)
@@ -279,3 +315,13 @@ TSE::Vector2 TSE::TileMap::ChunkToLocalPos(const Vector2 &v, const TileMapChunk
{ {
return v + chunk.pos * chunkSize; return v + chunk.pos * chunkSize;
} }
TSE::Vector2 TSE::TileMap::RealPosToTileMapPos(const Vector2 &v)
{
return v * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * v.y, nextLine.y * 0.5f * v.x);
}
TSE::Vector2 TSE::TileMap::TileMapToRealPos(const Vector2 &v)
{
return v * Vector2(nextLine.x, nextLine.y * 0.5f) + Vector2(-nextLine.x * v.y, nextLine.y * 0.5f * v.x);
}

View File

@@ -5,35 +5,33 @@
#include <unordered_map> #include <unordered_map>
#include "elements/BehaviourScript.hpp" #include "elements/BehaviourScript.hpp"
#include "Vector2.hpp" #include "Vector2.hpp"
#include "Vector2i.hpp"
#include "elements/Sprite.hpp" #include "elements/Sprite.hpp"
#include "elements/TileSet.hpp" #include "elements/TileSet.hpp"
#include "enums/SortingOrder.hpp"
namespace TSE namespace TSE
{ {
enum SortingOrder
{
TopRight,
TopLeft,
BottomRight,
BottomLeft,
};
struct TileMapChunk struct TileMapChunk
{ {
private: private:
std::vector<Vector2> orderedPositions;
std::vector<Vector2i> orderedSpriteIDs;
SortingOrder order; SortingOrder order;
int chunksize; int chunksize;
std::unordered_map<Vector2, int> sprites; std::unordered_map<Vector2, Vector2i> sprites;
public: public:
bool dirtyPositions = true;
bool dirtySpriteIds = true;
Vector2 nextLine; Vector2 nextLine;
Vector2 pos; Vector2 pos;
TileMapChunk(int _chunksize = 16, const Vector2& _pos = {0,0}, SortingOrder _order = TopRight); 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 RemoveTile(Vector2 p);
void SetOrdering(SortingOrder _order); void SetOrdering(SortingOrder _order);
void GetOrderedPositions(Vector2* array); const std::vector<Vector2>* GetOrderedPositions();
void GetOrderedSpriteIds(int* array); const std::vector<Vector2i>* GetOrderedSpriteIds();
int GetChunksize(); int GetChunksize();
int GetSpriteCount(); int GetSpriteCount();
@@ -42,24 +40,29 @@ namespace TSE
class TileMap : public BehaviourScript class TileMap : public BehaviourScript
{ {
private: private:
bool dirty = true;
std::vector<Vector2> orderedChunks;
Rect bounds = Rect(0,0,0,0); Rect bounds = Rect(0,0,0,0);
Vector2 nextLine = Vector2(-0.5f, 1.25f); Vector2 nextLine = Vector2(0.5f, 0.5f);
public: public:
int chunkSize = 16; int chunkSize = 16;
SortingOrder order = TopRight; SortingOrder order = BottomRight;
Vector2 SpriteScale = Vector2(1,1); Vector2 SpriteScale = Vector2(1,1);
TileSet* set; TileSet* set;
std::unordered_map<Vector2, TileMapChunk> chunks; std::unordered_map<Vector2, TileMapChunk> chunks;
void RemoveTile(Vector2 p); 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); TileMapChunk* GetChunk(const Vector2& pos);
void GetChunkPositionsInOrder(Vector2* arr); const std::vector<Vector2>* GetChunkPositionsInOrder();
int GetChunkCount(); int GetChunkCount();
TileSet* GetTileSet(); TileSet* GetTileSet();
const Rect& GetBounds() const { return bounds; } const Rect& GetBounds() const { return bounds; }
void SetNextLineOffset(const Vector2& offset); void SetNextLineOffset(const Vector2& offset);
Vector2 GetNextLineOffset(); Vector2 GetNextLineOffset();
Vector2 RealPosToTileMapPos(const Vector2& v);
Vector2 TileMapToRealPos(const Vector2& v);
void DirtyAll();
inline const char* GetName() override inline const char* GetName() override
{ {

View File

@@ -1,6 +1,7 @@
#include "Layer.hpp" #include "Layer.hpp"
#include "BehaviourScripts/Renderable.hpp" #include "BehaviourScripts/Renderable.hpp"
#include "elements/BehaviourScript.hpp" #include "elements/BehaviourScript.hpp"
#include "IdGenerator.hpp"
void HandleObject(TSE::Transformable* trans, TSE::TransformationStack& stack, TSE::IRenderer& rnd) 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) TSE::Layer::Layer(const string &n)
{ {
ID = GenerateRandomUUID();
name = n; name = n;
} }
@@ -94,3 +96,13 @@ void TSE::Layer::Update()
trans->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 "Types.hpp"
#include "interfaces/IRenderer.hpp" #include "interfaces/IRenderer.hpp"
#include <vector> #include <vector>
#include "interfaces/IIdentifyable.hpp"
namespace TSE namespace TSE
{ {
class Layer class Layer : public IIdentifyable
{ {
private: private:
string name; string name;
std::vector<Transformable*> objectsToRender; std::vector<Transformable*> objectsToRender;
bool nonVisual = false;
public: public:
Layer(const string& name); Layer(const string& name);
@@ -27,5 +29,7 @@ namespace TSE
void SetName(const string& name); void SetName(const string& name);
std::vector<Transformable*>& GetAllObjects(); std::vector<Transformable*>& GetAllObjects();
void Update(); void Update();
void SetNonVisual(bool v);
bool IsVisual();
}; };
} // namespace TSE } // namespace TSE

View File

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

View File

@@ -0,0 +1,40 @@
#include "RenderPipeline.hpp"
void TSE::RenderPipeline::AddRenderStep(const RenderStep &step)
{
steps.push_back(step);
}
void TSE::RenderPipeline::AddRenderStepAt(const RenderStep &step, int n)
{
steps.insert(steps.begin() + n, step);
}
void TSE::RenderPipeline::SetRenderStepAt(const RenderStep &step, int n)
{
steps[n] = step;
}
void TSE::RenderPipeline::RemoveRenderStepAt(int n)
{
auto i = steps.begin() += n;
steps.erase(i);
}
int TSE::RenderPipeline::GetRenderStepCount()
{
return steps.size();
}
const TSE::RenderStep &TSE::RenderPipeline::GetRenderStepAt(int n)
{
return steps[n];
}
TSE::RenderPipeline* TSE::RenderPipeline::CreateEmpty()
{
RenderPipeline* res = new RenderPipeline();
RenderStep step;
res->AddRenderStep(step);
return res;
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include "RenderStep.hpp"
namespace TSE
{
class RenderPipeline
{
private:
std::vector<RenderStep> steps;
public:
void AddRenderStep(const RenderStep& step);
void AddRenderStepAt(const RenderStep& step, int n);
void SetRenderStepAt(const RenderStep& step, int n);
void RemoveRenderStepAt(int n);
int GetRenderStepCount();
const RenderStep& GetRenderStepAt(int n);
static RenderPipeline* CreateEmpty();
};
} // namespace TSE

View File

@@ -0,0 +1,18 @@
#pragma once
#include "Layer.hpp"
#include <vector>
#include "interfaces/IRenderTarget.hpp"
#include "Types.hpp"
namespace TSE
{
struct RenderStep
{
public:
std::vector<Layer*> layersToRender;
IRenderTarget* target;
bool EditorCamera = true;
};
} // namespace TSE

View File

@@ -1,24 +1,89 @@
#include "Scene.hpp" #include "Scene.hpp"
#include "BehaviourScripts/Camera.hpp"
#include <algorithm>
#include "Debug.hpp"
#include "RenderPipeline.hpp"
void TSE::Scene::Render(IRenderer &rnd, const IWindow &wnd) void TSE::Scene::Render(IRenderer &rnd, const IWindow &wnd)
{ {
int counter = 1; RenderPipeline* pipeline = IRenderer::pipeline;
for(auto l : layers) auto camerasBackup = std::vector<Camera*>(IRenderer::camerasToRenderWith);
{
l.second->Render(rnd);
if(counter++ != layers.size())
{
rnd.End(); //OPTIMIZE:
//takes up 13,97% of function, but only needed, if there is more then one layer
//possible optimizations:
// -remove layers
// -make layer calculations, in shader
// -make an offset, that is calculated on cpu, and then commit everything at once
// now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used if(pipeline != nullptr)
rnd.Flush(); {
rnd.Begin(); for(int i = 0; i < pipeline->GetRenderStepCount(); i++)
wnd.ClearDepthBuffer(); {
IRenderer::camerasToRenderWith = std::vector<Camera*>(camerasBackup);
const RenderStep& step = pipeline->GetRenderStepAt(i);
if(!step.EditorCamera)
{
for(int i = 0; i < IRenderer::camerasToRenderWith.size(); i++)
{
if(IRenderer::camerasToRenderWith[i]->baseObject->name == ".EditorCamera")
IRenderer::camerasToRenderWith.erase(IRenderer::camerasToRenderWith.begin() + i);
}
}
for(int i = 0; i < IRenderer::camerasToRenderWith.size(); i++)
{
if(IRenderer::camerasToRenderWith[i]->baseObject->name != ".EditorCamera")
IRenderer::camerasToRenderWith[i]->SetRenderTarget(step.target);
}
int counter = 1;
for(auto l : step.layersToRender)
{
if(!l->IsVisual()) continue;
l->Render(rnd);
if(counter++ != layers.size())
{
rnd.End(); //OPTIMIZE:
//takes up 13,97% of function, but only needed, if there is more then one layer
//possible optimizations:
// -remove layers
// -make layer calculations, in shader
// -make an offset, that is calculated on cpu, and then commit everything at once
// now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used
rnd.Flush();
rnd.Begin();
wnd.ClearDepthBuffer();
}
}
}
}
else
{
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())
{
rnd.End(); //OPTIMIZE:
//takes up 13,97% of function, but only needed, if there is more then one layer
//possible optimizations:
// -remove layers
// -make layer calculations, in shader
// -make an offset, that is calculated on cpu, and then commit everything at once
// now it is better because it is only done once per frame if only one shader is used, or textures are full, or more then one layers are used
rnd.Flush();
rnd.Begin();
wnd.ClearDepthBuffer();
}
} }
} }
} }

View File

@@ -23,7 +23,6 @@ namespace TSE
public: public:
string name = "Unnamed"; string name = "Unnamed";
inline static ITextureHelper* helper = nullptr;
Texture(const string& path); Texture(const string& path);
Texture(const int& width, const int& height, int bpp = 32); Texture(const int& width, const int& height, int bpp = 32);

View File

@@ -0,0 +1,429 @@
#include "VolumeTexture3D.hpp"
#include "Debug.hpp"
#include <algorithm>
#include <cctype>
#include <filesystem>
#include <vector>
TSE::VolumeTexture3D::VolumeTexture3D(const string &path)
{
namespace fs = std::filesystem;
Size = Vector3(0, 0, 0);
Bpp = 0;
std::error_code ec;
const fs::path folderPath = fs::absolute(path, ec);
if(ec || !fs::exists(folderPath, ec))
{
TSE_WARNING("Can't create VolumeTexture3D because the given path is inaccessible: \n" + path);
return;
}
if(ec || !fs::is_directory(folderPath, ec))
{
TSE_WARNING("Can't create VolumeTexture3D because the given path is not a folder: \n" + folderPath.string());
return;
}
std::vector<fs::path> pngFiles;
for(fs::directory_iterator it(folderPath, ec); !ec && it != fs::directory_iterator(); it.increment(ec))
{
if(!it->is_regular_file(ec))
continue;
const fs::path &filePath = it->path();
auto extension = filePath.extension().string();
std::transform(extension.begin(), extension.end(), extension.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
if(extension == ".png")
pngFiles.push_back(filePath);
}
if(ec)
{
TSE_WARNING("Can't read VolumeTexture3D folder: \n" + folderPath.string());
return;
}
if(pngFiles.empty())
{
TSE_WARNING("Can't create VolumeTexture3D because the folder contains no png files: \n" + folderPath.string());
return;
}
std::sort(pngFiles.begin(), pngFiles.end());
std::vector<FIBITMAP*> loadedBitmaps;
loadedBitmaps.reserve(pngFiles.size());
uint width = 0;
uint height = 0;
for(const fs::path &filePath : pngFiles)
{
FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filePath.string().c_str(), 0);
if(fif == FREE_IMAGE_FORMAT::FIF_UNKNOWN)
fif = FreeImage_GetFIFFromFilename(filePath.string().c_str());
if(fif == FREE_IMAGE_FORMAT::FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif))
{
TSE_WARNING("Failed to load png for VolumeTexture3D: \n" + filePath.string());
for(FIBITMAP* loadedBmp : loadedBitmaps)
FreeImage_Unload(loadedBmp);
return;
}
FIBITMAP* currentBmp = FreeImage_Load(fif, filePath.string().c_str());
if(currentBmp == nullptr)
{
TSE_WARNING("Failed to load png for VolumeTexture3D: \n" + filePath.string());
for(FIBITMAP* loadedBmp : loadedBitmaps)
FreeImage_Unload(loadedBmp);
return;
}
if(FreeImage_GetBPP(currentBmp) != 32)
{
FIBITMAP* convertedBmp = FreeImage_ConvertTo32Bits(currentBmp);
FreeImage_Unload(currentBmp);
currentBmp = convertedBmp;
}
if(currentBmp == nullptr)
{
TSE_WARNING("Failed to convert png for VolumeTexture3D: \n" + filePath.string());
for(FIBITMAP* loadedBmp : loadedBitmaps)
FreeImage_Unload(loadedBmp);
return;
}
const uint currentWidth = FreeImage_GetWidth(currentBmp);
const uint currentHeight = FreeImage_GetHeight(currentBmp);
if(loadedBitmaps.empty())
{
width = currentWidth;
height = currentHeight;
}
else if(currentWidth != width || currentHeight != height)
{
TSE_WARNING("Can't create VolumeTexture3D because all pngs must have the same dimensions: \n" + filePath.string());
FreeImage_Unload(currentBmp);
for(FIBITMAP* loadedBmp : loadedBitmaps)
FreeImage_Unload(loadedBmp);
return;
}
loadedBitmaps.push_back(currentBmp);
}
Bpp = 32;
chanels = 4;
Size = Vector3(width, height, static_cast<float>(loadedBitmaps.size()));
bmp = new FIBITMAP*[loadedBitmaps.size()];
imagePtr = new byte*[loadedBitmaps.size()];
for(size_t i = 0; i < loadedBitmaps.size(); ++i)
{
bmp[i] = loadedBitmaps[i];
imagePtr[i] = FreeImage_GetBits(bmp[i]);
}
regist();
}
TSE::VolumeTexture3D::VolumeTexture3D(const int &width, const int &height, const int &depth, int bpp)
{
switch (bpp)
{
case 32:
chanels = 4;
break;
case 24:
chanels = 3;
case 16:
chanels = 1;
case 8:
chanels = 4;
}
Bpp = bpp;
Size = Vector3(width, height, depth);
bmp = new FIBITMAP*[depth];
imagePtr = new byte*[depth];
for(int i = 0; i < Depth(); i++)
{
bmp[i] = FreeImage_Allocate(width, height, bpp);
imagePtr[i] = FreeImage_GetBits(bmp[i]);
}
regist();
}
TSE::VolumeTexture3D::VolumeTexture3D(const Vector3 &size, int bpp)
: VolumeTexture3D(size.x, size.y, size.z, bpp) { }
TSE::VolumeTexture3D::~VolumeTexture3D()
{
if(bmp != nullptr)
{
for(int i = 0; i < Depth(); i++)
{
if(bmp[i] != nullptr)
{
FreeImage_Unload(bmp[i]);
bmp[i] = nullptr;
}
}
delete [] bmp;
delete [] imagePtr;
}
if(TextureID != 0)
{
PlatformDestroy();
TextureID = 0;
}
}
TSE::uint TSE::VolumeTexture3D::bpp() const
{
return Bpp;
}
TSE::Vector2 TSE::VolumeTexture3D::size() const
{
return Vector2(Size.x, Size.y);
}
float TSE::VolumeTexture3D::Width() const
{
return Size.x;
}
float TSE::VolumeTexture3D::Height() const
{
return Size.y;
}
float TSE::VolumeTexture3D::Depth() const
{
return Size.z;
}
TSE::byte TSE::VolumeTexture3D::Chanels() const
{
return chanels;
}
TSE::byte *TSE::VolumeTexture3D::GetImagePtr(const int depth) const
{
return imagePtr[depth];
}
void TSE::VolumeTexture3D::SetPixel(const Vector3 &pos, const Color &c)
{
SetPixel(pos.x, pos.y, pos.z, c);
}
void TSE::VolumeTexture3D::GetPixel(const Vector3 &pos, Color &c) const
{
GetPixel(pos.x, pos.y, pos.z, c);
}
void TSE::VolumeTexture3D::SetPixelNoApply(const Vector3 &pos, const Color &c)
{
SetPixelNoApply(pos.x, pos.y, pos.z, c);
}
void TSE::VolumeTexture3D::SetChanels(const byte &ch)
{
chanels = ch;
}
TSE::uint TSE::VolumeTexture3D::GetTextureId() const
{
return TextureID;
}
void TSE::VolumeTexture3D::SetTextureId(uint id)
{
TextureID = id;
}
void TSE::VolumeTexture3D::SetPixel(const int &x, const int &y, const int &z, const Color &c)
{
SetPixelNoApply(x,y,z,c);
Apply();
}
void TSE::VolumeTexture3D::GetPixel(const int &x, const int &y, const int &z, Color &c) const
{
if(x >= Width() || x < 0 || y >= Height() || y < 0|| z >= Depth() || z < 0)
{
TSE_WARNING("trying to access pixel outside of texture.\n pixel: (" + std::to_string(x) + ";" + std::to_string(y) + ";" + std::to_string(z) + ")\nTexture size: (" + std::to_string(Width()) + ";" + std::to_string(Height()) + ";" + std::to_string(Depth()) );
return;
}
byte* pixel = getPixelPointer(x,y,z);
byte b = *pixel++;
byte g = *pixel++;
byte r = *pixel++;
byte a = *pixel++;
if(bpp() == 8)
c = Color(r,r,r);
else if(bpp() == 24)
c = Color(r,g,b,a);
else if(bpp() == 32)
c = Color(r,g,b);
}
void TSE::VolumeTexture3D::Fill(const Color &c)
{
for (int x = 0; x < Width(); x++)
{
for (int y = 0; y < Height(); y++)
{
for (int z = 0; z < Depth(); z++)
{
SetPixelNoApply(x,y,z,c);
}
}
}
Apply();
}
void TSE::VolumeTexture3D::SetPixelNoApply(const int &x, const int &y, const int &z, const Color &c)
{
if(x >= Width() || x < 0 || y >= Height() || y < 0 || z >= Depth() || z < 0)
{
TSE_WARNING("trying to access pixel outside of texture.\n pixel: (" + std::to_string(x) + ";" + std::to_string(y) + ";" + std::to_string(z) + ")\nTexture size: (" + std::to_string(Width()) + ";" + std::to_string(Height()) + ";" + std::to_string(Depth()) );
return;
}
byte* pixel = getPixelPointer(x,y,z);
if(chanels == 4 && bpp() == 8)
{
byte r2bit = static_cast<byte>(c.r * 3.0f);
byte g2bit = static_cast<byte>(c.g * 3.0f);
byte b2bit = static_cast<byte>(c.b * 3.0f);
byte a2bit = static_cast<byte>(c.a * 3.0f);
byte result = (r2bit << 6) | (g2bit << 4) | (b2bit << 2) | a2bit;
*pixel++ = result;
return;
}
*pixel++ = c.B();
if(bpp() > 8)
{
*pixel++ = c.G();
*pixel++ = c.R();
if(bpp() > 24)
*pixel++ = c.A();
}
}
void TSE::VolumeTexture3D::AddPixelNoApply(const int &x, const int &y, const int &z, const Color &c)
{
if(x >= Width() || x < 0 ||y >= Height() || y < 0 || z >= Depth() || z < 0)
{
TSE_WARNING("trying to access pixel outside of texture.\n pixel: (" + std::to_string(x) + ";" + std::to_string(y) + ";" + std::to_string(z) + ")\nTexture size: (" + std::to_string(Width()) + ";" + std::to_string(Height()) + ";" + std::to_string(Depth()) );
return;
}
byte* pixel = getPixelPointer(x,y,z);
if(chanels == 4 && bpp() == 8) //TODO add propper adding, becouse currently is only setting
{
byte r2bit = static_cast<byte>(c.r * 3.0f);
byte g2bit = static_cast<byte>(c.g * 3.0f);
byte b2bit = static_cast<byte>(c.b * 3.0f);
byte a2bit = static_cast<byte>(c.a * 3.0f);
byte result = (r2bit << 6) | (g2bit << 4) | (b2bit << 2) | a2bit;
*pixel++ = result;
return;
}
Color bc(pixel[2], pixel[1], pixel[0], pixel[3]);
bc = c + bc;
*pixel++ = bc.B();
if(bpp() > 8)
{
*pixel++ = bc.G();
*pixel++ = bc.R();
if(bpp() > 24)
*pixel++ = bc.A();
}
}
void TSE::VolumeTexture3D::Recreate(const int &x, const int &y, const int &z, const int &bpp, const int &chanels)
{
if(bmp != nullptr)
{
for(int i = 0; i < Depth(); i++)
{
if(bmp[i] != nullptr)
{
FreeImage_Unload(bmp[i]);
bmp[i] = nullptr;
}
}
delete [] bmp;
delete [] imagePtr;
}
if(TextureID != 0)
{
PlatformDestroy();
TextureID = 0;
}
this->chanels = chanels;
Bpp = bpp;
Size = Vector3(x, y, z);
bmp = new FIBITMAP*[z];
imagePtr = new byte*[z];
for(int i = 0; i < Depth(); i++)
{
bmp[i] = FreeImage_Allocate(x, y, bpp);
imagePtr[i] = FreeImage_GetBits(bmp[i]);
}
regist();
}
void TSE::VolumeTexture3D::SavePNG(const std::string &path) const
{
//TODO: implement save all images as PNG in the given path, if the given path is inaccaseable, or not a folder, ust TSE_WARNING with an apropriate message
}
TSE::byte *TSE::VolumeTexture3D::getPixelPointer(const int &x, const int &y, const int &z) const
{
int alphaoffset = y * 2;
if(bpp() > 24)
alphaoffset = 0;
int offset = ((y * Width() + x) * (bpp() / 8) + alphaoffset);
return imagePtr[z] + offset;
}
void TSE::VolumeTexture3D::bind() const
{
helper->Bind3D(this);
}
void TSE::VolumeTexture3D::unbind() const
{
helper->UnBind3D(this);
}
void TSE::VolumeTexture3D::Apply()
{
helper->Apply3D(this);
}
void TSE::VolumeTexture3D::regist()
{
helper->Regist3D(this);
}
void TSE::VolumeTexture3D::PlatformDestroy()
{
helper->PlatromDestroy3D(this);
}

View File

@@ -0,0 +1,61 @@
#pragma once
#include "interfaces/ITexture.hpp"
#include "Types.hpp"
#include "Vector3.hpp"
#include "Color.hpp"
#include "interfaces/ITextureHelper.hpp"
#define FREEIMAGE_LIB
#include "FI/FreeImage.h"
namespace TSE
{
class VolumeTexture3D : public ITexture
{
protected:
uint TextureID = 0;
Vector3 Size;
uint Bpp;
byte chanels = 0;
FIBITMAP** bmp = nullptr;
byte** imagePtr = nullptr;
public:
string name = "Unnamed";
VolumeTexture3D(const string& path);
VolumeTexture3D(const int& width, const int& height, const int& depth, int bpp = 32);
VolumeTexture3D(const Vector3& size, int bpp = 32);
~VolumeTexture3D();
uint bpp() const;
Vector2 size() const override;
float Width() const override;
float Height() const override;
float Depth() const;
byte Chanels() const;
byte* GetImagePtr(const int depth) const;
void SetPixel(const Vector3& pos, const Color& c);
void GetPixel(const Vector3& pos, Color& c) const;
void SetPixelNoApply(const Vector3& pos, const Color& c);
void SetChanels(const byte& ch);
uint GetTextureId() const override;
void SetTextureId(uint id);
void SetPixel(const int& x, const int& y, const int& z, const Color& c);
void GetPixel(const int& x, const int& y, const int& z, Color& c) const;
void Fill(const Color& c);
void SetPixelNoApply(const int& x, const int& y, const int& z, const Color& c);
void AddPixelNoApply(const int& x, const int& y, const int& z, const Color& c);
void Recreate(const int& x, const int& y, const int& z, const int& bpp, const int& chanels);
void SavePNG(const std::string& path) const;
byte* getPixelPointer(const int& x, const int& y, const int& z) const;
void bind() const;
void unbind() const;
void Apply();
void regist();
void PlatformDestroy();
};
} // namespace TSE

View File

@@ -19,6 +19,7 @@ namespace TSE
enum Modifier enum Modifier
{ {
None = 0x0000,
ShiftMod = 0x0001, ShiftMod = 0x0001,
ControlMod = 0x0002, ControlMod = 0x0002,
AltMod = 0x0004, AltMod = 0x0004,

View File

@@ -0,0 +1,12 @@
#pragma once
namespace TSE
{
enum SortingOrder
{
TopRight,
TopLeft,
BottomRight,
BottomLeft,
};
}

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

@@ -13,11 +13,12 @@ namespace TSE
public: public:
inline static IRenderTextureCreator* factory = nullptr; inline static IRenderTextureCreator* factory = nullptr;
virtual void SetSize(Vector2 v) = 0; virtual void SetSize(Vector2 v) = 0;
virtual uint GetTextureId(uint id) const = 0;
}; };
class IRenderTextureCreator class IRenderTextureCreator
{ {
public: public:
virtual IRenderTexture* CreateTextureHeap(Vector2 v) = 0; virtual IRenderTexture* CreateTextureHeap(Vector2 v, uint textureCount = 1) = 0;
}; };
} // namespace TSE } // namespace TSE

View File

@@ -7,11 +7,13 @@
namespace TSE namespace TSE
{ {
class Camera; class Camera;
class RenderPipeline;
class IRenderer class IRenderer
{ {
public: public:
inline static TSE::RenderPipeline* pipeline = nullptr;
static std::vector<Camera*> camerasToRenderWith; static std::vector<Camera*> camerasToRenderWith;
virtual void End() = 0; virtual void End() = 0;

View File

@@ -2,6 +2,7 @@
#include <list> #include <list>
#include "IResizeNotifiable.hpp" #include "IResizeNotifiable.hpp"
#include "Vector2.hpp"
namespace TSE namespace TSE
{ {
@@ -15,5 +16,9 @@ namespace TSE
public: public:
void AddResizeNotifiable(IResizeNotifiable* obj); void AddResizeNotifiable(IResizeNotifiable* obj);
void RemoveResizeNotifiable(IResizeNotifiable* obj); void RemoveResizeNotifiable(IResizeNotifiable* obj);
inline Vector2 GetRawIResizableSize()
{
return Vector2(width, height);
};
}; };
} // namespace TSE } // namespace TSE

View File

@@ -1,12 +1,15 @@
#pragma once #pragma once
#include "Vector2.hpp" #include "Vector2.hpp"
#include "interfaces/ITextureHelper.hpp"
namespace TSE namespace TSE
{ {
class ITexture class ITexture
{ {
public: public:
inline static ITextureHelper* helper = nullptr;
virtual ~ITexture() = default; virtual ~ITexture() = default;
virtual Vector2 size() const = 0; virtual Vector2 size() const = 0;
virtual float Width() const = 0; virtual float Width() const = 0;

View File

@@ -3,6 +3,7 @@
namespace TSE namespace TSE
{ {
class Texture; class Texture;
class VolumeTexture3D;
class ITextureHelper class ITextureHelper
{ {
@@ -12,5 +13,11 @@ namespace TSE
virtual void Apply(Texture* tex) = 0; virtual void Apply(Texture* tex) = 0;
virtual void Regist(Texture* tex) = 0; virtual void Regist(Texture* tex) = 0;
virtual void PlatromDestroy(Texture* tex) = 0; virtual void PlatromDestroy(Texture* tex) = 0;
virtual void Bind3D(const VolumeTexture3D* tex) = 0;
virtual void UnBind3D(const VolumeTexture3D* tex) = 0;
virtual void Apply3D(VolumeTexture3D* tex) = 0;
virtual void Regist3D(VolumeTexture3D* tex) = 0;
virtual void PlatromDestroy3D(VolumeTexture3D* tex) = 0;
}; };
} // namespace TSE } // namespace TSE

View File

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

View File

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

View File

@@ -3,11 +3,14 @@
#include "BehaviourScriptRegistry.hpp" #include "BehaviourScriptRegistry.hpp"
#include "BehaviourScripts/AudioListener.hpp" #include "BehaviourScripts/AudioListener.hpp"
#include "BehaviourScripts/AudioSource.hpp" #include "BehaviourScripts/AudioSource.hpp"
#include "BehaviourScripts/TileMap.hpp"
#include "BehaviourScripts/OrdererSpriteSet.hpp"
#include "BehaviourScripts/PhysicsObject.hpp"
#include "BehaviourScripts/basicEditorCamera.hpp" #include "BehaviourScripts/basicEditorCamera.hpp"
TSE::EDITOR::EditorSubsystem::EditorSubsystem() : sv(nullptr), editorLayer("") TSE::EDITOR::EditorSubsystem::EditorSubsystem() : sv(nullptr), editorLayer("")
{ {
rt = IRenderTexture::factory->CreateTextureHeap({100,100}); rt = IRenderTexture::factory->CreateTextureHeap({100,100}, 5);
sv = SceneView(rt); sv = SceneView(rt);
controller.AddGuiElement("Scene", &sv); controller.AddGuiElement("Scene", &sv);
@@ -26,6 +29,9 @@ TSE::EDITOR::EditorSubsystem::EditorSubsystem() : sv(nullptr), editorLayer("")
BehaviourScriptRegistry::RegisterBehaviourScript("Camera", []() -> BehaviourScript* {return new Camera();}); BehaviourScriptRegistry::RegisterBehaviourScript("Camera", []() -> BehaviourScript* {return new Camera();});
BehaviourScriptRegistry::RegisterBehaviourScript("Audio Listener", []() -> BehaviourScript* {return new AudioListener();}); BehaviourScriptRegistry::RegisterBehaviourScript("Audio Listener", []() -> BehaviourScript* {return new AudioListener();});
BehaviourScriptRegistry::RegisterBehaviourScript("Audio Source", []() -> BehaviourScript* {return new AudioSource();}); BehaviourScriptRegistry::RegisterBehaviourScript("Audio Source", []() -> BehaviourScript* {return new AudioSource();});
BehaviourScriptRegistry::RegisterBehaviourScript("Tile Map", []() -> BehaviourScript* {return new TileMap();});
BehaviourScriptRegistry::RegisterBehaviourScript("Orderer Sprite Set", []() -> BehaviourScript* {return new OrdererSpriteSet();});
BehaviourScriptRegistry::RegisterBehaviourScript("Physics Object", []() -> BehaviourScript* { return new PhysicsObject(BodyType::Dynamic, ColliderShape::Box, 1.0f, 0.3f, Vector3(1, 1, 0)); });
#pragma region camerastuff #pragma region camerastuff
@@ -40,6 +46,7 @@ TSE::EDITOR::EditorSubsystem::EditorSubsystem() : sv(nullptr), editorLayer("")
editorLayer = Layer(".editor"); editorLayer = Layer(".editor");
editorLayer.AddTransformable(editorCamera); editorLayer.AddTransformable(editorCamera);
editorLayer.SetNonVisual(true);
#pragma endregion #pragma endregion
} }

View File

@@ -2,6 +2,7 @@
#include "BehaviourScriptRegistry.hpp" #include "BehaviourScriptRegistry.hpp"
#include "elements/ShaderRegistry.hpp" #include "elements/ShaderRegistry.hpp"
#include "BehaviourScripts/Camera.hpp" #include "BehaviourScripts/Camera.hpp"
#include "windows/HirearchieView.hpp"
#include <algorithm> #include <algorithm>
namespace TSE::EDITOR namespace TSE::EDITOR
@@ -207,6 +208,10 @@ namespace TSE::EDITOR
{ {
Draw((TileMap*)element, debug); Draw((TileMap*)element, debug);
} }
else if (name == "Orderer Sprite Set")
{
Draw((OrdererSpriteSet*)element, debug);
}
else else
{ {
element->CustomDraw(debug); element->CustomDraw(debug);
@@ -439,6 +444,14 @@ namespace TSE::EDITOR
Texture* value = element->GetValue<Texture*>(name); Texture* value = element->GetValue<Texture*>(name);
Draw(value, debug, name , true); Draw(value, debug, name , true);
} }
if (type == typeid(uint).name())
{
int value = element->GetValue<uint>(name);
if(ImGui::InputInt(name.c_str(), &value))
{
element->SetValue(name, value);
}
}
else else
{ {
ImGui::TextDisabled(("Not Implemented: " + type).c_str()); ImGui::TextDisabled(("Not Implemented: " + type).c_str());
@@ -573,7 +586,7 @@ namespace TSE::EDITOR
ImGui::Text("Editor Camera can't be main camera"); ImGui::Text("Editor Camera can't be main camera");
} }
ImGui::Separator(); ImGui::Separator();
// Render Scale // Render Scale
float renderScale = element->GetRenderScale(); float renderScale = element->GetRenderScale();
if (ImGui::DragFloat("Render Scale", &renderScale, 0.1f)) if (ImGui::DragFloat("Render Scale", &renderScale, 0.1f))
@@ -604,6 +617,56 @@ namespace TSE::EDITOR
if (ImGui::DragFloat("Field of View (deg)", &fov, 0.1f)) if (ImGui::DragFloat("Field of View (deg)", &fov, 0.1f))
element->SetFov(fov); element->SetFov(fov);
if (!isPerspective) ImGui::EndDisabled(); if (!isPerspective) ImGui::EndDisabled();
Scene* curScene = HirearchieView::currentScene;
ImGui::SeparatorText("Layers To Render");
if (curScene == nullptr)
{
ImGui::TextDisabled("No active scene available.");
return;
}
if (ImGui::BeginChild("LayersToRender", ImVec2(0, 170), ImGuiChildFlags_Borders))
{
const int layerCount = curScene->GetLayerCount();
if (layerCount <= 0)
{
ImGui::TextDisabled("Scene has no layers.");
}
else
{
for (int i = 0; i < layerCount; i++)
{
Layer* layer = curScene->GetLayerAt(i);
if (layer == nullptr) continue;
if (!layer->IsVisual()) continue;
const uuids::uuid& layerID = layer->GetID();
auto it = std::find(element->layersNotToRender.begin(), element->layersNotToRender.end(), layerID);
bool shouldRenderLayer = (it == element->layersNotToRender.end());
const std::string checkBoxLabel = layer->GetName() + "##layer_to_render_" + std::to_string(i);
if (ImGui::Checkbox(checkBoxLabel.c_str(), &shouldRenderLayer))
{
if (shouldRenderLayer)
{
auto removeIt = std::find(element->layersNotToRender.begin(), element->layersNotToRender.end(), layerID);
if (removeIt != element->layersNotToRender.end())
{
element->layersNotToRender.erase(removeIt);
}
}
else if (it == element->layersNotToRender.end())
{
element->layersNotToRender.push_back(layerID);
}
}
}
}
}
ImGui::EndChild();
} }
void ElementDrawer::Draw(ParticleSystem *element, const bool &debug) void ElementDrawer::Draw(ParticleSystem *element, const bool &debug)
{ {
@@ -828,6 +891,7 @@ namespace TSE::EDITOR
{ {
chunk.SetOrdering(element->order); chunk.SetOrdering(element->order);
} }
element->DirtyAll();
} }
ImGui::BeginDisabled(); ImGui::BeginDisabled();
@@ -855,6 +919,30 @@ namespace TSE::EDITOR
ImGui::TextDisabled(("Chunk Count: " + std::to_string(element->GetChunkCount())).c_str()); ImGui::TextDisabled(("Chunk Count: " + std::to_string(element->GetChunkCount())).c_str());
} }
} }
void ElementDrawer::Draw(OrdererSpriteSet *element, const bool &debug)
{
int orderIndex = static_cast<int>(element->order);
const char* orderItems[] = { "TopRight", "TopLeft", "BottomRight", "BottomLeft" };
if (ImGui::Combo("Order", &orderIndex, orderItems, IM_ARRAYSIZE(orderItems)))
{
element->order = static_cast<SortingOrder>(orderIndex);
for (auto& [_, chunk] : element->chunks)
{
chunk.SetOrdering(element->order);
}
element->DirtyAll();
}
ImGui::BeginDisabled();
ImGui::DragInt("Chunk Size", &element->chunkSize, 1.0f);
ImGui::EndDisabled();
if (debug)
{
ImGui::Separator();
ImGui::TextDisabled(("Chunk Count: " + std::to_string(element->GetChunkCount())).c_str());
}
}
void ElementDrawer::DrawAudioClipCompact(AudioClip *element, const bool &debug, const std::string &label) void ElementDrawer::DrawAudioClipCompact(AudioClip *element, const bool &debug, const std::string &label)
{ {
float item_spacing = ImGui::GetStyle().ItemSpacing.x; float item_spacing = ImGui::GetStyle().ItemSpacing.x;

View File

@@ -14,6 +14,7 @@
#include "BehaviourScripts/AudioListener.hpp" #include "BehaviourScripts/AudioListener.hpp"
#include "BehaviourScripts/AudioSource.hpp" #include "BehaviourScripts/AudioSource.hpp"
#include "BehaviourScripts/TileMap.hpp" #include "BehaviourScripts/TileMap.hpp"
#include "BehaviourScripts/OrdererSpriteSet.hpp"
namespace TSE::EDITOR namespace TSE::EDITOR
{ {
@@ -81,6 +82,7 @@ namespace TSE::EDITOR
static void Draw(Camera* element, const bool& debug); static void Draw(Camera* element, const bool& debug);
static void Draw(ParticleSystem* element, const bool& debug); static void Draw(ParticleSystem* element, const bool& debug);
static void Draw(TileMap* element, const bool& debug); static void Draw(TileMap* element, const bool& debug);
static void Draw(OrdererSpriteSet* element, const bool& debug);
static void DrawAudioClipCompact(AudioClip* element, const bool& debug, const std::string& label); static void DrawAudioClipCompact(AudioClip* element, const bool& debug, const std::string& label);
static void DrawAudioClipNormal(AudioClip* element, const bool& debug, const std::string& label); static void DrawAudioClipNormal(AudioClip* element, const bool& debug, const std::string& label);

View File

@@ -19,7 +19,7 @@ void TSE::EDITOR::CameraView::Define()
ImGuiWindowFlags flags2 = ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar; ImGuiWindowFlags flags2 = ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar;
if(ImGui::BeginChild("##CameraChild", {0,0}, ImGuiChildFlags_None, flags2)) if(ImGui::BeginChild("##CameraChild", {0,0}, ImGuiChildFlags_None, flags2))
{ {
ImGui::Image(fb->GetTextureId(), {fb->Width(), fb->Height()},{0,1}, {1,0}); ImGui::Image(fb->GetTextureId(0), {fb->Width(), fb->Height()},{0,1}, {1,0});
auto vec2 = ImGui::GetWindowSize(); auto vec2 = ImGui::GetWindowSize();
if(fb->Width() != vec2.x || fb->Height() != vec2.y) if(fb->Width() != vec2.x || fb->Height() != vec2.y)
{ {

View File

@@ -17,7 +17,6 @@ namespace TSE::EDITOR
RenamingTransformable = 3, RenamingTransformable = 3,
RenamingScene = 4 RenamingScene = 4
}; };
Scene* currentScene;
uuids::uuid selected = uuids::uuid(); uuids::uuid selected = uuids::uuid();
bool openPopUpNamingLayer = false; bool openPopUpNamingLayer = false;
@@ -29,6 +28,7 @@ namespace TSE::EDITOR
Layer* tmpHolder2 = nullptr; Layer* tmpHolder2 = nullptr;
public: public:
inline static Scene* currentScene = nullptr;
HirearchieView(Scene* s); HirearchieView(Scene* s);
void SetScene(Scene* s); void SetScene(Scene* s);
void Define() override; void Define() override;

View File

@@ -5,25 +5,37 @@ TSE::EDITOR::SceneView::SceneView(TSE::IRenderTexture *frameBuffer) : GuiWindow(
fb = frameBuffer; fb = frameBuffer;
} }
int selected = 0;
void TSE::EDITOR::SceneView::Define() void TSE::EDITOR::SceneView::Define()
{ {
ImGuiWindowFlags flags2 = ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar; ImGuiWindowFlags flags2 = ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar;
if(ImGui::BeginChild("##SceneChild", {0,0}, ImGuiChildFlags_None, flags2)) if(ImGui::BeginChild("##SceneChild", {0,0}, ImGuiChildFlags_None, flags2))
{ {
ImGui::Image(fb->GetTextureId(), {fb->Width(), fb->Height()},{0,1}, {1,0}); ImGui::Image(fb->GetTextureId(selected), {fb->Width(), fb->Height()},{0,1}, {1,0});
auto vec2 = ImGui::GetWindowSize(); auto vec2 = ImGui::GetWindowSize();
if(fb->Width() != vec2.x || fb->Height() != vec2.y) if(fb->Width() != vec2.x || fb->Height() != vec2.y)
{ {
fb->SetSize({vec2.x, vec2.y}); fb->SetSize({vec2.x, vec2.y});
} }
if(ImGui::IsWindowFocused())
{
IsHovered = true; static const char* items[] = {
} "0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15",
else "16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"
{ };
IsHovered = false;
} ImGui::SetCursorPos(ImVec2(6.0f, 6.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0,0,0,0.6f));
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0,0,0,0.9f));
ImGui::SetNextItemWidth(80.0f);
ImGui::Combo("##SceneDropdown", &selected, items, IM_ARRAYSIZE(items));
ImGui::PopStyleColor(2);
IsHovered = ImGui::IsWindowFocused();
} }
ImGui::EndChild(); ImGui::EndChild();
} }

View File

@@ -149,3 +149,13 @@ bool TSE::GLFW::WindowGlfw::ShouldClose() const
{ {
return glfwWindowShouldClose(window); return glfwWindowShouldClose(window);
} }
void TSE::GLFW::WindowGlfw::DoneSetup()
{
renderingBackend->onResize(width, height);
for (auto const& i : objectsToResize)
{
i->OnResize(width, height, this);
}
}

View File

@@ -7,7 +7,6 @@
#include "enums/WindowType.hpp" #include "enums/WindowType.hpp"
#include "Color.hpp" #include "Color.hpp"
namespace TSE::GLFW namespace TSE::GLFW
{ {
class WindowGlfw : public IWindow class WindowGlfw : public IWindow
@@ -36,5 +35,6 @@ namespace TSE::GLFW
bool ShouldClose() const override; bool ShouldClose() const override;
inline void Bind() override { }; inline void Bind() override { };
inline void Unbind() override { }; inline void Unbind() override { };
void DoneSetup() override;
}; };
} // namespace TSE::GLFW } // namespace TSE::GLFW

View File

@@ -0,0 +1,3 @@
#pragma once
#define TSE_GLFW

View File

@@ -1,54 +0,0 @@
#include "RenderTexture.hpp"
TSE::GLFW::RenderTexture::RenderTexture(Vector2 v) : buffer(v)
{
buffer.AddResizeNotifiable(this);
}
TSE::Vector2 TSE::GLFW::RenderTexture::size() const
{
return buffer.GetSize();
}
void TSE::GLFW::RenderTexture::SetSize(Vector2 v)
{
buffer.Resize(v);
}
float TSE::GLFW::RenderTexture::Width() const
{
return buffer.GetSize().x;
}
float TSE::GLFW::RenderTexture::Height() const
{
return buffer.GetSize().y;
}
TSE::uint TSE::GLFW::RenderTexture::GetTextureId() const
{
return buffer.GetTextureId();
}
void TSE::GLFW::RenderTexture::Update()
{
buffer.Update();
}
void TSE::GLFW::RenderTexture::Bind()
{
buffer.Bind();
}
void TSE::GLFW::RenderTexture::Unbind()
{
buffer.Unbind();
}
void TSE::GLFW::RenderTexture::OnResize(float width, float height, IResizable *wnd)
{
for (auto const& i : objectsToResize)
{
i->OnResize(width, height, this);
}
}

View File

@@ -1,61 +0,0 @@
#include "GL/gl3w.h"
#include "GL/gl.h"
#include "TextureHelperOpenGL.hpp"
void TSE::GLFW::TextureHelperOpenGL::Bind(const Texture *tex)
{
glBindTexture(GL_TEXTURE_2D, tex->GetTextureId());
}
void TSE::GLFW::TextureHelperOpenGL::UnBind(const Texture *tex)
{
glBindTexture(GL_TEXTURE_2D, 0);
}
void TSE::GLFW::TextureHelperOpenGL::Apply(Texture *tex)
{
glBindTexture(GL_TEXTURE_2D, tex->GetTextureId());
if(tex->Chanels() == 1)
{
if (tex->bpp() == 8)
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr());
}
if(tex->Chanels() == 3)
{
if(tex->bpp() == 24)
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_BGR, GL_UNSIGNED_BYTE, tex->GetImagePtr());
}
else if(tex->Chanels() == 4)
{
if(tex->bpp() == 32)
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, tex->GetImagePtr());
if (tex->bpp() == 8) //need to decode it with bitwise operations in shader
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr());
}
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
void TSE::GLFW::TextureHelperOpenGL::Regist(Texture *tex)
{
uint TextureID;
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
tex->SetTextureId(TextureID);
tex->Apply();
}
void TSE::GLFW::TextureHelperOpenGL::PlatromDestroy(Texture *tex)
{
uint id = tex->GetTextureId();
glDeleteTextures(1, &id);
}

View File

@@ -1,99 +0,0 @@
#include "FrameBuffer.hpp"
#include "Debug.hpp"
TSE::GLFW::FrameBuffer::FrameBuffer(const Vector2 &size)
{
width = size.x;
height = size.y;
CreateFBTexture();
for (auto const& i : objectsToResize)
{
i->OnResize(size.x, size.y, this);
}
Initialize();
}
void TSE::GLFW::FrameBuffer::Bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, bufferID);
}
void TSE::GLFW::FrameBuffer::Unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
TSE::GLFW::FrameBuffer::~FrameBuffer()
{
glDeleteFramebuffers(1,&bufferID);
glDeleteTextures(1, &textureID);
glDeleteRenderbuffers(1, &depthRboID);
}
void TSE::GLFW::FrameBuffer::Resize(Vector2 size)
{
width = size.x;
height = size.y;
shouldResize = true;
}
void TSE::GLFW::FrameBuffer::Update()
{
if (!shouldResize) return;
shouldResize = false;
CreateFBTexture();
for (auto const& i : objectsToResize)
{
i->OnResize(width, height, this);
}
}
TSE::uint TSE::GLFW::FrameBuffer::GetTextureId() const
{
return textureID;
}
TSE::Vector2 TSE::GLFW::FrameBuffer::GetSize() const
{
return {width, height};
}
void TSE::GLFW::FrameBuffer::Initialize()
{
glGenFramebuffers(1, &bufferID);
Bind();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRboID);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
TSE_ERROR("Failed to create OpenGL FBO.");
TSE_LOG(std::to_string(glGetError()));
}
Unbind();
}
void TSE::GLFW::FrameBuffer::LoadFBTexture()
{
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindRenderbuffer(GL_RENDERBUFFER, depthRboID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
}
void TSE::GLFW::FrameBuffer::CreateFBTexture()
{
glViewport(0,0, width, height);
//resize
if(textureID == 0)
glGenTextures(1, &textureID);
if(depthRboID == 0)
glGenRenderbuffers(1, &depthRboID);
LoadFBTexture();
}

View File

@@ -0,0 +1,659 @@
//----------------------------------------------------------------------------------------
//
// siv::PerlinNoise
// Perlin noise library for modern C++
//
// Copyright (C) 2013-2021 Ryo Suzuki <reputeless@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//----------------------------------------------------------------------------------------
# pragma once
# include <cstdint>
# include <algorithm>
# include <array>
# include <iterator>
# include <numeric>
# include <random>
# include <type_traits>
# if __has_include(<concepts>) && defined(__cpp_concepts)
# include <concepts>
# endif
// Library major version
# define SIVPERLIN_VERSION_MAJOR 3
// Library minor version
# define SIVPERLIN_VERSION_MINOR 0
// Library revision version
# define SIVPERLIN_VERSION_REVISION 0
// Library version
# define SIVPERLIN_VERSION ((SIVPERLIN_VERSION_MAJOR * 100 * 100) + (SIVPERLIN_VERSION_MINOR * 100) + (SIVPERLIN_VERSION_REVISION))
// [[nodiscard]] for constructors
# if (201907L <= __has_cpp_attribute(nodiscard))
# define SIVPERLIN_NODISCARD_CXX20 [[nodiscard]]
# else
# define SIVPERLIN_NODISCARD_CXX20
# endif
// std::uniform_random_bit_generator concept
# if __cpp_lib_concepts
# define SIVPERLIN_CONCEPT_URBG template <std::uniform_random_bit_generator URBG>
# define SIVPERLIN_CONCEPT_URBG_ template <std::uniform_random_bit_generator URBG>
# else
# define SIVPERLIN_CONCEPT_URBG template <class URBG, std::enable_if_t<std::conjunction_v<std::is_invocable<URBG&>, std::is_unsigned<std::invoke_result_t<URBG&>>>>* = nullptr>
# define SIVPERLIN_CONCEPT_URBG_ template <class URBG, std::enable_if_t<std::conjunction_v<std::is_invocable<URBG&>, std::is_unsigned<std::invoke_result_t<URBG&>>>>*>
# endif
// arbitrary value for increasing entropy
# ifndef SIVPERLIN_DEFAULT_Y
# define SIVPERLIN_DEFAULT_Y (0.12345)
# endif
// arbitrary value for increasing entropy
# ifndef SIVPERLIN_DEFAULT_Z
# define SIVPERLIN_DEFAULT_Z (0.34567)
# endif
namespace siv
{
template <class Float>
class BasicPerlinNoise
{
public:
static_assert(std::is_floating_point_v<Float>);
///////////////////////////////////////
//
// Typedefs
//
using state_type = std::array<std::uint8_t, 256>;
using value_type = Float;
using default_random_engine = std::mt19937;
using seed_type = typename default_random_engine::result_type;
///////////////////////////////////////
//
// Constructors
//
SIVPERLIN_NODISCARD_CXX20
constexpr BasicPerlinNoise() noexcept;
SIVPERLIN_NODISCARD_CXX20
explicit BasicPerlinNoise(seed_type seed);
SIVPERLIN_CONCEPT_URBG
SIVPERLIN_NODISCARD_CXX20
explicit BasicPerlinNoise(URBG&& urbg);
///////////////////////////////////////
//
// Reseed
//
void reseed(seed_type seed);
SIVPERLIN_CONCEPT_URBG
void reseed(URBG&& urbg);
///////////////////////////////////////
//
// Serialization
//
[[nodiscard]]
constexpr const state_type& serialize() const noexcept;
constexpr void deserialize(const state_type& state) noexcept;
///////////////////////////////////////
//
// Noise (The result is in the range [-1, 1])
//
[[nodiscard]]
value_type noise1D(value_type x) const noexcept;
[[nodiscard]]
value_type noise2D(value_type x, value_type y) const noexcept;
[[nodiscard]]
value_type noise3D(value_type x, value_type y, value_type z) const noexcept;
///////////////////////////////////////
//
// Noise (The result is remapped to the range [0, 1])
//
[[nodiscard]]
value_type noise1D_01(value_type x) const noexcept;
[[nodiscard]]
value_type noise2D_01(value_type x, value_type y) const noexcept;
[[nodiscard]]
value_type noise3D_01(value_type x, value_type y, value_type z) const noexcept;
///////////////////////////////////////
//
// Octave noise (The result can be out of the range [-1, 1])
//
[[nodiscard]]
value_type octave1D(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type octave2D(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type octave3D(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
///////////////////////////////////////
//
// Octave noise (The result is clamped to the range [-1, 1])
//
[[nodiscard]]
value_type octave1D_11(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type octave2D_11(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type octave3D_11(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
///////////////////////////////////////
//
// Octave noise (The result is clamped and remapped to the range [0, 1])
//
[[nodiscard]]
value_type octave1D_01(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type octave2D_01(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type octave3D_01(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
///////////////////////////////////////
//
// Octave noise (The result is normalized to the range [-1, 1])
//
[[nodiscard]]
value_type normalizedOctave1D(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type normalizedOctave2D(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type normalizedOctave3D(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
///////////////////////////////////////
//
// Octave noise (The result is normalized and remapped to the range [0, 1])
//
[[nodiscard]]
value_type normalizedOctave1D_01(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type normalizedOctave2D_01(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
[[nodiscard]]
value_type normalizedOctave3D_01(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
private:
state_type m_permutation;
};
using PerlinNoise = BasicPerlinNoise<double>;
namespace perlin_detail
{
////////////////////////////////////////////////
//
// These functions are provided for consistency.
// You may get different results from std::shuffle() with different standard library implementations.
//
SIVPERLIN_CONCEPT_URBG
[[nodiscard]]
inline std::uint64_t Random(const std::uint64_t max, URBG&& urbg)
{
return (urbg() % (max + 1));
}
template <class RandomIt, class URBG>
inline void Shuffle(RandomIt first, RandomIt last, URBG&& urbg)
{
if (first == last)
{
return;
}
using difference_type = typename std::iterator_traits<RandomIt>::difference_type;
for (RandomIt it = first + 1; it < last; ++it)
{
const std::uint64_t n = static_cast<std::uint64_t>(it - first);
std::iter_swap(it, first + static_cast<difference_type>(Random(n, std::forward<URBG>(urbg))));
}
}
//
////////////////////////////////////////////////
template <class Float>
[[nodiscard]]
inline constexpr Float Fade(const Float t) noexcept
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
template <class Float>
[[nodiscard]]
inline constexpr Float Lerp(const Float a, const Float b, const Float t) noexcept
{
return (a + (b - a) * t);
}
template <class Float>
[[nodiscard]]
inline constexpr Float Grad(const std::uint8_t hash, const Float x, const Float y, const Float z) noexcept
{
const std::uint8_t h = hash & 15;
const Float u = h < 8 ? x : y;
const Float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
template <class Float>
[[nodiscard]]
inline constexpr Float Remap_01(const Float x) noexcept
{
return (x * Float(0.5) + Float(0.5));
}
template <class Float>
[[nodiscard]]
inline constexpr Float Clamp_11(const Float x) noexcept
{
return std::clamp(x, Float(-1.0), Float(1.0));
}
template <class Float>
[[nodiscard]]
inline constexpr Float RemapClamp_01(const Float x) noexcept
{
if (x <= Float(-1.0))
{
return Float(0.0);
}
else if (Float(1.0) <= x)
{
return Float(1.0);
}
return (x * Float(0.5) + Float(0.5));
}
template <class Noise, class Float>
[[nodiscard]]
inline auto Octave1D(const Noise& noise, Float x, const std::int32_t octaves, const Float persistence) noexcept
{
using value_type = Float;
value_type result = 0;
value_type amplitude = 1;
for (std::int32_t i = 0; i < octaves; ++i)
{
result += (noise.noise1D(x) * amplitude);
x *= 2;
amplitude *= persistence;
}
return result;
}
template <class Noise, class Float>
[[nodiscard]]
inline auto Octave2D(const Noise& noise, Float x, Float y, const std::int32_t octaves, const Float persistence) noexcept
{
using value_type = Float;
value_type result = 0;
value_type amplitude = 1;
for (std::int32_t i = 0; i < octaves; ++i)
{
result += (noise.noise2D(x, y) * amplitude);
x *= 2;
y *= 2;
amplitude *= persistence;
}
return result;
}
template <class Noise, class Float>
[[nodiscard]]
inline auto Octave3D(const Noise& noise, Float x, Float y, Float z, const std::int32_t octaves, const Float persistence) noexcept
{
using value_type = Float;
value_type result = 0;
value_type amplitude = 1;
for (std::int32_t i = 0; i < octaves; ++i)
{
result += (noise.noise3D(x, y, z) * amplitude);
x *= 2;
y *= 2;
z *= 2;
amplitude *= persistence;
}
return result;
}
template <class Float>
[[nodiscard]]
inline constexpr Float MaxAmplitude(const std::int32_t octaves, const Float persistence) noexcept
{
using value_type = Float;
value_type result = 0;
value_type amplitude = 1;
for (std::int32_t i = 0; i < octaves; ++i)
{
result += amplitude;
amplitude *= persistence;
}
return result;
}
}
///////////////////////////////////////
template <class Float>
inline constexpr BasicPerlinNoise<Float>::BasicPerlinNoise() noexcept
: m_permutation{ 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 } {}
template <class Float>
inline BasicPerlinNoise<Float>::BasicPerlinNoise(const seed_type seed)
{
reseed(seed);
}
template <class Float>
SIVPERLIN_CONCEPT_URBG_
inline BasicPerlinNoise<Float>::BasicPerlinNoise(URBG&& urbg)
{
reseed(std::forward<URBG>(urbg));
}
///////////////////////////////////////
template <class Float>
inline void BasicPerlinNoise<Float>::reseed(const seed_type seed)
{
reseed(default_random_engine{ seed });
}
template <class Float>
SIVPERLIN_CONCEPT_URBG_
inline void BasicPerlinNoise<Float>::reseed(URBG&& urbg)
{
std::iota(m_permutation.begin(), m_permutation.end(), uint8_t{ 0 });
perlin_detail::Shuffle(m_permutation.begin(), m_permutation.end(), std::forward<URBG>(urbg));
}
///////////////////////////////////////
template <class Float>
inline constexpr const typename BasicPerlinNoise<Float>::state_type& BasicPerlinNoise<Float>::serialize() const noexcept
{
return m_permutation;
}
template <class Float>
inline constexpr void BasicPerlinNoise<Float>::deserialize(const state_type& state) noexcept
{
m_permutation = state;
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise1D(const value_type x) const noexcept
{
return noise3D(x,
static_cast<value_type>(SIVPERLIN_DEFAULT_Y),
static_cast<value_type>(SIVPERLIN_DEFAULT_Z));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise2D(const value_type x, const value_type y) const noexcept
{
return noise3D(x,
y,
static_cast<value_type>(SIVPERLIN_DEFAULT_Z));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise3D(const value_type x, const value_type y, const value_type z) const noexcept
{
const value_type _x = std::floor(x);
const value_type _y = std::floor(y);
const value_type _z = std::floor(z);
const std::int32_t ix = static_cast<std::int32_t>(_x) & 255;
const std::int32_t iy = static_cast<std::int32_t>(_y) & 255;
const std::int32_t iz = static_cast<std::int32_t>(_z) & 255;
const value_type fx = (x - _x);
const value_type fy = (y - _y);
const value_type fz = (z - _z);
const value_type u = perlin_detail::Fade(fx);
const value_type v = perlin_detail::Fade(fy);
const value_type w = perlin_detail::Fade(fz);
const std::uint8_t A = (m_permutation[ix & 255] + iy) & 255;
const std::uint8_t B = (m_permutation[(ix + 1) & 255] + iy) & 255;
const std::uint8_t AA = (m_permutation[A] + iz) & 255;
const std::uint8_t AB = (m_permutation[(A + 1) & 255] + iz) & 255;
const std::uint8_t BA = (m_permutation[B] + iz) & 255;
const std::uint8_t BB = (m_permutation[(B + 1) & 255] + iz) & 255;
const value_type p0 = perlin_detail::Grad(m_permutation[AA], fx, fy, fz);
const value_type p1 = perlin_detail::Grad(m_permutation[BA], fx - 1, fy, fz);
const value_type p2 = perlin_detail::Grad(m_permutation[AB], fx, fy - 1, fz);
const value_type p3 = perlin_detail::Grad(m_permutation[BB], fx - 1, fy - 1, fz);
const value_type p4 = perlin_detail::Grad(m_permutation[(AA + 1) & 255], fx, fy, fz - 1);
const value_type p5 = perlin_detail::Grad(m_permutation[(BA + 1) & 255], fx - 1, fy, fz - 1);
const value_type p6 = perlin_detail::Grad(m_permutation[(AB + 1) & 255], fx, fy - 1, fz - 1);
const value_type p7 = perlin_detail::Grad(m_permutation[(BB + 1) & 255], fx - 1, fy - 1, fz - 1);
const value_type q0 = perlin_detail::Lerp(p0, p1, u);
const value_type q1 = perlin_detail::Lerp(p2, p3, u);
const value_type q2 = perlin_detail::Lerp(p4, p5, u);
const value_type q3 = perlin_detail::Lerp(p6, p7, u);
const value_type r0 = perlin_detail::Lerp(q0, q1, v);
const value_type r1 = perlin_detail::Lerp(q2, q3, v);
return perlin_detail::Lerp(r0, r1, w);
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise1D_01(const value_type x) const noexcept
{
return perlin_detail::Remap_01(noise1D(x));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise2D_01(const value_type x, const value_type y) const noexcept
{
return perlin_detail::Remap_01(noise2D(x, y));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise3D_01(const value_type x, const value_type y, const value_type z) const noexcept
{
return perlin_detail::Remap_01(noise3D(x, y, z));
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Octave1D(*this, x, octaves, persistence);
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Octave2D(*this, x, y, octaves, persistence);
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Octave3D(*this, x, y, z, octaves, persistence);
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D_11(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Clamp_11(octave1D(x, octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D_11(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Clamp_11(octave2D(x, y, octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D_11(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Clamp_11(octave3D(x, y, z, octaves, persistence));
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D_01(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::RemapClamp_01(octave1D(x, octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D_01(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::RemapClamp_01(octave2D(x, y, octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D_01(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::RemapClamp_01(octave3D(x, y, z, octaves, persistence));
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave1D(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
{
return (octave1D(x, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave2D(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
{
return (octave2D(x, y, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave3D(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
{
return (octave3D(x, y, z, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
}
///////////////////////////////////////
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave1D_01(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Remap_01(normalizedOctave1D(x, octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave2D_01(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Remap_01(normalizedOctave2D(x, y, octaves, persistence));
}
template <class Float>
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave3D_01(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
{
return perlin_detail::Remap_01(normalizedOctave3D(x, y, z, octaves, persistence));
}
}
# undef SIVPERLIN_NODISCARD_CXX20
# undef SIVPERLIN_CONCEPT_URBG
# undef SIVPERLIN_CONCEPT_URBG_

107
TSE_Math/src/Random.cpp Normal file
View File

@@ -0,0 +1,107 @@
#include "Random.hpp"
#include <bit>
#include <cstdint>
TSE::Random::Random(uint seed)
{
state = static_cast<uint>(static_cast<std::uint32_t>(seed));
}
TSE::uint TSE::Random::nextUInt(uint minInc, uint maxInc)
{
constexpr std::uint32_t multiplier = 1664525u;
constexpr std::uint32_t increment = 1013904223u;
std::uint32_t nextState = static_cast<std::uint32_t>(state);
nextState = nextState * multiplier + increment;
state = static_cast<uint>(nextState);
if(minInc == 0u && maxInc == 0u)
{
return state;
}
if(minInc > maxInc)
{
uint temp = minInc;
minInc = maxInc;
maxInc = temp;
}
const std::uint64_t span = static_cast<std::uint64_t>(maxInc) - static_cast<std::uint64_t>(minInc) + 1ull;
const std::uint64_t offset = static_cast<std::uint64_t>(nextState) % span;
return static_cast<uint>(static_cast<std::uint64_t>(minInc) + offset);
}
int TSE::Random::nextInt(int minInc, int maxInc)
{
const std::uint32_t bits = static_cast<std::uint32_t>(nextUInt());
if(minInc == 0 && maxInc == 0)
{
return static_cast<int>(std::bit_cast<std::int32_t>(bits));
}
if(minInc > maxInc)
{
int temp = minInc;
minInc = maxInc;
maxInc = temp;
}
const std::int64_t span = static_cast<std::int64_t>(maxInc) - static_cast<std::int64_t>(minInc) + 1ll;
const std::uint64_t offset = static_cast<std::uint64_t>(bits) % static_cast<std::uint64_t>(span);
const std::int64_t value = static_cast<std::int64_t>(minInc) + static_cast<std::int64_t>(offset);
return static_cast<int>(value);
}
short TSE::Random::nextShort(short minInc, short maxInc)
{
const std::uint32_t bits = static_cast<std::uint32_t>(nextUInt());
const std::uint16_t lowerBits = static_cast<std::uint16_t>(bits);
if(minInc == 0 && maxInc == 0)
{
return static_cast<short>(std::bit_cast<std::int16_t>(lowerBits));
}
if(minInc > maxInc)
{
short temp = minInc;
minInc = maxInc;
maxInc = temp;
}
const std::int32_t span = static_cast<std::int32_t>(maxInc) - static_cast<std::int32_t>(minInc) + 1;
const std::uint32_t offset = static_cast<std::uint32_t>(lowerBits) % static_cast<std::uint32_t>(span);
const std::int32_t value = static_cast<std::int32_t>(minInc) + static_cast<std::int32_t>(offset);
return static_cast<short>(value);
}
TSE::byte TSE::Random::nextByte(byte minInc, byte maxInc)
{
const std::uint32_t bits = static_cast<std::uint32_t>(nextUInt());
const std::uint8_t lowerBits = static_cast<std::uint8_t>(bits);
if(minInc == 0 && maxInc == 0)
{
return static_cast<byte>(lowerBits);
}
if(minInc > maxInc)
{
byte temp = minInc;
minInc = maxInc;
maxInc = temp;
}
const std::uint16_t span = static_cast<std::uint16_t>(maxInc) - static_cast<std::uint16_t>(minInc) + 1u;
const std::uint16_t offset = static_cast<std::uint16_t>(lowerBits) % span;
return static_cast<byte>(static_cast<std::uint16_t>(minInc) + offset);
}
float TSE::Random::nextFloat01()
{
constexpr float invRange = 1.0f / 4294967296.0f;
return static_cast<float>(static_cast<std::uint32_t>(nextUInt())) * invRange;
}

20
TSE_Math/src/Random.hpp Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include "Types.hpp"
namespace TSE
{
class Random
{
private:
uint state;
public:
Random(uint seed);
uint nextUInt(uint minInc = 0, uint maxInc = 0);
int nextInt(int minInc = 0, int maxInc = 0);
short nextShort(short minInc = 0, short maxInc = 0);
byte nextByte(byte minInc = 0, byte maxInc = 0);
float nextFloat01();
};
}

138
TSE_Math/src/Vector2i.cpp Normal file
View File

@@ -0,0 +1,138 @@
#include "Vector2i.hpp"
#include "Vector2.hpp"
#include "Vector3.hpp"
#include "Vector4.hpp"
#include <cmath>
TSE::Vector2i::Vector2i() { }
TSE::Vector2i::Vector2i(int _x, int _y)
{
x = _x;
y = _y;
}
TSE::Vector2i::Vector2i(const Vector2i &other)
{
x = other.x;
y = other.y;
}
TSE::Vector2i::Vector2i(const Vector2 &other)
{
x = other.x;
y = other.y;
}
TSE::Vector2i::Vector2i(const Vector3 &other)
{
x = other.x;
y = other.y;
}
TSE::Vector2i::Vector2i(const Vector4 &other)
{
x = other.x;
y = other.y;
}
bool TSE::Vector2i::IsValid() const
{
return !std::isnan(x) && !std::isnan(y);
}
TSE::string TSE::Vector2i::ToString() const
{
return "(" + std::to_string(x) + "|" + std::to_string(y) + ")";
}
TSE::Vector2 TSE::Vector2i::ToVector2() const
{
return Vector2();
}
TSE::Vector3 TSE::Vector2i::ToVector3() const
{
return Vector3(x,y,0);
}
TSE::Vector4 TSE::Vector2i::ToVector4() const
{
return Vector4(x,y,0,0);
}
TSE::Vector2i TSE::Vector2i::operator+(const Vector2i &other) const
{
return Vector2i(x + other.x, y + other.y);
}
TSE::Vector2i TSE::Vector2i::operator+=(const Vector2i &other)
{
*this = *this + other;
return *this;
}
TSE::Vector2i TSE::Vector2i::operator-(const Vector2i &other) const
{
return Vector2i(x - other.x, y - other.y);
}
TSE::Vector2i TSE::Vector2i::operator-=(const Vector2i &other)
{
*this = *this - other;
return *this;
}
TSE::Vector2i TSE::Vector2i::operator*(const Vector2i &other) const
{
return Vector2i(x * other.x, y * other.y);
}
TSE::Vector2i TSE::Vector2i::operator*=(const Vector2i &other)
{
*this = *this * other;
return *this;
}
TSE::Vector2i TSE::Vector2i::operator/(const Vector2i &other) const
{
return Vector2i(x / other.x, y / other.y);
}
TSE::Vector2i TSE::Vector2i::operator/=(const Vector2i &other)
{
*this = *this / other;
return *this;
}
TSE::Vector2i TSE::Vector2i::operator*(const float other) const
{
return Vector2i(x * other, y * other);
}
TSE::Vector2i TSE::Vector2i::operator*=(const float other)
{
*this = *this * other;
return *this;
}
TSE::Vector2i TSE::Vector2i::operator/(const float other) const
{
return Vector2i(x / other, y / other);
}
TSE::Vector2i TSE::Vector2i::operator/=(const float other)
{
*this = *this / other;
return *this;
}
bool TSE::Vector2i::operator==(const Vector2i &other) const
{
return x == other.x && y == other.y;
}
bool TSE::Vector2i::operator!=(const Vector2i &other) const
{
return !(*this == other);
}

85
TSE_Math/src/Vector2i.hpp Normal file
View File

@@ -0,0 +1,85 @@
#pragma once
#include "Types.hpp"
#include "MathF.hpp"
#include <functional>
namespace TSE
{
class Vector2;
class Vector3;
class Vector4;
class Vector2i
{
public:
#pragma region members
int x = 0, y = 0;
#pragma endregion members
#pragma region consts
static const Vector2i left;
static const Vector2i right;
static const Vector2i up;
static const Vector2i down;
static const Vector2i one;
static const Vector2i zero;
#pragma endregion
#pragma region ctor
/// @brief enpty constructor defined as (0,0)
Vector2i();
/// @brief constructs a Vector2i with custom values
/// @param _x the x component
/// @param _y the y component
Vector2i(int _x, int _y);
/// @brief copy constructor
/// @param other the Vector2i to be copied from
Vector2i(const Vector2i& other);
/// @brief copy constructor
/// @param other the Vector2i to be copied from
Vector2i(const Vector2& other);
/// @brief converter constructor. it converts a Vector3 to a Vector2i without encointing for the z component
/// @param other the Vector3 to convert
Vector2i(const Vector3& other);
/// @brief converter constructor. it converts a Vector4 to a Vector2i without encointing for the z, and w component
/// @param other the Vector4 to convert
Vector2i(const Vector4& other);
#pragma endregion ctor
#pragma region methods
/// @brief checks if the individual components have valid values aka are not nan
/// @return are the values valid
bool IsValid() const;
/// @brief gives you the Vector2i as a string representation. mostly for debugging
/// @return the Vector2i in a format like (x|y)
string ToString() const;
/// @brief creates a Vector3 with the same values as the Vector2i, the y component gets the value 0
/// @return the Vector2i as a Vector3
Vector2 ToVector2() const;
/// @brief creates a Vector3 with the same values as the Vector2i, the y component gets the value 0
/// @return the Vector2i as a Vector3
Vector3 ToVector3() const;
/// @brief creates a Vector4 with the same values as the Vector2i, the y and w components get the value 0
/// @return the Vector2i as a Vector4
Vector4 ToVector4() const;
#pragma region operators
Vector2i operator+(const Vector2i& other) const;
Vector2i operator+=(const Vector2i& other);
Vector2i operator-(const Vector2i& other) const;
Vector2i operator-=(const Vector2i& other);
Vector2i operator*(const Vector2i& other) const;
Vector2i operator*=(const Vector2i& other);
Vector2i operator/(const Vector2i& other) const;
Vector2i operator/=(const Vector2i& other);
Vector2i operator*(const float other) const;
Vector2i operator*=(const float other);
Vector2i operator/(const float other) const;
Vector2i operator/=(const float other);
bool operator==(const Vector2i& other) const;
bool operator!=(const Vector2i& other) const;
#pragma endregion operators
#pragma endregion methods
};
} // namespace TSE

View File

@@ -1,6 +1,9 @@
#pragma once #pragma once
#include "Types.hpp" #include "Types.hpp"
#include <functional>
#include <cstddef>
#include "MathF.hpp"
namespace TSE namespace TSE
{ {
@@ -145,3 +148,22 @@ namespace TSE
}; };
} // namespace TSE } // namespace TSE
namespace std
{
template<>
struct hash<TSE::Vector3>
{
size_t operator()(const TSE::Vector3& v) const noexcept
{
size_t h1 = std::hash<float>{}(v.x);
size_t h2 = std::hash<float>{}(v.y);
size_t h3 = std::hash<float>{}(v.z);
size_t hash = h1;
hash ^= h2 + TSE::TSE_HASH_GOLDEN_RATIO_32 + (hash << 6) + (hash >> 2);
hash ^= h3 + TSE::TSE_HASH_GOLDEN_RATIO_32 + (hash << 6) + (hash >> 2);
return hash;
}
};
}

View File

@@ -0,0 +1,71 @@
#cmake version
cmake_minimum_required(VERSION 3.31)
#project name
project(TSE_OpenGlImpl)
#cpp settings
find_program(CLANG_C NAMES clang)
find_program(CLANG_CXX NAMES clang++)
if(CLANG_C AND CLANG_CXX)
message(STATUS "foung Clang, using as Compiler")
set(CMAKE_C_COMPILER ${CLANG_C} CACHE STRING "C Compiler" FORCE)
set(CMAKE_CXX_COMPILER ${CLANG_CXX} CACHE STRING "C++ Compiler" FORCE)
else()
message(STATUS "Clang not found, using Standard-Compiler")
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
#project output settings
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib/Debug")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib/Release")
#source files
file(GLOB CPP_SOURCE_TSE
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*/*/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*.c"
"${PROJECT_SOURCE_DIR}/src/*/*.c"
"${PROJECT_SOURCE_DIR}/src/*/*/*.c"
"${PROJECT_SOURCE_DIR}/src/*/*/*/*.c"
)
#includes
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Base/src)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Base/include)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Math/src)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Core/src)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Core/include)
#project def
if(Lib)
add_library(TSE_OpenGlImpl SHARED ${CPP_SOURCE_TSE})
else()
add_library(TSE_OpenGlImpl STATIC ${CPP_SOURCE_TSE})
endif()
# Window backend specific includes for WindowManager.hpp and platform glue.
if(USE_GLFW)
target_include_directories(TSE_OpenGlImpl PRIVATE
${PROJECT_SOURCE_DIR}/../TSE_GlfwImpl/src
${PROJECT_SOURCE_DIR}/../TSE_GlfwImpl/include
)
elseif(USE_SDL3)
target_include_directories(TSE_OpenGlImpl PRIVATE
${PROJECT_SOURCE_DIR}/../TSE_Sdl3Impl/src
${PROJECT_SOURCE_DIR}/../TSE_Sdl3Impl/include
)
endif()
#flags
target_compile_options(TSE_OpenGlImpl PRIVATE -march=native)

View File

@@ -4,7 +4,7 @@
#include "GL/gl3w.h" #include "GL/gl3w.h"
#include "GL/gl.h" #include "GL/gl.h"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class CameraHelperOpenGL : public ICameraHelper class CameraHelperOpenGL : public ICameraHelper
{ {
@@ -14,4 +14,4 @@ namespace TSE::GLFW
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
}; };
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -1,17 +1,18 @@
#include "DefaultRendererOpenGL.hpp" #include "DefaultRendererOpenGL.hpp"
#include "BehaviourScripts/Camera.hpp" #include "BehaviourScripts/Camera.hpp"
#include "BehaviourScripts/Renderable.hpp" #include "BehaviourScripts/Renderable.hpp"
#include "Debug.hpp"
#define RENDERER_MAX_SPRITES 20000 #define RENDERER_MAX_SPRITES 20000
#define RENDERER_MAX_INDECIES 60000 #define RENDERER_MAX_INDECIES 60000
TSE::GLFW::DefaultRendererOpenGL::DefaultRendererOpenGL(Shader &shader) TSE::OpenGL::DefaultRendererOpenGL::DefaultRendererOpenGL(Shader &shader)
{ {
iboData = new ushort[RENDERER_MAX_INDECIES]; iboData = new ushort[RENDERER_MAX_INDECIES];
InitShader(shader, true); InitShader(shader, true);
} }
TSE::GLFW::DefaultRendererOpenGL::~DefaultRendererOpenGL() TSE::OpenGL::DefaultRendererOpenGL::~DefaultRendererOpenGL()
{ {
if(vao != 0) if(vao != 0)
glDeleteVertexArrays(1, &vao); glDeleteVertexArrays(1, &vao);
@@ -19,7 +20,7 @@ TSE::GLFW::DefaultRendererOpenGL::~DefaultRendererOpenGL()
delete ibo; delete ibo;
} }
void TSE::GLFW::DefaultRendererOpenGL::InitShader(Shader &s, bool init) void TSE::OpenGL::DefaultRendererOpenGL::InitShader(Shader &s, bool init)
{ {
if(!init) End(); if(!init) End();
if(vao != 0) if(vao != 0)
@@ -50,13 +51,13 @@ void TSE::GLFW::DefaultRendererOpenGL::InitShader(Shader &s, bool init)
if(!init) Begin(); if(!init) Begin();
} }
void TSE::GLFW::DefaultRendererOpenGL::End() void TSE::OpenGL::DefaultRendererOpenGL::End()
{ {
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
vbo.Unbind(); vbo.Unbind();
} }
void TSE::GLFW::DefaultRendererOpenGL::Flush() void TSE::OpenGL::DefaultRendererOpenGL::Flush()
{ {
lastShader->Flush(); lastShader->Flush();
@@ -78,6 +79,8 @@ void TSE::GLFW::DefaultRendererOpenGL::Flush()
camerasToRenderWith[i]->PostDraw(); camerasToRenderWith[i]->PostDraw();
} }
lastShader->PostDraw();
if(ibobound) if(ibobound)
{ {
ibo->Unbind(); ibo->Unbind();
@@ -88,18 +91,18 @@ void TSE::GLFW::DefaultRendererOpenGL::Flush()
iboOffset = 0; iboOffset = 0;
} }
void TSE::GLFW::DefaultRendererOpenGL::Begin() void TSE::OpenGL::DefaultRendererOpenGL::Begin()
{ {
vbo.Bind(); vbo.Bind();
bufferPointer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); bufferPointer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
} }
void TSE::GLFW::DefaultRendererOpenGL::Submit(const Transformable &trans, TransformationStack &stack) void TSE::OpenGL::DefaultRendererOpenGL::Submit(const Transformable &trans, TransformationStack &stack)
{ {
Submit(trans, (IShader*)lastShader, stack); Submit(trans, (IShader*)lastShader, stack);
} }
void TSE::GLFW::DefaultRendererOpenGL::Submit(const Transformable &trans, IShader *shader, TransformationStack &stack) void TSE::OpenGL::DefaultRendererOpenGL::Submit(const Transformable &trans, IShader *shader, TransformationStack &stack)
{ {
Shader* s = dynamic_cast<Shader*>(shader); Shader* s = dynamic_cast<Shader*>(shader);
if(lastShader == nullptr) InitShader(*s, true); if(lastShader == nullptr) InitShader(*s, true);
@@ -134,14 +137,14 @@ void TSE::GLFW::DefaultRendererOpenGL::Submit(const Transformable &trans, IShade
lastShader->Submit(trans, bufferPointer, stack, Redraw, *this); lastShader->Submit(trans, bufferPointer, stack, Redraw, *this);
} }
void TSE::GLFW::DefaultRendererOpenGL::Redraw(IRenderer &rnd) void TSE::OpenGL::DefaultRendererOpenGL::Redraw(IRenderer &rnd)
{ {
rnd.End(); rnd.End();
rnd.Flush(); rnd.Flush();
rnd.Begin(); rnd.Begin();
} }
bool TSE::GLFW::DefaultRendererOpenGL::CreateIbo() bool TSE::OpenGL::DefaultRendererOpenGL::CreateIbo()
{ {
if(indexCount == 0) return true; if(indexCount == 0) return true;
if(ibo != nullptr) if(ibo != nullptr)

View File

@@ -6,7 +6,7 @@
#include "interfaces/IRenderer.hpp" #include "interfaces/IRenderer.hpp"
#include <vector> #include <vector>
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class DefaultRendererOpenGL : public IRenderer class DefaultRendererOpenGL : public IRenderer
{ {
@@ -35,4 +35,4 @@ namespace TSE::GLFW
static void Redraw(IRenderer& rnd); static void Redraw(IRenderer& rnd);
bool CreateIbo(); bool CreateIbo();
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -1,24 +1,36 @@
#include "GL/gl3w.h" #include "GL/gl3w.h"
#include "GL/gl.h" #include "GL/gl.h"
#include "OpenGLRenderingBackend.hpp" #include "OpenGLRenderingBackend.hpp"
#include "GLFW/glfw3.h"
#include "WindowGlfw.hpp"
#include "Debug.hpp" #include "Debug.hpp"
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include "extern/imgui_impl_glfw.h"
#include "extern/imgui_impl_opengl3.h" #include "extern/imgui_impl_opengl3.h"
#include "PathHelper.hpp" #include "PathHelper.hpp"
#include "elements/Texture.hpp" #include "interfaces/ITexture.hpp"
#include "TextureHelperOpenGL.hpp" #include "TextureHelperOpenGL.hpp"
#include "interfaces/IRenderer.hpp" #include "interfaces/IRenderer.hpp"
#include "BehaviourScripts/Camera.hpp" #include "BehaviourScripts/Camera.hpp"
#include "RenderTextureCreatorOpenGL.hpp" #include "RenderTextureCreatorOpenGL.hpp"
#include "CameraHelperOpenGL.hpp" #include "CameraHelperOpenGL.hpp"
TSE::GLFW::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync) #include "WindowManager.hpp"
#if defined(TSE_GLFW)
#include "GLFW/glfw3.h"
#include "WindowGlfw.hpp"
#include "extern/imgui_impl_glfw.h"
using namespace TSE::GLFW;
#elif defined(TSE_SDL3)
#include "SDL3/SDL.h"
#include "WindowSdl3.hpp"
#include "extern/imgui_impl_sdl3.h"
using namespace TSE::SDL3;
#endif
TSE::OpenGL::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync)
: OpenGLRenderingBackend(_backgroundColor, _vsync, 0, false){ } : OpenGLRenderingBackend(_backgroundColor, _vsync, 0, false){ }
TSE::GLFW::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync, int _samples, bool _useseImGui) TSE::OpenGL::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync, int _samples, bool _useseImGui)
{ {
backgroundColor = _backgroundColor; backgroundColor = _backgroundColor;
vsync = _vsync; vsync = _vsync;
@@ -26,33 +38,50 @@ TSE::GLFW::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor
useseImGui = _useseImGui; useseImGui = _useseImGui;
} }
TSE::GLFW::OpenGLRenderingBackend::~OpenGLRenderingBackend() TSE::OpenGL::OpenGLRenderingBackend::~OpenGLRenderingBackend()
{ {
if(useseImGui) if(useseImGui)
{ {
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
#if defined(TSE_GLFW)
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
#elif defined(TSE_SDL3)
ImGui_ImplSDL3_Shutdown();
#endif
ImGui::DestroyContext(); ImGui::DestroyContext();
} }
} }
void TSE::GLFW::OpenGLRenderingBackend::InitPreWindow() void TSE::OpenGL::OpenGLRenderingBackend::InitPreWindow()
{ {
IRenderTexture::factory = new RenderTextureCreatorOpenGL(); IRenderTexture::factory = new RenderTextureCreatorOpenGL();
Texture::helper = new TextureHelperOpenGL(); ITexture::helper = new TextureHelperOpenGL();
Camera::helper = new CameraHelperOpenGL(); Camera::helper = new CameraHelperOpenGL();
#if defined(TSE_GLFW)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, TSE_OPENGL_VERSION_MAJOR); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, TSE_OPENGL_VERSION_MAJOR);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, TSE_OPENGL_VERSION_MINOR); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, TSE_OPENGL_VERSION_MINOR);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_SAMPLES, samples); glfwWindowHint(GLFW_SAMPLES, samples);
#elif defined(TSE_SDL3)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, TSE_OPENGL_VERSION_MAJOR);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, TSE_OPENGL_VERSION_MINOR);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
#endif
} }
bool TSE::GLFW::OpenGLRenderingBackend::InitPostWindow() bool TSE::OpenGL::OpenGLRenderingBackend::InitPostWindow()
{ {
#if defined(TSE_GLFW)
WindowGlfw* wnd = static_cast<WindowGlfw*>(window); WindowGlfw* wnd = static_cast<WindowGlfw*>(window);
glfwMakeContextCurrent(wnd->window); glfwMakeContextCurrent(wnd->window);
#elif defined(TSE_SDL3)
WindowSdl3* wnd = static_cast<WindowSdl3*>(window);
wnd->context = SDL_GL_CreateContext(wnd->window);
SDL_GL_MakeCurrent(wnd->window, wnd->context);
#endif
if(gl3wInit()) if(gl3wInit())
{ {
Debug::Log("Failed to initialize gl3w."); Debug::Log("Failed to initialize gl3w.");
@@ -63,9 +92,17 @@ bool TSE::GLFW::OpenGLRenderingBackend::InitPostWindow()
Debug::Log("gl3w dose not support the selected version of OpenGL."); Debug::Log("gl3w dose not support the selected version of OpenGL.");
return false; return false;
} }
#if defined(TSE_GLFW)
if(vsync) glfwSwapInterval(1); if(vsync) glfwSwapInterval(1);
else glfwSwapInterval(0); else glfwSwapInterval(0);
#elif defined(TSE_SDL3)
if(vsync)
{
if(!SDL_GL_SetSwapInterval(-1))
SDL_GL_SetSwapInterval(1);
}
else SDL_GL_SetSwapInterval(0);
#endif
Debug::Log("OpenGL:" + std::string((const char*)glGetString(GL_VERSION))); Debug::Log("OpenGL:" + std::string((const char*)glGetString(GL_VERSION)));
Debug::Log("GLSL:" + std::string((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION))); Debug::Log("GLSL:" + std::string((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)));
@@ -88,7 +125,7 @@ bool TSE::GLFW::OpenGLRenderingBackend::InitPostWindow()
std::string imguiIniPath; std::string imguiIniPath;
bool TSE::GLFW::OpenGLRenderingBackend::InitEnd() bool TSE::OpenGL::OpenGLRenderingBackend::InitEnd()
{ {
if(useseImGui) if(useseImGui)
{ {
@@ -102,8 +139,15 @@ bool TSE::GLFW::OpenGLRenderingBackend::InitEnd()
io.IniFilename = imguiIniPath.c_str(); io.IniFilename = imguiIniPath.c_str();
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
#if defined(TSE_GLFW)
WindowGlfw* wnd = static_cast<WindowGlfw*>(window); WindowGlfw* wnd = static_cast<WindowGlfw*>(window);
wnd->useImGui = true;
ImGui_ImplGlfw_InitForOpenGL(wnd->window, true); ImGui_ImplGlfw_InitForOpenGL(wnd->window, true);
#elif defined(TSE_SDL3)
WindowSdl3* wnd = static_cast<WindowSdl3*>(window);
wnd->useImGui = true;
ImGui_ImplSDL3_InitForOpenGL(wnd->window, wnd->context);
#endif
ImGui_ImplOpenGL3_Init("#version 130"); ImGui_ImplOpenGL3_Init("#version 130");
Debug::Log("ImGui:" + std::string(ImGui::GetVersion())); Debug::Log("ImGui:" + std::string(ImGui::GetVersion()));
@@ -111,12 +155,12 @@ bool TSE::GLFW::OpenGLRenderingBackend::InitEnd()
return true; return true;
} }
void TSE::GLFW::OpenGLRenderingBackend::onResize(int width, int height) void TSE::OpenGL::OpenGLRenderingBackend::onResize(int width, int height)
{ {
glViewport(0,0,width, height); glViewport(0,0,width, height);
} }
void TSE::GLFW::OpenGLRenderingBackend::onUpdate() const void TSE::OpenGL::OpenGLRenderingBackend::onUpdate() const
{ {
int error = glGetError(); int error = glGetError();
if(error != GL_NO_ERROR) if(error != GL_NO_ERROR)
@@ -124,6 +168,12 @@ void TSE::GLFW::OpenGLRenderingBackend::onUpdate() const
Debug::Log("OpenGL Error: " + std::to_string(error)); Debug::Log("OpenGL Error: " + std::to_string(error));
} }
#if defined(TSE_GLFW)
WindowGlfw* wnd = static_cast<WindowGlfw*>(window);
#elif defined(TSE_SDL3)
WindowSdl3* wnd = static_cast<WindowSdl3*>(window);
#endif
if(useseImGui) if(useseImGui)
{ {
ImGui::Render(); ImGui::Render();
@@ -132,19 +182,30 @@ void TSE::GLFW::OpenGLRenderingBackend::onUpdate() const
if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{ {
#if defined(TSE_GLFW)
GLFWwindow* backup_current_context = glfwGetCurrentContext(); GLFWwindow* backup_current_context = glfwGetCurrentContext();
#elif defined(TSE_SDL3)
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
#endif
ImGui::UpdatePlatformWindows(); ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault(); ImGui::RenderPlatformWindowsDefault();
#if defined(TSE_GLFW)
glfwMakeContextCurrent(backup_current_context); glfwMakeContextCurrent(backup_current_context);
#elif defined(TSE_SDL3)
SDL_GL_MakeCurrent(wnd->window, backup_current_context);
#endif
} }
} }
WindowGlfw* wnd = static_cast<WindowGlfw*>(window); #if defined(TSE_GLFW)
glfwSwapBuffers(wnd->window); glfwSwapBuffers(wnd->window);
#elif defined(TSE_SDL3)
SDL_GL_SwapWindow(wnd->window);
#endif
} }
void TSE::GLFW::OpenGLRenderingBackend::onClear() const void TSE::OpenGL::OpenGLRenderingBackend::onClear() const
{ {
for (int i = 0; i < IRenderer::camerasToRenderWith.size(); i++) for (int i = 0; i < IRenderer::camerasToRenderWith.size(); i++)
{ {
@@ -158,12 +219,16 @@ void TSE::GLFW::OpenGLRenderingBackend::onClear() const
if(useseImGui) if(useseImGui)
{ {
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
#if defined(TSE_GLFW)
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
#elif defined(TSE_SDL3)
ImGui_ImplSDL3_NewFrame();
#endif
ImGui::NewFrame(); ImGui::NewFrame();
} }
} }
void TSE::GLFW::OpenGLRenderingBackend::onClearDepthBuffer() const void TSE::OpenGL::OpenGLRenderingBackend::onClearDepthBuffer() const
{ {
for (int i = 0; i < IRenderer::camerasToRenderWith.size(); i++) for (int i = 0; i < IRenderer::camerasToRenderWith.size(); i++)
{ {

View File

@@ -5,7 +5,7 @@
#define TSE_OPENGL_VERSION_MAJOR 3 #define TSE_OPENGL_VERSION_MAJOR 3
#define TSE_OPENGL_VERSION_MINOR 3 #define TSE_OPENGL_VERSION_MINOR 3
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class OpenGLRenderingBackend : public IRenderingBackend class OpenGLRenderingBackend : public IRenderingBackend
{ {
@@ -25,4 +25,4 @@ namespace TSE::GLFW
void onClear() const override; void onClear() const override;
void onClearDepthBuffer() const override; void onClearDepthBuffer() const override;
}; };
} // namespace TSE } // namespace OpenGL

View File

@@ -0,0 +1,59 @@
#include "RenderTexture.hpp"
TSE::OpenGL::RenderTexture::RenderTexture(Vector2 v, uint textureCount) : buffer(v, textureCount)
{
buffer.AddResizeNotifiable(this);
}
TSE::Vector2 TSE::OpenGL::RenderTexture::size() const
{
return buffer.GetSize();
}
void TSE::OpenGL::RenderTexture::SetSize(Vector2 v)
{
buffer.Resize(v);
}
float TSE::OpenGL::RenderTexture::Width() const
{
return buffer.GetSize().x;
}
float TSE::OpenGL::RenderTexture::Height() const
{
return buffer.GetSize().y;
}
TSE::uint TSE::OpenGL::RenderTexture::GetTextureId() const
{
return buffer.GetTextureId();
}
TSE::uint TSE::OpenGL::RenderTexture::GetTextureId(uint id) const
{
return buffer.GetTextureId(id);
}
void TSE::OpenGL::RenderTexture::Update()
{
buffer.Update();
}
void TSE::OpenGL::RenderTexture::Bind()
{
buffer.Bind();
}
void TSE::OpenGL::RenderTexture::Unbind()
{
buffer.Unbind();
}
void TSE::OpenGL::RenderTexture::OnResize(float width, float height, IResizable *wnd)
{
for (auto const& i : objectsToResize)
{
i->OnResize(width, height, this);
}
}

View File

@@ -6,20 +6,21 @@
#include "interfaces/IResizeNotifiable.hpp" #include "interfaces/IResizeNotifiable.hpp"
#include "interfaces/IRenderTexture.hpp" #include "interfaces/IRenderTexture.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class RenderTexture : public IRenderTexture class RenderTexture : public IRenderTexture
{ {
public: public:
FrameBuffer buffer; FrameBuffer buffer;
RenderTexture(Vector2 v); RenderTexture(Vector2 v, uint textureCount = 1);
Vector2 size() const override; Vector2 size() const override;
void SetSize(Vector2 v) override; void SetSize(Vector2 v) override;
float Width() const override; float Width() const override;
float Height() const override; float Height() const override;
uint GetTextureId() const override; uint GetTextureId() const override;
uint GetTextureId(uint id) const override;
void Update() override; void Update() override;
void Bind() override; void Bind() override;
@@ -27,4 +28,4 @@ namespace TSE::GLFW
void OnResize(float width, float height, IResizable* wnd) override; void OnResize(float width, float height, IResizable* wnd) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -3,14 +3,14 @@
#include "interfaces/IRenderTexture.hpp" #include "interfaces/IRenderTexture.hpp"
#include "RenderTexture.hpp" #include "RenderTexture.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class RenderTextureCreatorOpenGL : public IRenderTextureCreator class RenderTextureCreatorOpenGL : public IRenderTextureCreator
{ {
public: public:
inline IRenderTexture* CreateTextureHeap(Vector2 v) override inline IRenderTexture* CreateTextureHeap(Vector2 v, uint textureCount = 1) override
{ {
return new RenderTexture(v); return new RenderTexture(v, textureCount);
}; };
}; };
} // namespace name } // namespace OpenGL

View File

@@ -0,0 +1,165 @@
#include "GL/gl3w.h"
#include "GL/gl.h"
#include "TextureHelperOpenGL.hpp"
void TSE::OpenGL::TextureHelperOpenGL::Bind(const Texture *tex)
{
glBindTexture(GL_TEXTURE_2D, tex->GetTextureId());
}
void TSE::OpenGL::TextureHelperOpenGL::UnBind(const Texture *tex)
{
glBindTexture(GL_TEXTURE_2D, 0);
}
void TSE::OpenGL::TextureHelperOpenGL::Apply(Texture *tex)
{
glBindTexture(GL_TEXTURE_2D, tex->GetTextureId());
if(tex->Chanels() == 1)
{
if (tex->bpp() == 8)
glTexImage2D(GL_TEXTURE_2D, 0,GL_R8, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr());
if (tex->bpp() == 16)
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, tex->Width(), tex->Height(), 0, GL_RED, GL_SHORT, tex->GetImagePtr());
}
if(tex->Chanels() == 3)
{
if(tex->bpp() == 24)
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, tex->Width(), tex->Height(), 0, GL_BGR, GL_UNSIGNED_BYTE, tex->GetImagePtr());
}
else if(tex->Chanels() == 4)
{
if(tex->bpp() == 32)
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, tex->GetImagePtr());
if (tex->bpp() == 8) //need to decode it with bitwise operations in shader
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA2, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr());
}
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
void TSE::OpenGL::TextureHelperOpenGL::Regist(Texture *tex)
{
uint TextureID;
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
tex->SetTextureId(TextureID);
tex->Apply();
}
void TSE::OpenGL::TextureHelperOpenGL::PlatromDestroy(Texture *tex)
{
uint id = tex->GetTextureId();
glDeleteTextures(1, &id);
}
void TSE::OpenGL::TextureHelperOpenGL::Bind3D(const VolumeTexture3D *tex)
{
glBindTexture(GL_TEXTURE_3D, tex->GetTextureId());
}
void TSE::OpenGL::TextureHelperOpenGL::UnBind3D(const VolumeTexture3D *tex)
{
glBindTexture(GL_TEXTURE_3D, 0);
}
void TSE::OpenGL::TextureHelperOpenGL::Apply3D(VolumeTexture3D *tex)
{
glBindTexture(GL_TEXTURE_3D, tex->GetTextureId());
ushort internal,input,size;
if(tex->Chanels() == 1)
{
if (tex->bpp() == 8)
{
internal = GL_R8;
input = GL_RED;
size = GL_UNSIGNED_BYTE;
}
if (tex->bpp() == 16)
{
internal = GL_R16I;
input = GL_RED;
size = GL_SHORT;
}
}
if(tex->Chanels() == 3)
{
if(tex->bpp() == 24)
{
internal = GL_RGB;
input = GL_BGR;
size = GL_UNSIGNED_BYTE;
}
}
else if(tex->Chanels() == 4)
{
if(tex->bpp() == 32)
{
internal = GL_R16;
input = GL_BGRA;
size = GL_UNSIGNED_BYTE;
}
if (tex->bpp() == 8) //need to decode it with bitwise operations in shader
{
internal = GL_RGBA2;
input = GL_RED;
size = GL_UNSIGNED_BYTE;
}
}
glTexImage3D(GL_TEXTURE_3D, 0, internal, tex->Width(), tex->Height(), tex->Depth(), 0, input, size, nullptr);
for (int z = 0; z < tex->Depth(); ++z)
{
glTexSubImage3D(
GL_TEXTURE_3D,
0,
0,
0,
z,
tex->Width(),
tex->Height(),
1,
input,
size,
tex->GetImagePtr(z)
);
}
//glGenerateMipmap(GL_TEXTURE_3D);
glBindTexture(GL_TEXTURE_3D, 0);
}
void TSE::OpenGL::TextureHelperOpenGL::Regist3D(VolumeTexture3D *tex)
{
uint TextureID;
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_3D, TextureID);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
tex->SetTextureId(TextureID);
tex->Apply();
}
void TSE::OpenGL::TextureHelperOpenGL::PlatromDestroy3D(VolumeTexture3D *tex)
{
uint id = tex->GetTextureId();
glDeleteTextures(1, &id);
}

View File

@@ -2,8 +2,9 @@
#include "interfaces/ITextureHelper.hpp" #include "interfaces/ITextureHelper.hpp"
#include "elements/Texture.hpp" #include "elements/Texture.hpp"
#include "elements/VolumeTexture3D.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class TextureHelperOpenGL : public ITextureHelper class TextureHelperOpenGL : public ITextureHelper
{ {
@@ -13,5 +14,11 @@ namespace TSE::GLFW
void Apply(Texture* tex) override; void Apply(Texture* tex) override;
void Regist(Texture* tex) override; void Regist(Texture* tex) override;
void PlatromDestroy(Texture* tex) override; void PlatromDestroy(Texture* tex) override;
void Bind3D(const VolumeTexture3D* tex) override;
void UnBind3D(const VolumeTexture3D* tex) override;
void Apply3D(VolumeTexture3D* tex) override;
void Regist3D(VolumeTexture3D* tex) override;
void PlatromDestroy3D(VolumeTexture3D* tex) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -0,0 +1,119 @@
#include "FrameBuffer.hpp"
#include "Debug.hpp"
TSE::OpenGL::FrameBuffer::FrameBuffer(const Vector2 &size, uint textureCount)
{
textureOutputCount = textureCount;
width = size.x;
height = size.y;
CreateFBTexture();
for (auto const& i : objectsToResize)
{
i->OnResize(size.x, size.y, this);
}
Initialize();
}
void TSE::OpenGL::FrameBuffer::Bind()
{
glBindFramebuffer(GL_FRAMEBUFFER, bufferID);
}
void TSE::OpenGL::FrameBuffer::Unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
TSE::OpenGL::FrameBuffer::~FrameBuffer()
{
glDeleteFramebuffers(1,&bufferID);
for (int i = 0; i < textureOutputCount; i++)
{
glDeleteTextures(1, &(textureIDs[i]));
}
glDeleteRenderbuffers(1, &depthRboID);
}
void TSE::OpenGL::FrameBuffer::Resize(Vector2 size)
{
width = size.x;
height = size.y;
shouldResize = true;
}
void TSE::OpenGL::FrameBuffer::Update()
{
if (!shouldResize) return;
shouldResize = false;
CreateFBTexture();
for (auto const& i : objectsToResize)
{
i->OnResize(width, height, this);
}
}
TSE::uint TSE::OpenGL::FrameBuffer::GetTextureId(uint id) const
{
return textureIDs[id];
}
TSE::Vector2 TSE::OpenGL::FrameBuffer::GetSize() const
{
return {width, height};
}
void TSE::OpenGL::FrameBuffer::Initialize()
{
glGenFramebuffers(1, &bufferID);
Bind();
uint bufs[32];
for (int i = 0; i < textureOutputCount; i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textureIDs[i], 0);
bufs[i] = GL_COLOR_ATTACHMENT0 + i;
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRboID);
if(textureOutputCount > 1)
glDrawBuffers(textureOutputCount, bufs);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
TSE_ERROR("Failed to create OpenGL FBO.");
TSE_LOG(std::to_string(glGetError()));
}
Unbind();
}
void TSE::OpenGL::FrameBuffer::LoadFBTexture()
{
for (int i = 0; i < textureOutputCount; i++)
{
glBindTexture(GL_TEXTURE_2D, textureIDs[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glBindRenderbuffer(GL_RENDERBUFFER, depthRboID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
}
}
void TSE::OpenGL::FrameBuffer::CreateFBTexture()
{
glViewport(0,0, width, height);
//resize
for (int i = 0; i < textureOutputCount; i++)
{
if(textureIDs[i] == 0)
glGenTextures(1, &(textureIDs[i]));
}
if(depthRboID == 0)
glGenRenderbuffers(1, &depthRboID);
LoadFBTexture();
}

View File

@@ -4,23 +4,24 @@
#include "interfaces/IResizable.hpp" #include "interfaces/IResizable.hpp"
#include "Vector2.hpp" #include "Vector2.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class FrameBuffer : public buffer, public IResizable class FrameBuffer : public buffer, public IResizable
{ {
private: private:
uint textureID = 0; uint textureOutputCount = 1;
uint textureIDs[32] = {0};
uint depthRboID = 0; uint depthRboID = 0;
bool shouldResize = false; bool shouldResize = false;
public: public:
FrameBuffer(const Vector2& size); FrameBuffer(const Vector2& size, uint textureCount = 1);
void Bind() override; void Bind() override;
void Unbind() override; void Unbind() override;
~FrameBuffer() override; ~FrameBuffer() override;
void Resize(Vector2 size); void Resize(Vector2 size);
void Update(); void Update();
uint GetTextureId() const; uint GetTextureId(uint id = 0) const;
Vector2 GetSize() const; Vector2 GetSize() const;
private: private:

View File

@@ -1,24 +1,24 @@
#include "IndexBuffer.hpp" #include "IndexBuffer.hpp"
TSE::GLFW::IndexBuffer::IndexBuffer(ushort *data, ushort count) TSE::OpenGL::IndexBuffer::IndexBuffer(ushort *data, ushort count)
{ {
glGenBuffers(1, &bufferID); glGenBuffers(1, &bufferID);
WriteData(data, count); WriteData(data, count);
} }
void TSE::GLFW::IndexBuffer::WriteData(ushort *data, ushort count) void TSE::OpenGL::IndexBuffer::WriteData(ushort *data, ushort count)
{ {
Bind(); Bind();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort) * count, data, GL_DYNAMIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort) * count, data, GL_DYNAMIC_DRAW);
Unbind(); Unbind();
} }
void TSE::GLFW::IndexBuffer::Bind() void TSE::OpenGL::IndexBuffer::Bind()
{ {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferID);
} }
void TSE::GLFW::IndexBuffer::Unbind() void TSE::OpenGL::IndexBuffer::Unbind()
{ {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }

View File

@@ -3,7 +3,7 @@
#include "buffer.hpp" #include "buffer.hpp"
#include "Types.hpp" #include "Types.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class IndexBuffer : public buffer class IndexBuffer : public buffer
{ {

View File

@@ -1,35 +1,35 @@
#include "VertexBuffer.hpp" #include "VertexBuffer.hpp"
TSE::uint TSE::GLFW::VertexBuffer::boundBuffer = 0; TSE::uint TSE::OpenGL::VertexBuffer::boundBuffer = 0;
TSE::GLFW::VertexBuffer::VertexBuffer() TSE::OpenGL::VertexBuffer::VertexBuffer()
{ {
glGenBuffers(1, &bufferID); glGenBuffers(1, &bufferID);
} }
void TSE::GLFW::VertexBuffer::SetData(int size, void *buffer, GLenum usage) void TSE::OpenGL::VertexBuffer::SetData(int size, void *buffer, GLenum usage)
{ {
glBufferData(GL_ARRAY_BUFFER, size, buffer, usage); glBufferData(GL_ARRAY_BUFFER, size, buffer, usage);
} }
void TSE::GLFW::VertexBuffer::Bind() void TSE::OpenGL::VertexBuffer::Bind()
{ {
glBindBuffer(GL_ARRAY_BUFFER, bufferID); glBindBuffer(GL_ARRAY_BUFFER, bufferID);
boundBuffer = bufferID; boundBuffer = bufferID;
} }
void TSE::GLFW::VertexBuffer::Unbind() void TSE::OpenGL::VertexBuffer::Unbind()
{ {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
boundBuffer = 0; boundBuffer = 0;
} }
bool TSE::GLFW::VertexBuffer::IsBound() bool TSE::OpenGL::VertexBuffer::IsBound()
{ {
return boundBuffer == bufferID; return boundBuffer == bufferID;
} }
TSE::GLFW::VertexBuffer::~VertexBuffer() TSE::OpenGL::VertexBuffer::~VertexBuffer()
{ {
if(bufferID != 0) if(bufferID != 0)
{ {

View File

@@ -2,7 +2,7 @@
#include "buffer.hpp" #include "buffer.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class VertexBuffer : public buffer class VertexBuffer : public buffer
{ {

View File

@@ -4,7 +4,7 @@
#include "GL/gl.h" #include "GL/gl.h"
#include "Types.hpp" #include "Types.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class buffer class buffer
{ {

View File

@@ -3,58 +3,63 @@
#include "Shader.hpp" #include "Shader.hpp"
#include "Debug.hpp" #include "Debug.hpp"
TSE::uint TSE::GLFW::Shader::activeProgramID = 0; TSE::uint TSE::OpenGL::Shader::activeProgramID = 0;
void TSE::GLFW::Shader::Bind() const void TSE::OpenGL::Shader::Bind() const
{ {
Enable(true); Enable(true);
} }
void TSE::GLFW::Shader::Unbind() const void TSE::OpenGL::Shader::Unbind() const
{ {
Disable(true); Disable(true);
} }
void TSE::GLFW::Shader::Enable(bool notify) const void TSE::OpenGL::Shader::Enable(bool notify) const
{ {
activeProgramID = programID; activeProgramID = programID;
glUseProgram(programID); glUseProgram(programID);
if(notify) OnEnable(); if(notify) OnEnable();
} }
void TSE::GLFW::Shader::Disable(bool notify) const void TSE::OpenGL::Shader::Disable(bool notify) const
{ {
activeProgramID = 0; activeProgramID = 0;
glUseProgram(0); glUseProgram(0);
if(notify) OnDisable(); if(notify) OnDisable();
} }
void TSE::GLFW::Shader::Flush() void TSE::OpenGL::Shader::Flush()
{ {
OnFlush(); OnFlush();
} }
void TSE::GLFW::Shader::DrawCall(int indexCount) void TSE::OpenGL::Shader::DrawCall(int indexCount)
{ {
OnDrawCall(indexCount); OnDrawCall(indexCount);
} }
void TSE::GLFW::Shader::Submit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) void TSE::OpenGL::Shader::PostDraw()
{
OnPostDraw();
}
void TSE::OpenGL::Shader::Submit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{ {
OnSubmit(t, target, stack, restartDrawcall, rnd); OnSubmit(t, target, stack, restartDrawcall, rnd);
} }
bool TSE::GLFW::Shader::IsEnabled() const bool TSE::OpenGL::Shader::IsEnabled() const
{ {
return programID == activeProgramID; return programID == activeProgramID;
} }
int TSE::GLFW::Shader::packageSize() int TSE::OpenGL::Shader::packageSize()
{ {
return PackageSize; return PackageSize;
} }
TSE::GLFW::Shader::Shader(const std::vector<std::unique_ptr<ShaderPart>> &parts) TSE::OpenGL::Shader::Shader(const std::vector<std::unique_ptr<ShaderPart>> &parts)
{ {
programID = glCreateProgram(); programID = glCreateProgram();
@@ -80,12 +85,12 @@ TSE::GLFW::Shader::Shader(const std::vector<std::unique_ptr<ShaderPart>> &parts)
} }
} }
TSE::GLFW::Shader::~Shader() TSE::OpenGL::Shader::~Shader()
{ {
glDeleteProgram(programID); glDeleteProgram(programID);
} }
int TSE::GLFW::Shader::GetUniformLocation(const char *name) int TSE::OpenGL::Shader::GetUniformLocation(const char *name)
{ {
auto it = uniformLocations.find(name); auto it = uniformLocations.find(name);
if (it != uniformLocations.end()) return it->second; if (it != uniformLocations.end()) return it->second;
@@ -95,44 +100,44 @@ int TSE::GLFW::Shader::GetUniformLocation(const char *name)
return loc; return loc;
} }
void TSE::GLFW::Shader::SetUniform(const char *name, int value) void TSE::OpenGL::Shader::SetUniform(const char *name, int value)
{ {
glUniform1i(GetUniformLocation(name), value); glUniform1i(GetUniformLocation(name), value);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, const int *value, const int count) void TSE::OpenGL::Shader::SetUniform(const char *name, const int *value, const int count)
{ {
glUniform1iv(GetUniformLocation(name), count, value); glUniform1iv(GetUniformLocation(name), count, value);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, const Matrix4x4 *value) void TSE::OpenGL::Shader::SetUniform(const char *name, const Matrix4x4 *value)
{ {
float colmbMajor[16]; float colmbMajor[16];
value->ToArrayColumnMajor(colmbMajor); value->ToArrayColumnMajor(colmbMajor);
glUniformMatrix4fv(GetUniformLocation(name),1, false, colmbMajor); glUniformMatrix4fv(GetUniformLocation(name),1, false, colmbMajor);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, float value) void TSE::OpenGL::Shader::SetUniform(const char *name, float value)
{ {
glUniform1f(GetUniformLocation(name), value); glUniform1f(GetUniformLocation(name), value);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, const float *value, const int count) void TSE::OpenGL::Shader::SetUniform(const char *name, const float *value, const int count)
{ {
glUniform1fv(GetUniformLocation(name), count, value); glUniform1fv(GetUniformLocation(name), count, value);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, const Vector2 *value) void TSE::OpenGL::Shader::SetUniform(const char *name, const Vector2 *value)
{ {
glUniform2f(GetUniformLocation(name), value->x, value->y); glUniform2f(GetUniformLocation(name), value->x, value->y);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, const Vector3 *value) void TSE::OpenGL::Shader::SetUniform(const char *name, const Vector3 *value)
{ {
glUniform3f(GetUniformLocation(name), value->x, value->y, value->z); glUniform3f(GetUniformLocation(name), value->x, value->y, value->z);
} }
void TSE::GLFW::Shader::SetUniform(const char *name, const Vector4 *value) void TSE::OpenGL::Shader::SetUniform(const char *name, const Vector4 *value)
{ {
glUniform4f(GetUniformLocation(name), value->x, value->y, value->z, value->w); glUniform4f(GetUniformLocation(name), value->x, value->y, value->z, value->w);
} }

View File

@@ -9,7 +9,7 @@
#include "TransformationStack.hpp" #include "TransformationStack.hpp"
#include "interfaces/IRenderer.hpp" #include "interfaces/IRenderer.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class Shader : public IShader class Shader : public IShader
{ {
@@ -24,6 +24,7 @@ namespace TSE::GLFW
virtual void OnDisable() const {}; virtual void OnDisable() const {};
virtual void OnFlush() {}; virtual void OnFlush() {};
virtual void OnDrawCall(int indexCount) {}; virtual void OnDrawCall(int indexCount) {};
virtual void OnPostDraw() {};
virtual void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) {}; virtual void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) {};
public: public:
@@ -33,6 +34,7 @@ namespace TSE::GLFW
void Disable(bool notify = false) const; void Disable(bool notify = false) const;
void Flush(); void Flush();
void DrawCall(int indexCount); void DrawCall(int indexCount);
void PostDraw();
void Submit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd); void Submit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd);
bool IsEnabled() const; bool IsEnabled() const;
int packageSize(); int packageSize();
@@ -52,4 +54,4 @@ namespace TSE::GLFW
void SetUniform(const char* name, const Vector3* value) override; void SetUniform(const char* name, const Vector3* value) override;
void SetUniform(const char* name, const Vector4* value) override; void SetUniform(const char* name, const Vector4* value) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -6,7 +6,7 @@
#include <fstream> #include <fstream>
#include "PathHelper.hpp" #include "PathHelper.hpp"
void TSE::GLFW::ShaderPart::Init(const string &str, int shaderType) void TSE::OpenGL::ShaderPart::Init(const string &str, int shaderType)
{ {
shaderPartID = glCreateShader(shaderType); shaderPartID = glCreateShader(shaderType);
const char * cstr = str.c_str(); const char * cstr = str.c_str();
@@ -27,12 +27,12 @@ void TSE::GLFW::ShaderPart::Init(const string &str, int shaderType)
} }
} }
TSE::GLFW::ShaderPart::~ShaderPart() TSE::OpenGL::ShaderPart::~ShaderPart()
{ {
glDeleteShader(shaderPartID); glDeleteShader(shaderPartID);
} }
std::unique_ptr<TSE::GLFW::ShaderPart> TSE::GLFW::ShaderPart::LoadFromString(const std::string &str, int shaderType) std::unique_ptr<TSE::OpenGL::ShaderPart> TSE::OpenGL::ShaderPart::LoadFromString(const std::string &str, int shaderType)
{ {
if (str.length() == 0) throw; if (str.length() == 0) throw;
std::unique_ptr<ShaderPart> shader = std::make_unique<ShaderPart>(); std::unique_ptr<ShaderPart> shader = std::make_unique<ShaderPart>();
@@ -40,7 +40,7 @@ std::unique_ptr<TSE::GLFW::ShaderPart> TSE::GLFW::ShaderPart::LoadFromString(con
return shader; return shader;
} }
std::unique_ptr<TSE::GLFW::ShaderPart> TSE::GLFW::ShaderPart::LoadFromPath(const std::string &path, int shaderType) std::unique_ptr<TSE::OpenGL::ShaderPart> TSE::OpenGL::ShaderPart::LoadFromPath(const std::string &path, int shaderType)
{ {
std::ifstream stream; std::ifstream stream;
OpenFileReading(stream, path); OpenFileReading(stream, path);

View File

@@ -3,7 +3,7 @@
#include "Types.hpp" #include "Types.hpp"
#include <memory> #include <memory>
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class ShaderPart class ShaderPart
{ {
@@ -20,4 +20,4 @@ namespace TSE::GLFW
static std::unique_ptr<ShaderPart> LoadFromString(const std::string& str, int shaderType); static std::unique_ptr<ShaderPart> LoadFromString(const std::string& str, int shaderType);
static std::unique_ptr<ShaderPart> LoadFromPath(const std::string& path, int shaderType); static std::unique_ptr<ShaderPart> LoadFromPath(const std::string& path, int shaderType);
}; };
} // namespace TSE } // namespace OpenGL

View File

@@ -0,0 +1,238 @@
#include "basicOrderedSpriteSetShader.hpp"
#include "BehaviourScripts/Renderable.hpp"
#include "BehaviourScripts/OrdererSpriteSet.hpp"
#include "Color.hpp"
#include "basicOrderedSpriteSetShaderGLSL.hpp"
using namespace TSE;
using namespace TSE::OpenGL;
#define SHADER_MESH_INDEX 0
#define SHADER_POS_INDEX 1
#define SHADER_LAYER_HEIGHT_INDEX 2
#define SHADER_SPRITE_INDEX 3
#define SHADER_NORMAL_INDEX 4
#define SHADER_SCALE_INDEX 5
#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1 + 1 + 1 + 2)
TSE::OpenGL::BasicOrderedSpriteSetShader* BasicOrderedSpriteSetShader::instance = nullptr;
TSE::OpenGL::BasicOrderedSpriteSetShader *TSE::OpenGL::BasicOrderedSpriteSetShader::Instance()
{
return instance;
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::Destroy()
{
if(instance != nullptr)
delete instance;
instance = nullptr;
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::Init(float width, float height)
{
std::vector<std::unique_ptr<ShaderPart>> parts;
parts.push_back(ShaderPart::LoadFromString(vertOrderedSet, GL_VERTEX_SHADER));
parts.push_back(ShaderPart::LoadFromString(fragOrderedSet, GL_FRAGMENT_SHADER));
instance = new BasicOrderedSpriteSetShader(std::move(parts));
instance->Enable();
int texIDs[] = { 0 };
instance->SetUniform("atlas", 0);
instance->Disable();
}
TSE::OpenGL::BasicOrderedSpriteSetShader::BasicOrderedSpriteSetShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts)
{
PackageSize = SHADER_PACKAGE_SIZE;
}
TSE::OpenGL::BasicOrderedSpriteSetShader::~BasicOrderedSpriteSetShader()
{
if (meshVBO) glDeleteBuffers(1, &meshVBO);
if (meshIBO) glDeleteBuffers(1, &meshIBO);
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::SetMesh(const void *verts, int vertCount, int stride, int floatCountPerVertex, int posOffsetBytes, GLenum primitive, const void *indices, int indexCount, GLenum indexType)
{
GLint prevVAO = 0, prevArrayBuffer = 0, prevElementBuffer = 0;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevArrayBuffer);
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevElementBuffer);
if (!meshVBO) glGenBuffers(1, &meshVBO);
glBindBuffer(GL_ARRAY_BUFFER, meshVBO);
glBufferData(GL_ARRAY_BUFFER, vertCount * stride, verts, GL_STATIC_DRAW);
if (indices && indexCount > 0)
{
if (!meshIBO) glGenBuffers(1, &meshIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshIBO);
GLsizeiptr idxSize =
(indexType == GL_UNSIGNED_INT ? 4 :
indexType == GL_UNSIGNED_SHORT? 2 : 1) * indexCount;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, idxSize, indices, GL_STATIC_DRAW);
meshIndexCount = indexCount;
meshIndexType = indexType;
}
else
{
// Kein Index-Buffer
if (meshIBO) { glDeleteBuffers(1, &meshIBO); meshIBO = 0; }
meshIndexCount = 0;
}
meshVertexCount = vertCount;
meshStride = stride;
meshPosOffset = posOffsetBytes;
meshPosSize = floatCountPerVertex;
meshPrimitive = primitive;
meshReady = true;
glBindBuffer(GL_ARRAY_BUFFER, prevArrayBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevElementBuffer);
glBindVertexArray(prevVAO);
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::OnEnable() const
{
if (!meshReady)
{
// Fallback: unit-Quad als TRIANGLE_FAN (4 Vertices, 2D Positionen)
const float quad[8] = { -0.5f,0, 0.5f,0, 0.5f,1, -0.5f,1 };
const_cast<BasicOrderedSpriteSetShader*>(this)->SetMesh(
quad, 4, sizeof(float)*2, 2, 0, GL_TRIANGLE_FAN
);
}
GLint prevArrayBuffer = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevArrayBuffer);
glBindBuffer(GL_ARRAY_BUFFER, meshVBO);
glEnableVertexAttribArray(SHADER_MESH_INDEX); // LOC_QUAD/pos
glVertexAttribPointer(SHADER_MESH_INDEX, meshPosSize, GL_FLOAT, GL_FALSE, meshStride, (void*)meshPosOffset);
glVertexAttribDivisor(SHADER_MESH_INDEX, 0); // per-vertex (Mesh)
glBindBuffer(GL_ARRAY_BUFFER, prevArrayBuffer);
glEnableVertexAttribArray(SHADER_POS_INDEX);
glVertexAttribPointer(SHADER_POS_INDEX, 3, GL_FLOAT, GL_FALSE, PackageSize, (void*)0);
glVertexAttribDivisor(SHADER_POS_INDEX, 1);
glEnableVertexAttribArray(SHADER_LAYER_HEIGHT_INDEX);
glVertexAttribPointer(SHADER_LAYER_HEIGHT_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*3));
glVertexAttribDivisor(SHADER_LAYER_HEIGHT_INDEX, 1);
glEnableVertexAttribArray(SHADER_SPRITE_INDEX);
glVertexAttribPointer(SHADER_SPRITE_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*4));
glVertexAttribDivisor(SHADER_SPRITE_INDEX, 1);
glEnableVertexAttribArray(SHADER_NORMAL_INDEX);
glVertexAttribPointer(SHADER_NORMAL_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*5));
glVertexAttribDivisor(SHADER_NORMAL_INDEX, 1);
glEnableVertexAttribArray(SHADER_SCALE_INDEX);
glVertexAttribPointer(SHADER_SCALE_INDEX, 2, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*6));
glVertexAttribDivisor(SHADER_SCALE_INDEX, 1);
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::OnDisable() const
{
glDisableVertexAttribArray(SHADER_MESH_INDEX);
glDisableVertexAttribArray(SHADER_POS_INDEX);
glDisableVertexAttribArray(SHADER_LAYER_HEIGHT_INDEX);
glDisableVertexAttribArray(SHADER_SPRITE_INDEX);
glDisableVertexAttribArray(SHADER_NORMAL_INDEX);
glDisableVertexAttribArray(SHADER_SCALE_INDEX);
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::OnFlush()
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TextureID);
glDisable(GL_BLEND);
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::OnDrawCall(int indexCount)
{
if (instanceCount <= 0) return;
SetUniform("spriteCount", &SpriteCount);
GLint prevElementBuffer = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevElementBuffer);
if (meshIBO && meshIndexCount > 0)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshIBO);
glDrawElementsInstanced(meshPrimitive, meshIndexCount, meshIndexType, (void*)0, instanceCount);
}
else
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDrawArraysInstanced(meshPrimitive, 0, meshVertexCount, instanceCount);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)prevElementBuffer);
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::OnPostDraw()
{
glEnable(GL_BLEND);
instanceCount = 0;
}
void TSE::OpenGL::BasicOrderedSpriteSetShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
if (!r) return;
auto* tm = dynamic_cast<OrdererSpriteSet*>(t.GetBehaviourScript(ORDERERSPRITESET));
if (!tm) return;
auto tileSet = tm->GetTileSet();
TextureID = tileSet->GetTextueID();
SpriteCount = tileSet->GetCount();
const std::vector<Vector2> orderedChunks = *tm->GetChunkPositionsInOrder();
Matrix4x4 matr = t.GetLocalMatrix();
stack.Push(matr);
for(auto chunkPos : orderedChunks)
{
auto chunk = tm->GetChunk(chunkPos);
const int spriteCount = chunk->GetSpriteCount();
const std::vector<Vector3> spritePositions = *chunk->GetOrderedPositions();
const std::vector<Vector2i> spriteIds = *chunk->GetOrderedSpriteIds();
const std::vector<Vector2> spriteScales = *chunk->GetOrderedScales();
int chunkSize = chunk->GetChunksize();
for (int i = 0; i < spriteCount; i++)
{
Matrix4x4 mat = Matrix4x4::ToTranslationMatrix(chunkPos + spritePositions[i].ToVector2()) * Matrix4x4::ToRotationMatrix(Quaternion()) * Matrix4x4::ToScaleMatrix({1,1,1});
stack.Push(mat);
Vector3 pos = stack.Top() * Vector3(0,0,0);
*target++ = pos.x;
*target++ = pos.y;
*target++ = pos.z;
*target++ = spritePositions[i].z;
*target++ = spriteIds[i].x;
*target++ = spriteIds[i].y;
*target++ = spriteScales[i].x;
*target++ = spriteScales[i].y;
++instanceCount;
stack.Pop();
if(instanceCount >= 16000)
restartDrawcall(rnd);
}
}
stack.Pop();
restartDrawcall(rnd);
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "GL/gl3w.h"
#include "GL/gl.h"
#include "Shader.hpp"
#include "Types.hpp"
namespace TSE::OpenGL
{
class BasicOrderedSpriteSetShader : public Shader
{
private:
static BasicOrderedSpriteSetShader* instance;
mutable bool meshReady = false;
GLuint meshVBO = 0;
GLuint meshIBO = 0;
GLsizei meshVertexCount = 0; // für DrawArraysInstanced
GLsizei meshIndexCount = 0; // für DrawElementsInstanced
GLenum meshPrimitive = GL_TRIANGLES;
GLenum meshIndexType = GL_UNSIGNED_SHORT;
int instanceCount = 0; // eigener Instanzzähler
GLint meshPosSize = 2; // 2D (Billboard-Formen), für 3D Meshes: 3
GLsizei meshStride = sizeof(float) * 2;
size_t meshPosOffset = 0;
GLuint TextureID;
Vector2 SpriteCount;
public:
static BasicOrderedSpriteSetShader* Instance();
static void Destroy();
static void Init(float width, float height);
BasicOrderedSpriteSetShader(std::vector<std::unique_ptr<ShaderPart>>&& parts);
~BasicOrderedSpriteSetShader();
void SetMesh(const void* verts, int vertCount, int stride, int floatCountPerVertex, int posOffsetBytes, GLenum primitive, const void* indices = nullptr, int indexCount = 0, GLenum indexType = GL_UNSIGNED_SHORT);
protected:
void OnEnable() const override;
void OnDisable() const override;
void OnFlush() override;
void OnDrawCall(int indexCount) override;
void OnPostDraw() override;
void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override;
};
} // namespace TSE::GLFW

View File

@@ -0,0 +1,95 @@
#pragma once
inline const char* vertOrderedSet = R"(
#version 330 core
layout(location = 0) in vec2 aPos;
layout(location = 1) in vec3 iTilePos;
layout(location = 2) in float height;
layout(location = 3) in float iSpriteId;
layout(location = 4) in float iNormalId;
layout(location = 5) in vec2 spriteScale;
uniform mat4 prMatrix;
uniform mat4 camMatrix;
out vec2 vUV;
flat out int vSpriteId;
flat out int vNormalId;
flat out float vTileNdcY;
flat out float layerHeight;
void main()
{
vec3 local = vec3(aPos.x, aPos.y, 0);
vec2 baseUV = aPos + vec2(0.5, 0);
vec3 tileSize = vec3(spriteScale.x, spriteScale.y, 1);
vec3 worldPos = (iTilePos * tileSize) + (local * tileSize);
vec4 clip = prMatrix * camMatrix * vec4(worldPos, 1.0);
gl_Position = clip;
vUV = baseUV;
vSpriteId = int(iSpriteId + 0.5);
vNormalId = int(iNormalId + 0.5);
layerHeight = height;
vec3 localbottom = vec3(0.5, 0, 0);
vec3 worldPosBottom = (iTilePos * tileSize) + (localbottom * tileSize);
vec4 clipbottom = prMatrix * camMatrix * vec4(worldPosBottom, 1.0);
float ndcY = clipbottom.y / clipbottom.w;
vTileNdcY = ndcY * 0.5 + 0.5;
}
)";
inline const char* fragOrderedSet = R"(
#version 330 core
in vec2 vUV;
flat in int vSpriteId;
flat in int vNormalId;
flat in float vTileNdcY;
flat in float layerHeight;
uniform sampler2D atlas;
uniform vec2 spriteCount;
layout(location = 0) out vec4 FragColor;
layout(location = 1) out vec4 FragHeight;
layout(location = 2) out vec4 FragDepth;
void main()
{
float t = (vTileNdcY + 1.0) * 0.5 *0.8;
FragDepth = vec4(t, 0, 0, 1.0);
vec2 tileUVSize = 1.0 / spriteCount;
int cols = int(spriteCount.x);
int sx = vSpriteId % cols;
int sy = vSpriteId / cols;
vec2 atlasOffset = vec2(float(sx), float(sy)) * tileUVSize;
vec2 atlasUV = atlasOffset + (vUV * tileUVSize);
vec4 c = texture(atlas, atlasUV);
if (c.a < 0.01) discard;
float colorScaler = 1 - ((layerHeight - 1) * -1) * 0.3;
c = vec4(c.x * colorScaler,c.y * colorScaler,c.z * colorScaler,c.w);
FragColor = c;
if(vNormalId != -1)
{
int sx2 = vNormalId % cols;
int sy2 = vNormalId / cols;
vec2 atlasOffsetNormal = vec2(float(sx2), float(sy2)) * tileUVSize;
vec2 atlasUVNormal = atlasOffsetNormal + (vUV * tileUVSize);
vec4 cNormal = texture(atlas, atlasUVNormal);
cNormal.w = layerHeight;
FragHeight = cNormal;
}
}
)";

View File

@@ -12,21 +12,21 @@
#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1 + 1 + 4) #define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1 + 1 + 4)
TSE::GLFW::BasicParticleShader* TSE::GLFW::BasicParticleShader::instance = nullptr; TSE::OpenGL::BasicParticleShader* TSE::OpenGL::BasicParticleShader::instance = nullptr;
TSE::GLFW::BasicParticleShader *TSE::GLFW::BasicParticleShader::Instance() TSE::OpenGL::BasicParticleShader *TSE::OpenGL::BasicParticleShader::Instance()
{ {
return instance; return instance;
} }
void TSE::GLFW::BasicParticleShader::Destroy() void TSE::OpenGL::BasicParticleShader::Destroy()
{ {
if(instance != nullptr) if(instance != nullptr)
delete instance; delete instance;
instance = nullptr; instance = nullptr;
} }
void TSE::GLFW::BasicParticleShader::Init(float width, float height) void TSE::OpenGL::BasicParticleShader::Init(float width, float height)
{ {
std::vector<std::unique_ptr<ShaderPart>> parts; std::vector<std::unique_ptr<ShaderPart>> parts;
parts.push_back(ShaderPart::LoadFromString(vertPart, GL_VERTEX_SHADER)); parts.push_back(ShaderPart::LoadFromString(vertPart, GL_VERTEX_SHADER));
@@ -34,18 +34,18 @@ void TSE::GLFW::BasicParticleShader::Init(float width, float height)
instance = new BasicParticleShader(std::move(parts)); instance = new BasicParticleShader(std::move(parts));
} }
TSE::GLFW::BasicParticleShader::BasicParticleShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts) TSE::OpenGL::BasicParticleShader::BasicParticleShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts)
{ {
PackageSize = SHADER_PACKAGE_SIZE; PackageSize = SHADER_PACKAGE_SIZE;
} }
TSE::GLFW::BasicParticleShader::~BasicParticleShader() TSE::OpenGL::BasicParticleShader::~BasicParticleShader()
{ {
if (meshVBO) glDeleteBuffers(1, &meshVBO); if (meshVBO) glDeleteBuffers(1, &meshVBO);
if (meshIBO) glDeleteBuffers(1, &meshIBO); if (meshIBO) glDeleteBuffers(1, &meshIBO);
} }
void TSE::GLFW::BasicParticleShader::SetMesh(const void *verts, int vertCount, int stride, int floatCountPerVertex, int posOffsetBytes, GLenum primitive, const void *indices, int indexCount, GLenum indexType) void TSE::OpenGL::BasicParticleShader::SetMesh(const void *verts, int vertCount, int stride, int floatCountPerVertex, int posOffsetBytes, GLenum primitive, const void *indices, int indexCount, GLenum indexType)
{ {
GLint prevVAO = 0, prevArrayBuffer = 0, prevElementBuffer = 0; GLint prevVAO = 0, prevArrayBuffer = 0, prevElementBuffer = 0;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO);
@@ -86,7 +86,7 @@ void TSE::GLFW::BasicParticleShader::SetMesh(const void *verts, int vertCount, i
glBindVertexArray(prevVAO); glBindVertexArray(prevVAO);
} }
void TSE::GLFW::BasicParticleShader::OnEnable() const void TSE::OpenGL::BasicParticleShader::OnEnable() const
{ {
if (!meshReady) if (!meshReady)
{ {
@@ -128,7 +128,7 @@ void TSE::GLFW::BasicParticleShader::OnEnable() const
glVertexAttribDivisor(SHADER_COLOR_INDEX, 1); glVertexAttribDivisor(SHADER_COLOR_INDEX, 1);
} }
void TSE::GLFW::BasicParticleShader::OnDisable() const void TSE::OpenGL::BasicParticleShader::OnDisable() const
{ {
glDisableVertexAttribArray(SHADER_MESH_INDEX); glDisableVertexAttribArray(SHADER_MESH_INDEX);
glDisableVertexAttribArray(SHADER_POS_INDEX); glDisableVertexAttribArray(SHADER_POS_INDEX);
@@ -137,11 +137,11 @@ void TSE::GLFW::BasicParticleShader::OnDisable() const
glDisableVertexAttribArray(SHADER_COLOR_INDEX); glDisableVertexAttribArray(SHADER_COLOR_INDEX);
} }
void TSE::GLFW::BasicParticleShader::OnFlush() void TSE::OpenGL::BasicParticleShader::OnFlush()
{ {
} }
void TSE::GLFW::BasicParticleShader::OnDrawCall(int indexCount) void TSE::OpenGL::BasicParticleShader::OnDrawCall(int indexCount)
{ {
if (instanceCount <= 0) return; if (instanceCount <= 0) return;
@@ -163,7 +163,7 @@ void TSE::GLFW::BasicParticleShader::OnDrawCall(int indexCount)
instanceCount = 0; instanceCount = 0;
} }
void TSE::GLFW::BasicParticleShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) void TSE::OpenGL::BasicParticleShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{ {
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE)); auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
if (!r) return; if (!r) return;

View File

@@ -5,7 +5,7 @@
#include "Shader.hpp" #include "Shader.hpp"
#include "Types.hpp" #include "Types.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class BasicParticleShader : public Shader class BasicParticleShader : public Shader
{ {

View File

@@ -11,21 +11,21 @@
#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 4) #define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 4)
TSE::GLFW::BasicShader* TSE::GLFW::BasicShader::instance = nullptr; TSE::OpenGL::BasicShader* TSE::OpenGL::BasicShader::instance = nullptr;
TSE::GLFW::BasicShader *TSE::GLFW::BasicShader::Instance() TSE::OpenGL::BasicShader *TSE::OpenGL::BasicShader::Instance()
{ {
return instance; return instance;
} }
void TSE::GLFW::BasicShader::Destroy() void TSE::OpenGL::BasicShader::Destroy()
{ {
if(instance != nullptr) if(instance != nullptr)
delete instance; delete instance;
instance = nullptr; instance = nullptr;
} }
void TSE::GLFW::BasicShader::Init(float width, float height) void TSE::OpenGL::BasicShader::Init(float width, float height)
{ {
std::vector<std::unique_ptr<ShaderPart>> parts; std::vector<std::unique_ptr<ShaderPart>> parts;
parts.push_back(ShaderPart::LoadFromString(vert, GL_VERTEX_SHADER)); parts.push_back(ShaderPart::LoadFromString(vert, GL_VERTEX_SHADER));
@@ -33,12 +33,12 @@ void TSE::GLFW::BasicShader::Init(float width, float height)
instance = new BasicShader(std::move(parts)); instance = new BasicShader(std::move(parts));
} }
TSE::GLFW::BasicShader::BasicShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts) TSE::OpenGL::BasicShader::BasicShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts)
{ {
PackageSize = SHADER_PACKAGE_SIZE; PackageSize = SHADER_PACKAGE_SIZE;
} }
void TSE::GLFW::BasicShader::OnEnable() const void TSE::OpenGL::BasicShader::OnEnable() const
{ {
glEnableVertexAttribArray(SHADER_VERTEX_INDEX); glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0); glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0);
@@ -46,22 +46,22 @@ void TSE::GLFW::BasicShader::OnEnable() const
glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3)); glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3));
} }
void TSE::GLFW::BasicShader::OnDisable() const void TSE::OpenGL::BasicShader::OnDisable() const
{ {
glDisableVertexAttribArray(SHADER_VERTEX_INDEX); glDisableVertexAttribArray(SHADER_VERTEX_INDEX);
glDisableVertexAttribArray(SHADER_COLOR_INDEX); glDisableVertexAttribArray(SHADER_COLOR_INDEX);
} }
void TSE::GLFW::BasicShader::OnFlush() void TSE::OpenGL::BasicShader::OnFlush()
{ {
} }
void TSE::GLFW::BasicShader::OnDrawCall(int indexCount) void TSE::OpenGL::BasicShader::OnDrawCall(int indexCount)
{ {
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL);
} }
void TSE::GLFW::BasicShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) void TSE::OpenGL::BasicShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{ {
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE)); auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
if (!r) return; if (!r) return;

View File

@@ -2,7 +2,7 @@
#include "Shader.hpp" #include "Shader.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class BasicShader : public Shader class BasicShader : public Shader
{ {
@@ -22,4 +22,4 @@ namespace TSE::GLFW
void OnDrawCall(int indexCount) override; void OnDrawCall(int indexCount) override;
void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override; void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -13,22 +13,22 @@
#define SHADER_PACKAGE_SIZE (sizeof(float) * (3 + 4 + 2 + 1)) #define SHADER_PACKAGE_SIZE (sizeof(float) * (3 + 4 + 2 + 1))
TSE::GLFW::BasicTextureShader* TSE::GLFW::BasicTextureShader::instance = nullptr; TSE::OpenGL::BasicTextureShader* TSE::OpenGL::BasicTextureShader::instance = nullptr;
std::map<TSE::uint, float> TSE::GLFW::BasicTextureShader::textureSlots; std::map<TSE::uint, float> TSE::OpenGL::BasicTextureShader::textureSlots;
TSE::GLFW::BasicTextureShader *TSE::GLFW::BasicTextureShader::Instance() TSE::OpenGL::BasicTextureShader *TSE::OpenGL::BasicTextureShader::Instance()
{ {
return instance; return instance;
} }
void TSE::GLFW::BasicTextureShader::Destroy() void TSE::OpenGL::BasicTextureShader::Destroy()
{ {
if(instance != nullptr) if(instance != nullptr)
delete instance; delete instance;
instance = nullptr; instance = nullptr;
} }
void TSE::GLFW::BasicTextureShader::Init(float width, float height) void TSE::OpenGL::BasicTextureShader::Init(float width, float height)
{ {
std::vector<std::unique_ptr<ShaderPart>> parts; std::vector<std::unique_ptr<ShaderPart>> parts;
parts.push_back(ShaderPart::LoadFromString(vertT, GL_VERTEX_SHADER)); parts.push_back(ShaderPart::LoadFromString(vertT, GL_VERTEX_SHADER));
@@ -41,12 +41,12 @@ void TSE::GLFW::BasicTextureShader::Init(float width, float height)
instance->Disable(); instance->Disable();
} }
TSE::GLFW::BasicTextureShader::BasicTextureShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts) TSE::OpenGL::BasicTextureShader::BasicTextureShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts)
{ {
PackageSize = SHADER_PACKAGE_SIZE; PackageSize = SHADER_PACKAGE_SIZE;
} }
void TSE::GLFW::BasicTextureShader::OnEnable() const void TSE::OpenGL::BasicTextureShader::OnEnable() const
{ {
glEnableVertexAttribArray(SHADER_VERTEX_INDEX); glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0); glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0);
@@ -58,7 +58,7 @@ void TSE::GLFW::BasicTextureShader::OnEnable() const
glVertexAttribPointer(SHADER_TID_INDEX, 1, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 9)); glVertexAttribPointer(SHADER_TID_INDEX, 1, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 9));
} }
void TSE::GLFW::BasicTextureShader::OnDisable() const void TSE::OpenGL::BasicTextureShader::OnDisable() const
{ {
glDisableVertexAttribArray(SHADER_VERTEX_INDEX); glDisableVertexAttribArray(SHADER_VERTEX_INDEX);
glDisableVertexAttribArray(SHADER_COLOR_INDEX); glDisableVertexAttribArray(SHADER_COLOR_INDEX);
@@ -66,7 +66,7 @@ void TSE::GLFW::BasicTextureShader::OnDisable() const
glDisableVertexAttribArray(SHADER_TID_INDEX); glDisableVertexAttribArray(SHADER_TID_INDEX);
} }
void TSE::GLFW::BasicTextureShader::OnFlush() void TSE::OpenGL::BasicTextureShader::OnFlush()
{ {
auto it = textureSlots.begin(); auto it = textureSlots.begin();
for (int i = 0; i < textureSlots.size(); i++, it++) for (int i = 0; i < textureSlots.size(); i++, it++)
@@ -76,12 +76,12 @@ void TSE::GLFW::BasicTextureShader::OnFlush()
} }
} }
void TSE::GLFW::BasicTextureShader::OnDrawCall(int indexCount) void TSE::OpenGL::BasicTextureShader::OnDrawCall(int indexCount)
{ {
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL);
} }
void TSE::GLFW::BasicTextureShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) void TSE::OpenGL::BasicTextureShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{ {
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE)); auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
if (!r) return; if (!r) return;

View File

@@ -4,7 +4,7 @@
#include "Types.hpp" #include "Types.hpp"
#include <map> #include <map>
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class BasicTextureShader : public Shader class BasicTextureShader : public Shader
{ {
@@ -25,4 +25,4 @@ namespace TSE::GLFW
void OnDrawCall(int indexCount) override; void OnDrawCall(int indexCount) override;
void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override; void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -10,21 +10,21 @@
#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1) #define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1)
TSE::GLFW::BasicTileMapShader* TSE::GLFW::BasicTileMapShader::instance = nullptr; TSE::OpenGL::BasicTileMapShader* TSE::OpenGL::BasicTileMapShader::instance = nullptr;
TSE::GLFW::BasicTileMapShader *TSE::GLFW::BasicTileMapShader::Instance() TSE::OpenGL::BasicTileMapShader *TSE::OpenGL::BasicTileMapShader::Instance()
{ {
return instance; return instance;
} }
void TSE::GLFW::BasicTileMapShader::Destroy() void TSE::OpenGL::BasicTileMapShader::Destroy()
{ {
if(instance != nullptr) if(instance != nullptr)
delete instance; delete instance;
instance = nullptr; instance = nullptr;
} }
void TSE::GLFW::BasicTileMapShader::Init(float width, float height) void TSE::OpenGL::BasicTileMapShader::Init(float width, float height)
{ {
std::vector<std::unique_ptr<ShaderPart>> parts; std::vector<std::unique_ptr<ShaderPart>> parts;
parts.push_back(ShaderPart::LoadFromString(vertTile, GL_VERTEX_SHADER)); parts.push_back(ShaderPart::LoadFromString(vertTile, GL_VERTEX_SHADER));
@@ -37,18 +37,18 @@ void TSE::GLFW::BasicTileMapShader::Init(float width, float height)
instance->Disable(); instance->Disable();
} }
TSE::GLFW::BasicTileMapShader::BasicTileMapShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts) TSE::OpenGL::BasicTileMapShader::BasicTileMapShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts)
{ {
PackageSize = SHADER_PACKAGE_SIZE; PackageSize = SHADER_PACKAGE_SIZE;
} }
TSE::GLFW::BasicTileMapShader::~BasicTileMapShader() TSE::OpenGL::BasicTileMapShader::~BasicTileMapShader()
{ {
if (meshVBO) glDeleteBuffers(1, &meshVBO); if (meshVBO) glDeleteBuffers(1, &meshVBO);
if (meshIBO) glDeleteBuffers(1, &meshIBO); if (meshIBO) glDeleteBuffers(1, &meshIBO);
} }
void TSE::GLFW::BasicTileMapShader::SetMesh(const void *verts, int vertCount, int stride, int floatCountPerVertex, int posOffsetBytes, GLenum primitive, const void *indices, int indexCount, GLenum indexType) void TSE::OpenGL::BasicTileMapShader::SetMesh(const void *verts, int vertCount, int stride, int floatCountPerVertex, int posOffsetBytes, GLenum primitive, const void *indices, int indexCount, GLenum indexType)
{ {
GLint prevVAO = 0, prevArrayBuffer = 0, prevElementBuffer = 0; GLint prevVAO = 0, prevArrayBuffer = 0, prevElementBuffer = 0;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO);
@@ -89,7 +89,7 @@ void TSE::GLFW::BasicTileMapShader::SetMesh(const void *verts, int vertCount, in
glBindVertexArray(prevVAO); glBindVertexArray(prevVAO);
} }
void TSE::GLFW::BasicTileMapShader::OnEnable() const void TSE::OpenGL::BasicTileMapShader::OnEnable() const
{ {
if (!meshReady) if (!meshReady)
{ {
@@ -121,20 +121,20 @@ void TSE::GLFW::BasicTileMapShader::OnEnable() const
glVertexAttribDivisor(SHADER_SPRITE_INDEX, 1); glVertexAttribDivisor(SHADER_SPRITE_INDEX, 1);
} }
void TSE::GLFW::BasicTileMapShader::OnDisable() const void TSE::OpenGL::BasicTileMapShader::OnDisable() const
{ {
glDisableVertexAttribArray(SHADER_MESH_INDEX); glDisableVertexAttribArray(SHADER_MESH_INDEX);
glDisableVertexAttribArray(SHADER_POS_INDEX); glDisableVertexAttribArray(SHADER_POS_INDEX);
glDisableVertexAttribArray(SHADER_SPRITE_INDEX); glDisableVertexAttribArray(SHADER_SPRITE_INDEX);
} }
void TSE::GLFW::BasicTileMapShader::OnFlush() void TSE::OpenGL::BasicTileMapShader::OnFlush()
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TextureID); glBindTexture(GL_TEXTURE_2D, TextureID);
} }
void TSE::GLFW::BasicTileMapShader::OnDrawCall(int indexCount) void TSE::OpenGL::BasicTileMapShader::OnDrawCall(int indexCount)
{ {
if (instanceCount <= 0) return; if (instanceCount <= 0) return;
SetUniform("spriteCount", &SpriteCount); SetUniform("spriteCount", &SpriteCount);
@@ -158,7 +158,7 @@ void TSE::GLFW::BasicTileMapShader::OnDrawCall(int indexCount)
instanceCount = 0; instanceCount = 0;
} }
void TSE::GLFW::BasicTileMapShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) void TSE::OpenGL::BasicTileMapShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{ {
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE)); auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
if (!r) return; if (!r) return;
@@ -171,9 +171,7 @@ void TSE::GLFW::BasicTileMapShader::OnSubmit(const Transformable &t, float *&tar
SpriteCount = tileSet->GetCount(); SpriteCount = tileSet->GetCount();
SpriteScale = tm->SpriteScale; SpriteScale = tm->SpriteScale;
int chunkcount = tm->GetChunkCount(); const std::vector<Vector2> orderedChunks = *tm->GetChunkPositionsInOrder();
Vector2 orderedChunks[chunkcount];
tm->GetChunkPositionsInOrder(orderedChunks);
Matrix4x4 matr = t.GetLocalMatrix(); Matrix4x4 matr = t.GetLocalMatrix();
@@ -182,11 +180,9 @@ void TSE::GLFW::BasicTileMapShader::OnSubmit(const Transformable &t, float *&tar
for(auto chunkPos : orderedChunks) for(auto chunkPos : orderedChunks)
{ {
auto chunk = tm->GetChunk(chunkPos); auto chunk = tm->GetChunk(chunkPos);
int spriteCount = chunk->GetSpriteCount(); const int spriteCount = chunk->GetSpriteCount();
Vector2 spritePositions[spriteCount]; const std::vector<Vector2> spritePositions = *chunk->GetOrderedPositions();
int spriteIds[spriteCount]; const std::vector<Vector2i> spriteIds = *chunk->GetOrderedSpriteIds();
chunk->GetOrderedPositions(spritePositions);
chunk->GetOrderedSpriteIds(spriteIds);
int chunkSize = chunk->GetChunksize(); int chunkSize = chunk->GetChunksize();
for (int i = 0; i < spriteCount; i++) for (int i = 0; i < spriteCount; i++)
@@ -198,7 +194,7 @@ void TSE::GLFW::BasicTileMapShader::OnSubmit(const Transformable &t, float *&tar
*target++ = pos.x; *target++ = pos.x;
*target++ = pos.y; *target++ = pos.y;
*target++ = pos.z; *target++ = pos.z;
*target++ = spriteIds[i]; *target++ = spriteIds[i].x;
++instanceCount; ++instanceCount;
stack.Pop(); stack.Pop();
@@ -208,5 +204,6 @@ void TSE::GLFW::BasicTileMapShader::OnSubmit(const Transformable &t, float *&tar
} }
} }
stack.Pop();
restartDrawcall(rnd); restartDrawcall(rnd);
} }

View File

@@ -5,7 +5,7 @@
#include "Shader.hpp" #include "Shader.hpp"
#include "Types.hpp" #include "Types.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class BasicTileMapShader : public Shader class BasicTileMapShader : public Shader
{ {
@@ -41,4 +41,4 @@ namespace TSE::GLFW
void OnDrawCall(int indexCount) override; void OnDrawCall(int indexCount) override;
void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override; void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -4,32 +4,37 @@
#include "ditheringShader.hpp" #include "ditheringShader.hpp"
#include "basicParticleShader.hpp" #include "basicParticleShader.hpp"
#include "basicTileMapShader.hpp" #include "basicTileMapShader.hpp"
#include "basicOrderedSpriteSetShader.hpp"
#include "elements/ShaderRegistry.hpp" #include "elements/ShaderRegistry.hpp"
void TSE::GLFW::LoadBasicShaders(float width, float height) void TSE::OpenGL::LoadBasicShaders(float width, float height)
{ {
BasicShader::Init(width, height); BasicShader::Init(width, height);
BasicTextureShader::Init(width, height); BasicTextureShader::Init(width, height);
DitheringShader::Init(width, height); DitheringShader::Init(width, height);
BasicParticleShader::Init(width, height); BasicParticleShader::Init(width, height);
BasicTileMapShader::Init(width, height); BasicTileMapShader::Init(width, height);
BasicOrderedSpriteSetShader::Init(width, height);
ShaderRegistry::SetShader("Basic Unlit Shader", BasicShader::Instance()); ShaderRegistry::SetShader("Basic Unlit Shader", BasicShader::Instance());
ShaderRegistry::SetShader("Basic Unlit Texture Shader", BasicTextureShader::Instance()); ShaderRegistry::SetShader("Basic Unlit Texture Shader", BasicTextureShader::Instance());
ShaderRegistry::SetShader("Basic Unlit Dithering Shader", DitheringShader::Instance()); ShaderRegistry::SetShader("Basic Unlit Dithering Shader", DitheringShader::Instance());
ShaderRegistry::SetShader("Basic Unlit Particle Shader", BasicParticleShader::Instance()); ShaderRegistry::SetShader("Basic Unlit Particle Shader", BasicParticleShader::Instance());
ShaderRegistry::SetShader("Basic Unlit TileMap Shader", BasicTileMapShader::Instance()); ShaderRegistry::SetShader("Basic Unlit TileMap Shader", BasicTileMapShader::Instance());
ShaderRegistry::SetShader("Basic Ordered Sprite Set Shader", BasicOrderedSpriteSetShader::Instance());
} }
void TSE::GLFW::UnLoadBasicShaders() void TSE::OpenGL::UnLoadBasicShaders()
{ {
ShaderRegistry::RemoveShader("Basic Unlit Shader"); ShaderRegistry::RemoveShader("Basic Unlit Shader");
ShaderRegistry::RemoveShader("Basic Unlit Texture Shader"); ShaderRegistry::RemoveShader("Basic Unlit Texture Shader");
ShaderRegistry::RemoveShader("Basic Unlit Dithering Shader"); ShaderRegistry::RemoveShader("Basic Unlit Dithering Shader");
ShaderRegistry::RemoveShader("Basic Unlit Particle Shader"); ShaderRegistry::RemoveShader("Basic Unlit Particle Shader");
ShaderRegistry::RemoveShader("Basic Unlit TileMap Shader"); ShaderRegistry::RemoveShader("Basic Unlit TileMap Shader");
ShaderRegistry::RemoveShader("Basic Ordered Sprite Set Shader");
BasicShader::Destroy(); BasicShader::Destroy();
BasicTextureShader::Destroy(); BasicTextureShader::Destroy();
DitheringShader::Destroy(); DitheringShader::Destroy();
BasicParticleShader::Destroy(); BasicParticleShader::Destroy();
BasicTileMapShader::Destroy(); BasicTileMapShader::Destroy();
BasicOrderedSpriteSetShader::Destroy();
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
namespace TSE::GLFW namespace TSE::OpenGL
{ {
void LoadBasicShaders(float width, float height); void LoadBasicShaders(float width, float height);
void UnLoadBasicShaders(); void UnLoadBasicShaders();

View File

@@ -10,21 +10,21 @@
#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 4) #define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 4)
TSE::GLFW::DitheringShader* TSE::GLFW::DitheringShader::instance = nullptr; TSE::OpenGL::DitheringShader* TSE::OpenGL::DitheringShader::instance = nullptr;
TSE::GLFW::DitheringShader *TSE::GLFW::DitheringShader::Instance() TSE::OpenGL::DitheringShader *TSE::OpenGL::DitheringShader::Instance()
{ {
return instance; return instance;
} }
void TSE::GLFW::DitheringShader::Destroy() void TSE::OpenGL::DitheringShader::Destroy()
{ {
if(instance != nullptr) if(instance != nullptr)
delete instance; delete instance;
instance = nullptr; instance = nullptr;
} }
void TSE::GLFW::DitheringShader::Init(float width, float height) void TSE::OpenGL::DitheringShader::Init(float width, float height)
{ {
std::vector<std::unique_ptr<ShaderPart>> parts; std::vector<std::unique_ptr<ShaderPart>> parts;
parts.push_back(ShaderPart::LoadFromString(vertD, GL_VERTEX_SHADER)); parts.push_back(ShaderPart::LoadFromString(vertD, GL_VERTEX_SHADER));
@@ -32,12 +32,12 @@ void TSE::GLFW::DitheringShader::Init(float width, float height)
instance = new DitheringShader(std::move(parts)); instance = new DitheringShader(std::move(parts));
} }
TSE::GLFW::DitheringShader::DitheringShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts) TSE::OpenGL::DitheringShader::DitheringShader(std::vector<std::unique_ptr<ShaderPart>> &&parts) : Shader(parts)
{ {
PackageSize = SHADER_PACKAGE_SIZE; PackageSize = SHADER_PACKAGE_SIZE;
} }
void TSE::GLFW::DitheringShader::OnEnable() const void TSE::OpenGL::DitheringShader::OnEnable() const
{ {
glEnableVertexAttribArray(SHADER_VERTEX_INDEX); glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0); glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0);
@@ -45,22 +45,22 @@ void TSE::GLFW::DitheringShader::OnEnable() const
glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3)); glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3));
} }
void TSE::GLFW::DitheringShader::OnDisable() const void TSE::OpenGL::DitheringShader::OnDisable() const
{ {
glDisableVertexAttribArray(SHADER_VERTEX_INDEX); glDisableVertexAttribArray(SHADER_VERTEX_INDEX);
glDisableVertexAttribArray(SHADER_COLOR_INDEX); glDisableVertexAttribArray(SHADER_COLOR_INDEX);
} }
void TSE::GLFW::DitheringShader::OnFlush() void TSE::OpenGL::DitheringShader::OnFlush()
{ {
} }
void TSE::GLFW::DitheringShader::OnDrawCall(int indexCount) void TSE::OpenGL::DitheringShader::OnDrawCall(int indexCount)
{ {
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL); glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL);
} }
void TSE::GLFW::DitheringShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) void TSE::OpenGL::DitheringShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd)
{ {
auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE)); auto* r = dynamic_cast<Renderable*>(t.GetBehaviourScript(RENDERABLE));
if (!r) return; if (!r) return;

View File

@@ -2,7 +2,7 @@
#include "Shader.hpp" #include "Shader.hpp"
namespace TSE::GLFW namespace TSE::OpenGL
{ {
class DitheringShader : public Shader class DitheringShader : public Shader
{ {
@@ -22,4 +22,4 @@ namespace TSE::GLFW
void OnDrawCall(int indexCount) override; void OnDrawCall(int indexCount) override;
void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override; void OnSubmit(const Transformable& t, float*& target, TransformationStack& stack, void (*restartDrawcall)(IRenderer&), IRenderer& rnd) override;
}; };
} // namespace TSE::GLFW } // namespace TSE::OpenGL

View File

@@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.31) cmake_minimum_required(VERSION 3.31)
#project name #project name
project(TSE_GlfwOpenGlImpl) project(TSE_Sdl3Impl)
#cpp settings #cpp settings
find_program(CLANG_C NAMES clang) find_program(CLANG_C NAMES clang)
@@ -46,16 +46,14 @@ include_directories(${PROJECT_SOURCE_DIR}/../TSE_Base/include)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Math/src) include_directories(${PROJECT_SOURCE_DIR}/../TSE_Math/src)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Core/src) include_directories(${PROJECT_SOURCE_DIR}/../TSE_Core/src)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_Core/include) include_directories(${PROJECT_SOURCE_DIR}/../TSE_Core/include)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_GlfwImpl/src)
include_directories(${PROJECT_SOURCE_DIR}/../TSE_GlfwImpl/include)
#project def #project def
if(Lib) if(Lib)
add_library(TSE_GlfwOpenGlImpl SHARED ${CPP_SOURCE_TSE}) add_library(TSE_Sdl3Impl SHARED ${CPP_SOURCE_TSE})
else() else()
add_library(TSE_GlfwOpenGlImpl STATIC ${CPP_SOURCE_TSE}) add_library(TSE_Sdl3Impl STATIC ${CPP_SOURCE_TSE})
endif() endif()
#flags #flags
target_compile_options(TSE_GlfwOpenGlImpl PRIVATE -march=native) target_compile_options(TSE_Sdl3Impl PRIVATE -march=native)

Binary file not shown.

View File

@@ -0,0 +1,91 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/**
* Main include header for the SDL library, version 3.4.2
*
* It is almost always best to include just this one header instead of
* picking out individual headers included here. There are exceptions to
* this rule--SDL_main.h is special and not included here--but usually
* letting SDL.h include the kitchen sink for you is the correct approach.
*/
#ifndef SDL_h_
#define SDL_h_
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_assert.h>
#include <SDL3/SDL_asyncio.h>
#include <SDL3/SDL_atomic.h>
#include <SDL3/SDL_audio.h>
#include <SDL3/SDL_bits.h>
#include <SDL3/SDL_blendmode.h>
#include <SDL3/SDL_camera.h>
#include <SDL3/SDL_clipboard.h>
#include <SDL3/SDL_cpuinfo.h>
#include <SDL3/SDL_dialog.h>
#include <SDL3/SDL_dlopennote.h>
#include <SDL3/SDL_endian.h>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_gamepad.h>
#include <SDL3/SDL_gpu.h>
#include <SDL3/SDL_guid.h>
#include <SDL3/SDL_haptic.h>
#include <SDL3/SDL_hidapi.h>
#include <SDL3/SDL_hints.h>
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_iostream.h>
#include <SDL3/SDL_joystick.h>
#include <SDL3/SDL_keyboard.h>
#include <SDL3/SDL_keycode.h>
#include <SDL3/SDL_loadso.h>
#include <SDL3/SDL_locale.h>
#include <SDL3/SDL_log.h>
#include <SDL3/SDL_messagebox.h>
#include <SDL3/SDL_metal.h>
#include <SDL3/SDL_misc.h>
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_mutex.h>
#include <SDL3/SDL_pen.h>
#include <SDL3/SDL_pixels.h>
#include <SDL3/SDL_platform.h>
#include <SDL3/SDL_power.h>
#include <SDL3/SDL_process.h>
#include <SDL3/SDL_properties.h>
#include <SDL3/SDL_rect.h>
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_scancode.h>
#include <SDL3/SDL_sensor.h>
#include <SDL3/SDL_storage.h>
#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_system.h>
#include <SDL3/SDL_thread.h>
#include <SDL3/SDL_time.h>
#include <SDL3/SDL_timer.h>
#include <SDL3/SDL_tray.h>
#include <SDL3/SDL_touch.h>
#include <SDL3/SDL_version.h>
#include <SDL3/SDL_video.h>
#include <SDL3/SDL_oldnames.h>
#endif /* SDL_h_ */

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