Moved a few things to shader buffers, added some bugs that I have to fix
This commit is contained in:
@ -11,7 +11,7 @@
|
|||||||
</item>
|
</item>
|
||||||
|
|
||||||
<item>
|
<item>
|
||||||
<UICanvas ref="canvas" />
|
<UICanvas ref="canvas" camera="camera" />
|
||||||
<item ref="textbox" prefab="prefabs/VNTextbox" />
|
<item ref="textbox" prefab="prefabs/VNTextbox" />
|
||||||
|
|
||||||
<item>
|
<item>
|
||||||
|
@ -226,9 +226,8 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
|||||||
// Now we've sorted everything! Let's actually start rendering.
|
// Now we've sorted everything! Let's actually start rendering.
|
||||||
Shader *boundShader = nullptr;
|
Shader *boundShader = nullptr;
|
||||||
std::map<textureslot_t, Texture*> boundTextures;
|
std::map<textureslot_t, Texture*> boundTextures;
|
||||||
std::map<shaderbufferlocation_t, shaderbufferslot_t> locationSlotMap;
|
std::map<shaderbufferlocation_t, shaderbufferslot_t> boundBuffers;
|
||||||
std::map<IShaderParameterBuffer<shaderbufferlocation_t>*, shaderbufferslot_t> bufferSlotMap;
|
shaderbufferslot_t slot;
|
||||||
shaderbufferslot_t globalSlot = 0;
|
|
||||||
|
|
||||||
// TODO: This will be editable!
|
// TODO: This will be editable!
|
||||||
renderTarget->bind();
|
renderTarget->bind();
|
||||||
@ -262,25 +261,14 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bind the buffers to their slots
|
// Bind the buffers to their slots
|
||||||
|
slot = 0;
|
||||||
auto itBufferSlot = item.parameterBuffers.begin();
|
auto itBufferSlot = item.parameterBuffers.begin();
|
||||||
while(itBufferSlot != item.parameterBuffers.end()) {
|
while(itBufferSlot != item.parameterBuffers.end()) {
|
||||||
// First check if buffer is already bound
|
|
||||||
auto location = itBufferSlot->first;
|
auto location = itBufferSlot->first;
|
||||||
auto buff = itBufferSlot->second;
|
auto buff = itBufferSlot->second;
|
||||||
// auto existingBind = bufferSlotMap.find(buff);
|
boundBuffers[itBufferSlot->first] = slot;
|
||||||
shaderbufferslot_t slot;
|
|
||||||
|
|
||||||
// if(existingBind == bufferSlotMap.end()) {
|
|
||||||
// Not bound, let's find a slot we can use!
|
|
||||||
// slot = -1;
|
|
||||||
slot = globalSlot++;
|
|
||||||
// } else {
|
|
||||||
// // Already bound
|
|
||||||
// slot = existingBind->second;
|
|
||||||
// }
|
|
||||||
|
|
||||||
buff->bind(slot);
|
buff->bind(slot);
|
||||||
locationSlotMap[itBufferSlot->first] = slot;
|
slot++;
|
||||||
++itBufferSlot;
|
++itBufferSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +305,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
|||||||
|
|
||||||
auto itBuffer = item.parameterBuffers.begin();
|
auto itBuffer = item.parameterBuffers.begin();
|
||||||
while(itBuffer != item.parameterBuffers.end()) {
|
while(itBuffer != item.parameterBuffers.end()) {
|
||||||
item.shader->setParameterBuffer(itBuffer->first, locationSlotMap[itBuffer->first]);
|
item.shader->setParameterBuffer(itBuffer->first, boundBuffers[itBuffer->first]);
|
||||||
++itBuffer;
|
++itBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,17 +26,11 @@ float_t UIBorder::getContentHeight() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<struct ShaderPassItem> UIBorder::getRenderPasses() {
|
std::vector<struct ShaderPassItem> UIBorder::getRenderPasses() {
|
||||||
glm::mat4 view, proj;
|
|
||||||
auto canvas = this->getCanvas();
|
|
||||||
assertNotNull(canvas);
|
|
||||||
canvas->getProjectionAndView(&proj, &view);
|
|
||||||
|
|
||||||
struct ShaderPassItem item;
|
struct ShaderPassItem item;
|
||||||
auto shader = getGame()->renderManager.uiShader;
|
auto shader = getGame()->renderManager.uiShader;
|
||||||
item.shader = shader;
|
item.shader = shader;
|
||||||
item.colorValues[shader->paramColor] = COLOR_WHITE;
|
item.colorValues[shader->paramColor] = COLOR_WHITE;
|
||||||
item.matrixValues[shader->paramProjection] = proj;
|
item.parameterBuffers[shader->bufferUiCanvas] = &this->getCanvas()->shaderBuffer;
|
||||||
item.matrixValues[shader->paramView] = view;
|
|
||||||
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
|
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
|
||||||
if(this->texture == nullptr) {
|
if(this->texture == nullptr) {
|
||||||
item.boolValues[shader->paramHasTexture] = false;
|
item.boolValues[shader->paramHasTexture] = false;
|
||||||
|
@ -20,6 +20,32 @@ UICanvas::UICanvas(SceneItem *item) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UICanvas::rebufferShaderParameters() {
|
||||||
|
struct UICanvasShaderParameterBufferData data;
|
||||||
|
|
||||||
|
switch(this->drawType) {
|
||||||
|
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
|
||||||
|
data.projection = camera->getProjection();
|
||||||
|
data.view = camera->transform->getWorldTransform();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
||||||
|
data.projection = glm::ortho(
|
||||||
|
0.0f,
|
||||||
|
camera->getRenderTarget()->getWidth(),
|
||||||
|
camera->getRenderTarget()->getHeight(),
|
||||||
|
0.0f
|
||||||
|
);
|
||||||
|
data.view = glm::mat4(1.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assertUnreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->shaderBuffer.buffer(&data);
|
||||||
|
}
|
||||||
|
|
||||||
float_t UICanvas::getWidth() {
|
float_t UICanvas::getWidth() {
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
@ -36,41 +62,22 @@ float_t UICanvas::getContentHeight() {
|
|||||||
return this->getHeight();
|
return this->getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UICanvas::getProjectionAndView(glm::mat4 *proj, glm::mat4 *view) {
|
|
||||||
assertNotNull(proj);
|
|
||||||
assertNotNull(view);
|
|
||||||
|
|
||||||
switch(this->drawType) {
|
|
||||||
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
|
|
||||||
*proj = camera->getProjection();
|
|
||||||
*view = camera->transform->getWorldTransform();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
|
||||||
*proj = glm::ortho(
|
|
||||||
0.0f,
|
|
||||||
camera->getRenderTarget()->getWidth(),
|
|
||||||
camera->getRenderTarget()->getHeight(),
|
|
||||||
0.0f
|
|
||||||
);
|
|
||||||
*view = glm::mat4(1.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assertUnreachable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UICanvas::onStart() {
|
void UICanvas::onStart() {
|
||||||
if(camera == nullptr) camera = getScene()->findComponent<Camera>();
|
if(camera == nullptr) camera = getScene()->findComponent<Camera>();
|
||||||
|
|
||||||
|
this->shaderBuffer.init();
|
||||||
|
this->rebufferShaderParameters();
|
||||||
|
|
||||||
useEffectWithTeardown([&]{
|
useEffectWithTeardown([&]{
|
||||||
if(camera == nullptr) return evtRenderResize = [&] {};
|
if(camera == nullptr) return evtRenderResize = [&] {};
|
||||||
this->w = camera->getRenderTarget()->getWidth();
|
this->w = camera->getRenderTarget()->getWidth();
|
||||||
this->h = camera->getRenderTarget()->getHeight();
|
this->h = camera->getRenderTarget()->getHeight();
|
||||||
|
this->rebufferShaderParameters();
|
||||||
|
|
||||||
return evtRenderResize = useEvent([&](float_t w, float_t h){
|
return evtRenderResize = useEvent([&](float_t w, float_t h){
|
||||||
this->w = w;
|
this->w = w;
|
||||||
this->h = h;
|
this->h = h;
|
||||||
|
this->rebufferShaderParameters();
|
||||||
|
|
||||||
auto comps = this->item->findChildren<UIComponent>();
|
auto comps = this->item->findChildren<UIComponent>();
|
||||||
auto itComps = comps.begin();
|
auto itComps = comps.begin();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "scene/SceneItemComponent.hpp"
|
#include "scene/SceneItemComponent.hpp"
|
||||||
#include "display/RenderTarget.hpp"
|
#include "display/RenderTarget.hpp"
|
||||||
#include "scene/components/display/Camera.hpp"
|
#include "scene/components/display/Camera.hpp"
|
||||||
|
#include "display/shader/shaders/UIShader.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class UIComponentDimensional {
|
class UIComponentDimensional {
|
||||||
@ -52,7 +53,15 @@ namespace Dawn {
|
|||||||
float_t w = 1;
|
float_t w = 1;
|
||||||
float_t h = 1;
|
float_t h = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuffers all of the necessary shader buffer data for this canvas to
|
||||||
|
* the GPU.
|
||||||
|
*/
|
||||||
|
void rebufferShaderParameters();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
UICanvasShaderParameterBuffer shaderBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a UI Canvas Scene Item Element, and attaches it to the provided
|
* Creates a UI Canvas Scene Item Element, and attaches it to the provided
|
||||||
* scene.
|
* scene.
|
||||||
@ -73,14 +82,6 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
UICanvas(SceneItem *item);
|
UICanvas(SceneItem *item);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the type of projection and view matrixes are used.
|
|
||||||
*
|
|
||||||
* @param proj Projection matrix output.
|
|
||||||
* @param view View matrix ouput.
|
|
||||||
*/
|
|
||||||
void getProjectionAndView(glm::mat4 *proj, glm::mat4 *view);
|
|
||||||
|
|
||||||
float_t getWidth() override;
|
float_t getWidth() override;
|
||||||
float_t getHeight() override;
|
float_t getHeight() override;
|
||||||
float_t getContentWidth() override;
|
float_t getContentWidth() override;
|
||||||
|
@ -169,6 +169,7 @@ UICanvas * UIComponent::getCanvas() {
|
|||||||
if(canvas != nullptr) return canvas;
|
if(canvas != nullptr) return canvas;
|
||||||
parent = parent->getParent();
|
parent = parent->getParent();
|
||||||
}
|
}
|
||||||
|
assertUnreachable();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,17 +26,11 @@ float_t UIImage::getContentHeight() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<struct ShaderPassItem> UIImage::getRenderPasses() {
|
std::vector<struct ShaderPassItem> UIImage::getRenderPasses() {
|
||||||
glm::mat4 view, proj;
|
|
||||||
auto canvas = this->getCanvas();
|
|
||||||
assertNotNull(canvas);
|
|
||||||
canvas->getProjectionAndView(&proj, &view);
|
|
||||||
|
|
||||||
struct ShaderPassItem item;
|
struct ShaderPassItem item;
|
||||||
auto shader = getGame()->renderManager.uiShader;
|
auto shader = getGame()->renderManager.uiShader;
|
||||||
item.shader = shader;
|
item.shader = shader;
|
||||||
item.colorValues[shader->paramColor] = this->color;
|
item.colorValues[shader->paramColor] = this->color;
|
||||||
item.matrixValues[shader->paramProjection] = proj;
|
item.parameterBuffers[shader->bufferUiCanvas] = &this->getCanvas()->shaderBuffer;
|
||||||
item.matrixValues[shader->paramView] = view;
|
|
||||||
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
|
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
|
||||||
if(this->texture == nullptr) {
|
if(this->texture == nullptr) {
|
||||||
item.boolValues[shader->paramHasTexture] = false;
|
item.boolValues[shader->paramHasTexture] = false;
|
||||||
|
@ -71,17 +71,11 @@ std::vector<struct ShaderPassItem> UILabel::getRenderPasses() {
|
|||||||
if(!this->hasText()) return {};
|
if(!this->hasText()) return {};
|
||||||
this->updateMesh();
|
this->updateMesh();
|
||||||
|
|
||||||
glm::mat4 view, proj;
|
|
||||||
auto canvas = this->getCanvas();
|
|
||||||
assertNotNull(canvas);
|
|
||||||
canvas->getProjectionAndView(&proj, &view);
|
|
||||||
|
|
||||||
struct ShaderPassItem item;
|
struct ShaderPassItem item;
|
||||||
auto shader = getGame()->renderManager.fontShader;
|
auto shader = getGame()->renderManager.uiShader;
|
||||||
item.shader = shader;
|
item.shader = shader;
|
||||||
item.colorValues[shader->paramColor] = textColor;
|
item.colorValues[shader->paramColor] = textColor;
|
||||||
item.matrixValues[shader->paramProjection] = proj;
|
item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer;
|
||||||
item.matrixValues[shader->paramView] = view;
|
|
||||||
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
|
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
|
||||||
item.textureSlots[0] = this->font->getTexture();
|
item.textureSlots[0] = this->font->getTexture();
|
||||||
item.textureValues[shader->paramTexture] = 0;
|
item.textureValues[shader->paramTexture] = 0;
|
||||||
|
@ -10,5 +10,6 @@
|
|||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) {
|
Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) {
|
||||||
return new HelloWorldScene(game);
|
// return new HelloWorldScene(game);
|
||||||
|
return new Scene1Prologue(game);
|
||||||
}
|
}
|
@ -21,8 +21,8 @@ void RenderManager::init() {
|
|||||||
this->lockSimpleTextured = this->shaderManager.lockShader<SimpleTexturedShader>();
|
this->lockSimpleTextured = this->shaderManager.lockShader<SimpleTexturedShader>();
|
||||||
this->simpleTexturedShader = this->shaderManager.getShader<SimpleTexturedShader>(this->lockSimpleTextured);
|
this->simpleTexturedShader = this->shaderManager.getShader<SimpleTexturedShader>(this->lockSimpleTextured);
|
||||||
|
|
||||||
this->lockUIShaderProgram = this->shaderManager.lockShader<SimpleTexturedShader>();
|
this->lockUIShaderProgram = this->shaderManager.lockShader<UIShader>();
|
||||||
this->uiShader = this->shaderManager.getShader<SimpleTexturedShader>(this->lockUIShaderProgram);
|
this->uiShader = this->shaderManager.getShader<UIShader>(this->lockUIShaderProgram);
|
||||||
|
|
||||||
this->lockFontShader = this->shaderManager.lockShader<FontShader>();
|
this->lockFontShader = this->shaderManager.lockShader<FontShader>();
|
||||||
this->fontShader = this->shaderManager.getShader<FontShader>(this->lockFontShader);
|
this->fontShader = this->shaderManager.getShader<FontShader>(this->lockFontShader);
|
||||||
@ -78,6 +78,6 @@ void RenderManager::update() {
|
|||||||
|
|
||||||
RenderManager::~RenderManager() {
|
RenderManager::~RenderManager() {
|
||||||
this->shaderManager.releaseShader<SimpleTexturedShader>(this->lockSimpleTextured);
|
this->shaderManager.releaseShader<SimpleTexturedShader>(this->lockSimpleTextured);
|
||||||
this->shaderManager.releaseShader<SimpleTexturedShader>(this->lockUIShaderProgram);
|
this->shaderManager.releaseShader<UIShader>(this->lockUIShaderProgram);
|
||||||
this->shaderManager.releaseShader<FontShader>(this->lockFontShader);
|
this->shaderManager.releaseShader<FontShader>(this->lockFontShader);
|
||||||
}
|
}
|
@ -27,7 +27,7 @@ namespace Dawn {
|
|||||||
public:
|
public:
|
||||||
BackBufferRenderTarget backBuffer;
|
BackBufferRenderTarget backBuffer;
|
||||||
SimpleTexturedShader *simpleTexturedShader = nullptr;
|
SimpleTexturedShader *simpleTexturedShader = nullptr;
|
||||||
SimpleTexturedShader *uiShader = nullptr;
|
UIShader *uiShader = nullptr;
|
||||||
FontShader *fontShader = nullptr;
|
FontShader *fontShader = nullptr;
|
||||||
ExampleFont defaultFont;
|
ExampleFont defaultFont;
|
||||||
|
|
||||||
|
@ -9,4 +9,5 @@ target_sources(${DAWN_TARGET_NAME}
|
|||||||
FontShader.cpp
|
FontShader.cpp
|
||||||
SimpleTexturedShader.cpp
|
SimpleTexturedShader.cpp
|
||||||
SimpleBillboardedShader.cpp
|
SimpleBillboardedShader.cpp
|
||||||
|
UIShader.cpp
|
||||||
)
|
)
|
||||||
|
@ -10,9 +10,6 @@
|
|||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class SimpleTexturedShader : public Shader {
|
class SimpleTexturedShader : public Shader {
|
||||||
public:
|
public:
|
||||||
shaderparameter_t paramProjection;
|
|
||||||
shaderparameter_t paramView;
|
|
||||||
|
|
||||||
shaderparameter_t paramModel;
|
shaderparameter_t paramModel;
|
||||||
shaderparameter_t paramColor;
|
shaderparameter_t paramColor;
|
||||||
shaderparameter_t paramTexture;
|
shaderparameter_t paramTexture;
|
||||||
|
61
src/dawnopengl/display/shader/shaders/UIShader.cpp
Normal file
61
src/dawnopengl/display/shader/shaders/UIShader.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Copyright (c) 2023 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#include "UIShader.hpp"
|
||||||
|
|
||||||
|
using namespace Dawn;
|
||||||
|
|
||||||
|
void UIShader::compile() {
|
||||||
|
#if DAWN_OPENGL_GLSL
|
||||||
|
this->compileShader(
|
||||||
|
{
|
||||||
|
{ "aPos", 0 },
|
||||||
|
{ "aTexCoord", 1 }
|
||||||
|
},
|
||||||
|
// Vertex Shader
|
||||||
|
"#version 330 core\n"
|
||||||
|
"layout (location = 0) in vec3 aPos;\n"
|
||||||
|
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||||
|
|
||||||
|
"layout (std140) uniform ub_UICanvas {\n"
|
||||||
|
"mat4 u_View;\n"
|
||||||
|
"mat4 u_Projection;\n"
|
||||||
|
"};"
|
||||||
|
|
||||||
|
"uniform mat4 u_Model;\n"
|
||||||
|
|
||||||
|
"out vec2 o_TextCoord;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
"gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n"
|
||||||
|
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
|
||||||
|
"}",
|
||||||
|
|
||||||
|
// Fragment Shader
|
||||||
|
"#version 330 core\n"
|
||||||
|
|
||||||
|
"in vec2 o_TextCoord;\n"
|
||||||
|
"out vec4 o_Color;\n"
|
||||||
|
"uniform vec4 u_Color;\n"
|
||||||
|
"uniform bool u_HasTexture;\n"
|
||||||
|
"uniform sampler2D u_Text;\n"
|
||||||
|
|
||||||
|
"void main() {\n"
|
||||||
|
"if(u_HasTexture) {\n"
|
||||||
|
"o_Color = texture(u_Text, o_TextCoord) * u_Color;\n"
|
||||||
|
"} else {\n"
|
||||||
|
"o_Color = u_Color;"
|
||||||
|
"}\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
#error Shader Type must be GLSL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this->paramModel = this->getParameterByName("u_Model");
|
||||||
|
this->paramColor = this->getParameterByName("u_Color");
|
||||||
|
this->paramTexture = this->getParameterByName("u_Text");
|
||||||
|
this->paramHasTexture = this->getParameterByName("u_HasTexture");
|
||||||
|
this->bufferUiCanvas = this->getBufferLocationByName("ub_UICanvas");
|
||||||
|
}
|
@ -4,11 +4,30 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "SimpleTexturedShader.hpp"
|
#include "display/shader/buffers/RenderPipelineShaderBuffer.hpp"
|
||||||
|
#include "display/shader/Shader.hpp"
|
||||||
|
|
||||||
#define UI_SHADER_PROGRAM_PRIORITY 100
|
#define UI_SHADER_PROGRAM_PRIORITY 100
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class UIShader : public SimpleTexturedShader {
|
struct UICanvasShaderParameterBufferData {
|
||||||
|
glm::mat4 projection;
|
||||||
|
glm::mat4 view;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UICanvasShaderParameterBuffer :
|
||||||
|
public ShaderParameterBuffer<struct UICanvasShaderParameterBufferData>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class UIShader : public Shader {
|
||||||
|
public:
|
||||||
|
shaderparameter_t paramModel;
|
||||||
|
shaderparameter_t paramColor;
|
||||||
|
shaderparameter_t paramTexture;
|
||||||
|
shaderparameter_t paramHasTexture;
|
||||||
|
shaderbufferlocation_t bufferUiCanvas;
|
||||||
|
|
||||||
|
void compile() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
Reference in New Issue
Block a user