diff --git a/TSE b/TSE index 45501f1..769bbd4 160000 --- a/TSE +++ b/TSE @@ -1 +1 @@ -Subproject commit 45501f153de222598515fef62e04078a96a86a50a6e7bf670050bfd71fd3f12d +Subproject commit 769bbd426169ff79d55975524197abb9519a4774c04df0a8a92c4135f0e70eb4 diff --git a/TSE-RTS/Resources/tiles.png b/TSE-RTS/Resources/tiles.png index deeb8e2..a3a39b1 100644 Binary files a/TSE-RTS/Resources/tiles.png and b/TSE-RTS/Resources/tiles.png differ diff --git a/TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.cpp b/TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.cpp new file mode 100644 index 0000000..a8a92b0 --- /dev/null +++ b/TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.cpp @@ -0,0 +1,17 @@ +#include "CameraSizeChangeNotifyer.hpp" +#include "interfaces/IRenderTarget.hpp" + +void CameraSizeChangeNotifyer::OnUpdate() +{ + using namespace TSE; + + if(camToObserver != nullptr) + { + Vector2 currentSize = camToObserver->GetRenderTargetSize(); + if(currentSize != lastSize) + { + lastSize = currentSize; + TriggerObserver(&lastSize); + } + } +} \ No newline at end of file diff --git a/TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.hpp b/TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.hpp new file mode 100644 index 0000000..1a5c4a3 --- /dev/null +++ b/TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.hpp @@ -0,0 +1,25 @@ +#pragma once + +#define CAMERASIZECHANGENOTIFYER typeid(CameraSizeChangeNotifyer).name() + +#include "elements/BehaviourScript.hpp" +#include "elements/Transformable.hpp" +#include "interfaces/IObservable.hpp" +#include "Types.hpp" +#include "BehaviourScripts/Camera.hpp" +#include "Vector2.hpp" + +class CameraSizeChangeNotifyer : public TSE::BehaviourScript, public TSE::IObservable +{ +private: + +public: + TSE::Camera* camToObserver = nullptr; + TSE::Vector2 lastSize; + + void OnUpdate() override; + inline const char* GetName() override + { + return "Camera Size Change Notifyer"; + } +}; \ No newline at end of file diff --git a/TSE-RTS/src/BehaviourScripts/CanvasScaler.cpp b/TSE-RTS/src/BehaviourScripts/CanvasScaler.cpp new file mode 100644 index 0000000..952efce --- /dev/null +++ b/TSE-RTS/src/BehaviourScripts/CanvasScaler.cpp @@ -0,0 +1,13 @@ +#include "CanvasScaler.hpp" + +void CanvasScaler::OnObserved(void *data) +{ + using namespace TSE; + + Vector2* size = (Vector2*)data; + *mesh = Mesh::GetQuadMesh(); + for(auto& vertex : mesh->vertecies) + { + vertex *= *size * 2; + } +} \ No newline at end of file diff --git a/TSE-RTS/src/BehaviourScripts/CanvasScaler.hpp b/TSE-RTS/src/BehaviourScripts/CanvasScaler.hpp new file mode 100644 index 0000000..d20b966 --- /dev/null +++ b/TSE-RTS/src/BehaviourScripts/CanvasScaler.hpp @@ -0,0 +1,24 @@ +#pragma once + +#define CANVASSCALER typeid(CanvasScaler).name() + +#include "elements/BehaviourScript.hpp" +#include "elements/Transformable.hpp" +#include "Types.hpp" +#include "interfaces/IObserver.hpp" +#include "Mesh.hpp" + +class CanvasScaler : public TSE::BehaviourScript, public TSE::IObserver +{ +private: + +public: + + TSE::Mesh* mesh = nullptr; + + void OnObserved(void* data) override; + inline const char* GetName() override + { + return "Canvas Scaler"; + } +}; \ No newline at end of file diff --git a/TSE-RTS/src/BehaviourScripts/RenderTextureResizes.cpp b/TSE-RTS/src/BehaviourScripts/RenderTextureResizes.cpp new file mode 100644 index 0000000..d839650 --- /dev/null +++ b/TSE-RTS/src/BehaviourScripts/RenderTextureResizes.cpp @@ -0,0 +1,13 @@ +#include "RenderTextureResizes.hpp" + +void RenderTextureResizes::OnObserved(void *data) +{ + using namespace TSE; + + Vector2* size = (Vector2*)data; + if(size->x < 10) + { + return; + } + rt->SetSize(*size); +} \ No newline at end of file diff --git a/TSE-RTS/src/BehaviourScripts/RenderTextureResizes.hpp b/TSE-RTS/src/BehaviourScripts/RenderTextureResizes.hpp new file mode 100644 index 0000000..97fd7c8 --- /dev/null +++ b/TSE-RTS/src/BehaviourScripts/RenderTextureResizes.hpp @@ -0,0 +1,23 @@ +#pragma once + +#define RENDERTEXTURERESIZES typeid(RenderTextureResizes).name() + +#include "elements/BehaviourScript.hpp" +#include "elements/Transformable.hpp" +#include "Types.hpp" +#include "interfaces/IRenderTexture.hpp" +#include "interfaces/IObserver.hpp" + +class RenderTextureResizes : public TSE::BehaviourScript, public TSE::IObserver +{ +private: + +public: + TSE::IRenderTexture* rt = nullptr; + + void OnObserved(void* data) override; + inline const char* GetName() override + { + return "Render Texture Resizes"; + } +}; \ No newline at end of file diff --git a/TSE-RTS/src/game.cpp b/TSE-RTS/src/game.cpp index df401f2..d590caf 100644 --- a/TSE-RTS/src/game.cpp +++ b/TSE-RTS/src/game.cpp @@ -6,11 +6,17 @@ #include "Vector2.hpp" #include #include "PerlinNoise.hpp" +#include "BehaviourScripts/Camera.hpp" +#include "interfaces/IRenderTexture.hpp" +#include "BehaviourScripts/MeshContainer.hpp" +#include "BehaviourScripts/CameraSizeChangeNotifyer.hpp" +#include "BehaviourScripts/RenderTextureResizes.hpp" +#include "BehaviourScripts/CanvasScaler.hpp" #define circleRadius 32 #define circleFallof 25 -void game::setup(TSE::Scene* s) +void game::setup(TSE::Scene* s, TSE::IWindow* wnd) { using namespace TSE; s->AddLayer(&gameLayer); @@ -61,22 +67,81 @@ void game::setup(TSE::Scene* s) { if(noise >= 0.8f) { - maps[3]->SetTile(Vector2(x, y), {0,9}); + maps[3]->SetTile(Vector2(x, y), {0,9}, {2,9}); } else if(noise >= 0.6f) { - maps[2]->SetTile(Vector2(x, y), {0,9}); + maps[2]->SetTile(Vector2(x, y), {0,9}, {2,9}); } else if(noise >= 0.4f) { - maps[1]->SetTile(Vector2(x, y), {0,9}); + maps[1]->SetTile(Vector2(x, y), {0,9}, {2,9}); } else { - maps[0]->SetTile(Vector2(x, y), {0,9}); + maps[0]->SetTile(Vector2(x, y), {0,9}, {2,9}); } } } } + //RenderingLayer + + s->AddLayer(&renderingLayer); + + Transformable* lastPassCamera = new Transformable("lastPassCamera"); + Camera* lpCam = new Camera(); + lpCam->SetRenderTarget(wnd); + lpCam->SetRenderScale(1); + lpCam->layersNotToRender.push_back(gameLayer.GetID()); + lastPassCamera->AddBehaviourScript(lpCam); + CameraSizeChangeNotifyer* camNotifyer = new CameraSizeChangeNotifyer(); + camNotifyer->lastSize = {0,0}; + camNotifyer->camToObserver = lpCam; + lastPassCamera->AddBehaviourScript(camNotifyer); + + Vector2 canvasSize = wnd->GetSize() / 4.0f; + + IRenderTexture* rt = IRenderTexture::factory->CreateTextureHeap(canvasSize, 2); + Transformable* firstPassCamera = new Transformable("firstPassCamera"); + Camera* fpCam = new Camera(); + fpCam->SetRenderScale(256); + fpCam->SetRenderTarget(rt); + fpCam->layersNotToRender.push_back(renderingLayer.GetID()); + firstPassCamera->AddBehaviourScript(fpCam); + RenderTextureResizes* resizer = new RenderTextureResizes(); + resizer->rt = rt; + camNotifyer->Observe(resizer); + firstPassCamera->AddBehaviourScript(resizer); + + //Render pipeline setup + + gameLayer.AddTransformable(firstPassCamera); + renderingLayer.AddTransformable(lastPassCamera); + + //final + + Mesh* canvasMesh = new Mesh(Mesh::GetQuadMesh()); + for(auto& vertex : canvasMesh->vertecies) + { + vertex *= wnd->GetSize(); + } + MeshContainer* canvasContainer = new MeshContainer(canvasMesh); + + Material* canvasMat = new Material("canvasMat", ShaderRegistry::GetShader("LastPassShader")); + canvasMat->SetValue("threshold", 0.01f); + canvasMat->SetValue("darken", 0.45f); + canvasMat->SetValue("colorTextureID", rt->GetTextureId(0)); + canvasMat->SetValue("heightTextureID", rt->GetTextureId(1)); + Renderable* canvasRenderer = new Renderable(canvasMat); + + CanvasScaler* canvasScaler = new CanvasScaler(); + canvasScaler->mesh = canvasMesh; + camNotifyer->Observe(canvasScaler); + + lastPassCamera->AddBehaviourScript(canvasContainer); + lastPassCamera->AddBehaviourScript(canvasRenderer); + lastPassCamera->AddBehaviourScript(canvasScaler); + + //propper resize stuff for prior passes, and canvas, and implement LastPassShader siehe dazu den chat: https://chatgpt.com/c/69985c47-6a50-838b-852d-45bb0b8454e5 } \ No newline at end of file diff --git a/TSE-RTS/src/game.hpp b/TSE-RTS/src/game.hpp index 9eda776..013883f 100644 --- a/TSE-RTS/src/game.hpp +++ b/TSE-RTS/src/game.hpp @@ -1,10 +1,12 @@ #pragma once #include "elements/Scene.hpp" +#include "interfaces/IWindow.hpp" class game { public: inline static TSE::Layer gameLayer = TSE::Layer("gameLayer"); + inline static TSE::Layer renderingLayer = TSE::Layer("renderingLayer"); - static void setup(TSE::Scene* s); + static void setup(TSE::Scene* s, TSE::IWindow* wnd); }; \ No newline at end of file diff --git a/TSE-RTS/src/main.cpp b/TSE-RTS/src/main.cpp index 8755779..fb4cfb3 100644 --- a/TSE-RTS/src/main.cpp +++ b/TSE-RTS/src/main.cpp @@ -16,8 +16,9 @@ #include "EditorSubsystem.hpp" #include "game.hpp" #include "shaders/TileMapShader.hpp" +#include "shaders/LastPassShader.hpp" -#define USE_EDITOR +//#define USE_EDITOR using namespace TSE; using namespace TSE::GLFW; @@ -36,21 +37,27 @@ void SetupWindow() wnd = new WindowGlfw(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, true), WindowType::Maximized); editor = new EditorSubsystem(); #else - wnd = new WindowGlfw(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, false), WindowType::Maximized); + wnd = new WindowGlfw(PROJECT_NAME, 1920, 1080, new OpenGLRenderingBackend(backColor, false, 8, false), WindowType::Fullscreen); #endif LoadBasicShaders(wnd->GetSize().x, wnd->GetSize().y); TileMapShader::Init(wnd->GetSize().x, wnd->GetSize().y); + LastPassShader::Init(wnd->GetSize().x, wnd->GetSize().y); ShaderRegistry::SetShader("TileMapShader v2", TileMapShader::Instance()); + ShaderRegistry::SetShader("LastPassShader", LastPassShader::Instance()); rend = new DefaultRendererOpenGL(*BasicShader::Instance()); currentScene = new Scene(); + + #ifdef USE_EDITOR + ((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->layersNotToRender.push_back(game::renderingLayer.GetID()); + currentScene->AddLayer(&editor->editorLayer); + editor->hv.SetScene(currentScene); + #endif - game::setup(currentScene); + + game::setup(currentScene, wnd); -#ifdef USE_EDITOR - currentScene->AddLayer(&editor->editorLayer); - editor->hv.SetScene(currentScene); -#endif + wnd->DoneSetup(); } void CleanUp() diff --git a/TSE-RTS/src/shaders/LastPassShader.cpp b/TSE-RTS/src/shaders/LastPassShader.cpp new file mode 100644 index 0000000..c7f5520 --- /dev/null +++ b/TSE-RTS/src/shaders/LastPassShader.cpp @@ -0,0 +1,109 @@ +#include "LastPassShader.hpp" +#include "BehaviourScripts/Renderable.hpp" +#include "Color.hpp" +#include "interfaces/ITexture.hpp" +#include "LastPassShaderGLSL.hpp" + +using namespace TSE; +using namespace TSE::GLFW; + +#define SHADER_VERTEX_INDEX 0 +#define SHADER_UV_INDEX 1 + +#define SHADER_PACKAGE_SIZE (sizeof(float) * (3 + 2)) + +LastPassShader* LastPassShader::instance = nullptr; + +LastPassShader *LastPassShader::Instance() +{ + return instance; +} + +void LastPassShader::Destroy() +{ + if(instance != nullptr) + delete instance; + instance = nullptr; +} + +void LastPassShader::Init(float width, float height) +{ + std::vector> parts; + parts.push_back(ShaderPart::LoadFromString(vertLastPass, GL_VERTEX_SHADER)); + parts.push_back(ShaderPart::LoadFromString(fragLastPass, GL_FRAGMENT_SHADER)); + instance = new LastPassShader(std::move(parts)); + + instance->Enable(); + instance->SetUniform("colorTexture", 0); + instance->SetUniform("heightTexture", 1); + instance->Disable(); +} + +LastPassShader::LastPassShader(std::vector> &&parts) : Shader(parts) +{ + PackageSize = SHADER_PACKAGE_SIZE; +} + +void LastPassShader::OnEnable() const +{ + glEnableVertexAttribArray(SHADER_VERTEX_INDEX); + glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0); + glEnableVertexAttribArray(SHADER_UV_INDEX); + glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3)); +} + +void LastPassShader::OnDisable() const +{ + glDisableVertexAttribArray(SHADER_VERTEX_INDEX); + glDisableVertexAttribArray(SHADER_UV_INDEX); +} + +void LastPassShader::OnFlush() +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, ColorTextureID); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, HeightTextureID); + SetUniform("uThreshold", Threshold); + SetUniform("uDarken", Darken); +} + +void LastPassShader::OnDrawCall(int indexCount) +{ + glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL); +} + +void LastPassShader::OnSubmit(const TSE::Transformable &t, float *&target, TSE::TransformationStack &stack, void (*restartDrawcall)(TSE::IRenderer &), TSE::IRenderer &rnd) +{ + auto* r = dynamic_cast(t.GetBehaviourScript(RENDERABLE)); + if (!r) return; + if(!r->GetMaterial()->HasValue("colorTextureID")) return; + if(!r->GetMaterial()->HasValue("heightTextureID")) return; + if(!r->GetMaterial()->HasValue("threshold")) return; + if(!r->GetMaterial()->HasValue("darken")) return; + ColorTextureID = r->GetMaterial()->GetValue("colorTextureID"); + HeightTextureID = r->GetMaterial()->GetValue("heightTextureID"); + Threshold = r->GetMaterial()->GetValue("threshold"); + Darken = r->GetMaterial()->GetValue("darken"); + + const Vector3* verts = r->GetVertices(); + const Vector2* uvs = r->GetUVs(); + ushort vCount = r->GetVertexCount(); + + Matrix4x4 matr = t.GetLocalMatrix(); + + stack.Push(matr); + const Matrix4x4& top = stack.Top(); + + for (ushort i = 0; i < vCount; i++) { + Vector3 p = top * verts[i]; + Vector2 uv = uvs[i]; + *target++ = p.x; + *target++ = p.y; + *target++ = p.z; + *target++ = uv.x; + *target++ = uv.y; + } + + stack.Pop(); +} diff --git a/TSE-RTS/src/shaders/LastPassShader.hpp b/TSE-RTS/src/shaders/LastPassShader.hpp new file mode 100644 index 0000000..2748c5f --- /dev/null +++ b/TSE-RTS/src/shaders/LastPassShader.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "GL/gl3w.h" +#include "GL/gl.h" +#include "shader/Shader.hpp" +#include "Types.hpp" + +class LastPassShader : public TSE::GLFW::Shader +{ +private: + static LastPassShader* instance; + GLuint ColorTextureID; + GLuint HeightTextureID; + float Threshold; + float Darken; + +public: + static LastPassShader* Instance(); + static void Destroy(); + static void Init(float width, float height); + LastPassShader(std::vector>&& parts); + +protected: + void OnEnable() const override; + void OnDisable() const override; + void OnFlush() override; + void OnDrawCall(int indexCount) override; + void OnSubmit(const TSE::Transformable& t, float*& target, TSE::TransformationStack& stack, void (*restartDrawcall)(TSE::IRenderer&), TSE::IRenderer& rnd) override; +}; diff --git a/TSE-RTS/src/shaders/LastPassShaderGLSL.hpp b/TSE-RTS/src/shaders/LastPassShaderGLSL.hpp new file mode 100644 index 0000000..bfb3ff8 --- /dev/null +++ b/TSE-RTS/src/shaders/LastPassShaderGLSL.hpp @@ -0,0 +1,96 @@ +#pragma once + +inline const char* vertLastPass = R"( + #version 330 core + + layout (location = 0) in vec3 position; + layout (location = 1) in vec2 uv; + + uniform mat4 prMatrix; + uniform mat4 camMatrix; + + out DATA + { + vec2 uv_out; + } vs_out; + + + void main() + { + gl_Position = prMatrix * camMatrix * vec4(position.x, position.y, position.z, 1.0); + vs_out.uv_out = uv; + } +)"; + +inline const char* fragLastPass = R"( + #version 330 core + layout (location = 0) out vec4 color; + + uniform sampler2D colorTexture; + uniform sampler2D heightTexture; + + uniform float uThreshold; + uniform float uDarken; + + in DATA + { + vec2 uv_out; + } fs_in; + + float GetChangeInHeight4(ivec2 pos) + { + float center = texelFetch(heightTexture, pos, 0).a; + ivec2 s = textureSize(heightTexture, 0) - ivec2(1); + + float north = texelFetch(heightTexture, clamp(pos + ivec2(0, 1), ivec2(0), s), 0).a; + float south = texelFetch(heightTexture, clamp(pos + ivec2(0, -1), ivec2(0), s), 0).a; + float east = texelFetch(heightTexture, clamp(pos + ivec2(1, 0), ivec2(0), s), 0).a; + float west = texelFetch(heightTexture, clamp(pos + ivec2(-1, 0), ivec2(0), s), 0).a; + + float edge = 0.0; + edge = max(edge, abs(center - north)); + edge = max(edge, abs(center - south)); + edge = max(edge, abs(center - east)); + edge = max(edge, abs(center - west)); + + return edge; + } + + float GetChangeInNormal4(ivec2 pos) + { + float center = texelFetch(heightTexture, pos, 0).g; + ivec2 s = textureSize(heightTexture, 0) - ivec2(1); + + float north = texelFetch(heightTexture, clamp(pos + ivec2(0, 1), ivec2(0), s), 0).g; + float south = texelFetch(heightTexture, clamp(pos + ivec2(0, -1), ivec2(0), s), 0).g; + float east = texelFetch(heightTexture, clamp(pos + ivec2(1, 0), ivec2(0), s), 0).g; + float west = texelFetch(heightTexture, clamp(pos + ivec2(-1, 0), ivec2(0), s), 0).g; + + float edge = 0.0; + edge = max(edge, abs(center - north)); + edge = max(edge, abs(center - south)); + edge = max(edge, abs(center - east)); + edge = max(edge, abs(center - west)); + + return edge; + } + + void main() + { + + ivec2 size = textureSize(heightTexture, 0); + ivec2 p = clamp(ivec2(fs_in.uv_out * vec2(size)), ivec2(0), size - ivec2(1)); + + float changeInNormal = GetChangeInNormal4(p); + float changeInHeight = GetChangeInHeight4(p); + + float maskH = step(uThreshold, changeInHeight); + float maskN = step(uThreshold, changeInNormal); + float mask = max(maskH, maskN); + + vec3 col = texelFetch(colorTexture, p, 0).rgb; + col *= mix(1.0, 1.0 - uDarken, mask); + + color = vec4(col, 1.0); + } +)"; diff --git a/TSE-RTS/src/shaders/TileMapShader.cpp b/TSE-RTS/src/shaders/TileMapShader.cpp index eda4a56..40086f0 100644 --- a/TSE-RTS/src/shaders/TileMapShader.cpp +++ b/TSE-RTS/src/shaders/TileMapShader.cpp @@ -10,8 +10,9 @@ using namespace TSE::GLFW; #define SHADER_MESH_INDEX 0 #define SHADER_POS_INDEX 1 #define SHADER_SPRITE_INDEX 2 +#define SHADER_NORMAL_INDEX 3 -#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1) +#define SHADER_PACKAGE_SIZE sizeof(float) * (3 + 1 + 1) TileMapShader* TileMapShader::instance = nullptr; @@ -122,6 +123,11 @@ void TileMapShader::OnEnable() const glEnableVertexAttribArray(SHADER_SPRITE_INDEX); glVertexAttribPointer(SHADER_SPRITE_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*3)); glVertexAttribDivisor(SHADER_SPRITE_INDEX, 1); + + // layout 3: normalindex (float) + glEnableVertexAttribArray(SHADER_NORMAL_INDEX); + glVertexAttribPointer(SHADER_NORMAL_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*4)); + glVertexAttribDivisor(SHADER_NORMAL_INDEX, 1); } void TileMapShader::OnDisable() const @@ -129,12 +135,14 @@ void TileMapShader::OnDisable() const glDisableVertexAttribArray(SHADER_MESH_INDEX); glDisableVertexAttribArray(SHADER_POS_INDEX); glDisableVertexAttribArray(SHADER_SPRITE_INDEX); + glDisableVertexAttribArray(SHADER_NORMAL_INDEX); } void TileMapShader::OnFlush() { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureID); + glDisable(GL_BLEND); } void TileMapShader::OnDrawCall(int indexCount) @@ -159,6 +167,11 @@ void TileMapShader::OnDrawCall(int indexCount) } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)prevElementBuffer); +} + +void TileMapShader::OnPostDraw() +{ + glEnable(GL_BLEND); instanceCount = 0; } @@ -177,9 +190,7 @@ void TileMapShader::OnSubmit(const Transformable &t, float *&target, Transformat SpriteCount = tileSet->GetCount(); SpriteScale = tm->SpriteScale; - const int chunkcount = tm->GetChunkCount(); - Vector2 orderedChunks[chunkcount]; - tm->GetChunkPositionsInOrder(orderedChunks); + const std::vector orderedChunks = *tm->GetChunkPositionsInOrder(); Matrix4x4 matr = t.GetLocalMatrix(); @@ -189,10 +200,8 @@ void TileMapShader::OnSubmit(const Transformable &t, float *&target, Transformat { auto chunk = tm->GetChunk(chunkPos); const int spriteCount = chunk->GetSpriteCount(); - Vector2 spritePositions[spriteCount]; - int spriteIds[spriteCount]; - chunk->GetOrderedPositions(spritePositions); - chunk->GetOrderedSpriteIds(spriteIds); + const std::vector spritePositions = *chunk->GetOrderedPositions(); + const std::vector spriteIds = *chunk->GetOrderedSpriteIds(); int chunkSize = chunk->GetChunksize(); for (int i = 0; i < spriteCount; i++) @@ -204,12 +213,13 @@ void TileMapShader::OnSubmit(const Transformable &t, float *&target, Transformat *target++ = pos.x; *target++ = pos.y; *target++ = pos.z; - *target++ = spriteIds[i]; + *target++ = spriteIds[i].x; + *target++ = spriteIds[i].y; ++instanceCount; stack.Pop(); - if(instanceCount >= 20000) + if(instanceCount >= 16000) restartDrawcall(rnd); } } diff --git a/TSE-RTS/src/shaders/TileMapShader.hpp b/TSE-RTS/src/shaders/TileMapShader.hpp index 8722e7a..789589e 100644 --- a/TSE-RTS/src/shaders/TileMapShader.hpp +++ b/TSE-RTS/src/shaders/TileMapShader.hpp @@ -38,5 +38,6 @@ protected: void OnDisable() const override; void OnFlush() override; void OnDrawCall(int indexCount) override; + void OnPostDraw() override; void OnSubmit(const TSE::Transformable& t, float*& target, TSE::TransformationStack& stack, void (*restartDrawcall)(TSE::IRenderer&), TSE::IRenderer& rnd) override; }; diff --git a/TSE-RTS/src/shaders/TileMapShaderGLSL.hpp b/TSE-RTS/src/shaders/TileMapShaderGLSL.hpp index ebb1099..99eea45 100644 --- a/TSE-RTS/src/shaders/TileMapShaderGLSL.hpp +++ b/TSE-RTS/src/shaders/TileMapShaderGLSL.hpp @@ -7,6 +7,7 @@ inline const char* vertTile2 = R"( layout(location = 1) in vec3 iTilePos; layout(location = 2) in float iSpriteId; + layout(location = 3) in float iNormalId; uniform mat4 prMatrix; uniform mat4 camMatrix; @@ -15,6 +16,7 @@ inline const char* vertTile2 = R"( out vec2 vUV; flat out int vSpriteId; + flat out int vNormalId; void main() { @@ -28,6 +30,7 @@ inline const char* vertTile2 = R"( vUV = baseUV; vSpriteId = int(iSpriteId + 0.5); + vNormalId = int(iNormalId + 0.5); } )"; @@ -36,6 +39,7 @@ inline const char* fragTile2 = R"( in vec2 vUV; flat in int vSpriteId; + flat in int vNormalId; uniform sampler2D atlas; uniform vec2 spriteCount; @@ -51,15 +55,26 @@ inline const char* fragTile2 = R"( 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; - FragHeight = vec4(0,0,layerHeight,1); + + 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; + } } )";