made improvements with MRT, and the render pipeline, and made shure, that the software works in non editor mode too
This commit is contained in:
2
TSE
2
TSE
Submodule TSE updated: 45501f153d...769bbd4261
Binary file not shown.
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.8 KiB |
17
TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.cpp
Normal file
17
TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.cpp
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.hpp
Normal file
25
TSE-RTS/src/BehaviourScripts/CameraSizeChangeNotifyer.hpp
Normal file
@@ -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";
|
||||||
|
}
|
||||||
|
};
|
||||||
13
TSE-RTS/src/BehaviourScripts/CanvasScaler.cpp
Normal file
13
TSE-RTS/src/BehaviourScripts/CanvasScaler.cpp
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
TSE-RTS/src/BehaviourScripts/CanvasScaler.hpp
Normal file
24
TSE-RTS/src/BehaviourScripts/CanvasScaler.hpp
Normal file
@@ -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";
|
||||||
|
}
|
||||||
|
};
|
||||||
13
TSE-RTS/src/BehaviourScripts/RenderTextureResizes.cpp
Normal file
13
TSE-RTS/src/BehaviourScripts/RenderTextureResizes.cpp
Normal file
@@ -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);
|
||||||
|
}
|
||||||
23
TSE-RTS/src/BehaviourScripts/RenderTextureResizes.hpp
Normal file
23
TSE-RTS/src/BehaviourScripts/RenderTextureResizes.hpp
Normal file
@@ -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";
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -6,11 +6,17 @@
|
|||||||
#include "Vector2.hpp"
|
#include "Vector2.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "PerlinNoise.hpp"
|
#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 circleRadius 32
|
||||||
#define circleFallof 25
|
#define circleFallof 25
|
||||||
|
|
||||||
void game::setup(TSE::Scene* s)
|
void game::setup(TSE::Scene* s, TSE::IWindow* wnd)
|
||||||
{
|
{
|
||||||
using namespace TSE;
|
using namespace TSE;
|
||||||
s->AddLayer(&gameLayer);
|
s->AddLayer(&gameLayer);
|
||||||
@@ -61,22 +67,81 @@ void game::setup(TSE::Scene* s)
|
|||||||
{
|
{
|
||||||
if(noise >= 0.8f)
|
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)
|
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)
|
else if(noise >= 0.4f)
|
||||||
{
|
{
|
||||||
maps[1]->SetTile(Vector2(x, y), {0,9});
|
maps[1]->SetTile(Vector2(x, y), {0,9}, {2,9});
|
||||||
}
|
}
|
||||||
else
|
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<float>("threshold", 0.01f);
|
||||||
|
canvasMat->SetValue<float>("darken", 0.45f);
|
||||||
|
canvasMat->SetValue<uint>("colorTextureID", rt->GetTextureId(0));
|
||||||
|
canvasMat->SetValue<uint>("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
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "elements/Scene.hpp"
|
#include "elements/Scene.hpp"
|
||||||
|
#include "interfaces/IWindow.hpp"
|
||||||
|
|
||||||
class game
|
class game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline static TSE::Layer gameLayer = TSE::Layer("gameLayer");
|
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);
|
||||||
};
|
};
|
||||||
@@ -16,8 +16,9 @@
|
|||||||
#include "EditorSubsystem.hpp"
|
#include "EditorSubsystem.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "shaders/TileMapShader.hpp"
|
#include "shaders/TileMapShader.hpp"
|
||||||
|
#include "shaders/LastPassShader.hpp"
|
||||||
|
|
||||||
#define USE_EDITOR
|
//#define USE_EDITOR
|
||||||
|
|
||||||
using namespace TSE;
|
using namespace TSE;
|
||||||
using namespace TSE::GLFW;
|
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);
|
wnd = new WindowGlfw(PROJECT_NAME, 800, 600, new OpenGLRenderingBackend(backColor, false, 8, true), WindowType::Maximized);
|
||||||
editor = new EditorSubsystem();
|
editor = new EditorSubsystem();
|
||||||
#else
|
#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
|
#endif
|
||||||
LoadBasicShaders(wnd->GetSize().x, wnd->GetSize().y);
|
LoadBasicShaders(wnd->GetSize().x, wnd->GetSize().y);
|
||||||
TileMapShader::Init(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("TileMapShader v2", TileMapShader::Instance());
|
||||||
|
ShaderRegistry::SetShader("LastPassShader", LastPassShader::Instance());
|
||||||
|
|
||||||
rend = new DefaultRendererOpenGL(*BasicShader::Instance());
|
rend = new DefaultRendererOpenGL(*BasicShader::Instance());
|
||||||
currentScene = new Scene();
|
currentScene = new Scene();
|
||||||
|
|
||||||
game::setup(currentScene);
|
|
||||||
|
|
||||||
#ifdef USE_EDITOR
|
#ifdef USE_EDITOR
|
||||||
|
((Camera*)Transformable::Find(".EditorCamera")->GetBehaviourScript(CAMERA))->layersNotToRender.push_back(game::renderingLayer.GetID());
|
||||||
currentScene->AddLayer(&editor->editorLayer);
|
currentScene->AddLayer(&editor->editorLayer);
|
||||||
editor->hv.SetScene(currentScene);
|
editor->hv.SetScene(currentScene);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
game::setup(currentScene, wnd);
|
||||||
|
|
||||||
|
wnd->DoneSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanUp()
|
void CleanUp()
|
||||||
|
|||||||
109
TSE-RTS/src/shaders/LastPassShader.cpp
Normal file
109
TSE-RTS/src/shaders/LastPassShader.cpp
Normal file
@@ -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<std::unique_ptr<ShaderPart>> 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<std::unique_ptr<TSE::GLFW::ShaderPart>> &&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<Renderable*>(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<uint>("colorTextureID");
|
||||||
|
HeightTextureID = r->GetMaterial()->GetValue<uint>("heightTextureID");
|
||||||
|
Threshold = r->GetMaterial()->GetValue<float>("threshold");
|
||||||
|
Darken = r->GetMaterial()->GetValue<float>("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();
|
||||||
|
}
|
||||||
29
TSE-RTS/src/shaders/LastPassShader.hpp
Normal file
29
TSE-RTS/src/shaders/LastPassShader.hpp
Normal file
@@ -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<std::unique_ptr<TSE::GLFW::ShaderPart>>&& 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;
|
||||||
|
};
|
||||||
96
TSE-RTS/src/shaders/LastPassShaderGLSL.hpp
Normal file
96
TSE-RTS/src/shaders/LastPassShaderGLSL.hpp
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
)";
|
||||||
@@ -10,8 +10,9 @@ using namespace TSE::GLFW;
|
|||||||
#define SHADER_MESH_INDEX 0
|
#define SHADER_MESH_INDEX 0
|
||||||
#define SHADER_POS_INDEX 1
|
#define SHADER_POS_INDEX 1
|
||||||
#define SHADER_SPRITE_INDEX 2
|
#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;
|
TileMapShader* TileMapShader::instance = nullptr;
|
||||||
|
|
||||||
@@ -122,6 +123,11 @@ void TileMapShader::OnEnable() const
|
|||||||
glEnableVertexAttribArray(SHADER_SPRITE_INDEX);
|
glEnableVertexAttribArray(SHADER_SPRITE_INDEX);
|
||||||
glVertexAttribPointer(SHADER_SPRITE_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*3));
|
glVertexAttribPointer(SHADER_SPRITE_INDEX, 1, GL_FLOAT, GL_FALSE, PackageSize, (void*)(sizeof(float)*3));
|
||||||
glVertexAttribDivisor(SHADER_SPRITE_INDEX, 1);
|
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
|
void TileMapShader::OnDisable() const
|
||||||
@@ -129,12 +135,14 @@ void TileMapShader::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);
|
||||||
|
glDisableVertexAttribArray(SHADER_NORMAL_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileMapShader::OnFlush()
|
void TileMapShader::OnFlush()
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, TextureID);
|
glBindTexture(GL_TEXTURE_2D, TextureID);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileMapShader::OnDrawCall(int indexCount)
|
void TileMapShader::OnDrawCall(int indexCount)
|
||||||
@@ -159,6 +167,11 @@ void TileMapShader::OnDrawCall(int indexCount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)prevElementBuffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)prevElementBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileMapShader::OnPostDraw()
|
||||||
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
instanceCount = 0;
|
instanceCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +190,7 @@ void TileMapShader::OnSubmit(const Transformable &t, float *&target, Transformat
|
|||||||
SpriteCount = tileSet->GetCount();
|
SpriteCount = tileSet->GetCount();
|
||||||
SpriteScale = tm->SpriteScale;
|
SpriteScale = tm->SpriteScale;
|
||||||
|
|
||||||
const 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();
|
||||||
|
|
||||||
@@ -189,10 +200,8 @@ void TileMapShader::OnSubmit(const Transformable &t, float *&target, Transformat
|
|||||||
{
|
{
|
||||||
auto chunk = tm->GetChunk(chunkPos);
|
auto chunk = tm->GetChunk(chunkPos);
|
||||||
const 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++)
|
||||||
@@ -204,12 +213,13 @@ void TileMapShader::OnSubmit(const Transformable &t, float *&target, Transformat
|
|||||||
*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;
|
||||||
|
*target++ = spriteIds[i].y;
|
||||||
|
|
||||||
++instanceCount;
|
++instanceCount;
|
||||||
stack.Pop();
|
stack.Pop();
|
||||||
|
|
||||||
if(instanceCount >= 20000)
|
if(instanceCount >= 16000)
|
||||||
restartDrawcall(rnd);
|
restartDrawcall(rnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,5 +38,6 @@ protected:
|
|||||||
void OnDisable() const override;
|
void OnDisable() const override;
|
||||||
void OnFlush() override;
|
void OnFlush() override;
|
||||||
void OnDrawCall(int indexCount) 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;
|
void OnSubmit(const TSE::Transformable& t, float*& target, TSE::TransformationStack& stack, void (*restartDrawcall)(TSE::IRenderer&), TSE::IRenderer& rnd) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ inline const char* vertTile2 = R"(
|
|||||||
|
|
||||||
layout(location = 1) in vec3 iTilePos;
|
layout(location = 1) in vec3 iTilePos;
|
||||||
layout(location = 2) in float iSpriteId;
|
layout(location = 2) in float iSpriteId;
|
||||||
|
layout(location = 3) in float iNormalId;
|
||||||
|
|
||||||
uniform mat4 prMatrix;
|
uniform mat4 prMatrix;
|
||||||
uniform mat4 camMatrix;
|
uniform mat4 camMatrix;
|
||||||
@@ -15,6 +16,7 @@ inline const char* vertTile2 = R"(
|
|||||||
|
|
||||||
out vec2 vUV;
|
out vec2 vUV;
|
||||||
flat out int vSpriteId;
|
flat out int vSpriteId;
|
||||||
|
flat out int vNormalId;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@@ -28,6 +30,7 @@ inline const char* vertTile2 = R"(
|
|||||||
|
|
||||||
vUV = baseUV;
|
vUV = baseUV;
|
||||||
vSpriteId = int(iSpriteId + 0.5);
|
vSpriteId = int(iSpriteId + 0.5);
|
||||||
|
vNormalId = int(iNormalId + 0.5);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@@ -36,6 +39,7 @@ inline const char* fragTile2 = R"(
|
|||||||
|
|
||||||
in vec2 vUV;
|
in vec2 vUV;
|
||||||
flat in int vSpriteId;
|
flat in int vSpriteId;
|
||||||
|
flat in int vNormalId;
|
||||||
|
|
||||||
uniform sampler2D atlas;
|
uniform sampler2D atlas;
|
||||||
uniform vec2 spriteCount;
|
uniform vec2 spriteCount;
|
||||||
@@ -60,6 +64,17 @@ inline const char* fragTile2 = R"(
|
|||||||
c = vec4(c.x * colorScaler,c.y * colorScaler,c.z * colorScaler,c.w);
|
c = vec4(c.x * colorScaler,c.y * colorScaler,c.z * colorScaler,c.w);
|
||||||
|
|
||||||
FragColor = c;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|||||||
Reference in New Issue
Block a user