Initial RmlUI Integration

This commit is contained in:
Isuru Samarathunga
2025-09-20 20:25:26 +05:30
parent ece65b18da
commit 6a6debb0db
11 changed files with 401 additions and 35 deletions

View File

@ -6,7 +6,6 @@
#include <IACore/File.hpp>
namespace ia::iae::game
{
RefPtr<Scene> scene;
@ -26,8 +25,8 @@ namespace ia::iae::game
.ShouldLoop = true,
.Keys = {
SpriteRendererComponent::AnimationKeyFrame {
.Texture = Engine::CreateTexture(File::ReadToVector("Graphics/green.png")),
.Scale = {0.1f, 0.1f},
.Scale = {0.25f, 0.25f},
.ColorOverlay = {0.0f, 0.75f, 0.0f, 1.0f}
}
},
});
@ -42,8 +41,8 @@ namespace ia::iae::game
.ShouldLoop = true,
.Keys = {
SpriteRendererComponent::AnimationKeyFrame {
.Texture = Engine::CreateTexture(File::ReadToVector("Graphics/red.png")),
.Scale = {0.25f, 0.25f},
.Scale = {0.5f, 0.5f},
.ColorOverlay = {0.75f, 0.0f, 0.0f, 1.0f}
}
},
});
@ -52,8 +51,8 @@ namespace ia::iae::game
obstacle->SetLocalSortIndex(20);
obstacle->SetLocalPosition({150, 100});
scene->AddNode(g_player);
scene->AddNode(obstacle);
//scene->AddNode(g_player);
//scene->AddNode(obstacle);
}
VOID Game::Terminate()

View File

@ -38,7 +38,7 @@ namespace ia::iae
const auto vertexShader = LoadShaderFromMemory(ShaderStage::VERTEX, SHADER_SOURCE_UNLITMESH_VERT,
sizeof(SHADER_SOURCE_UNLITMESH_VERT), 0, 3, 0, 0);
const auto pixelShader = LoadShaderFromMemory(ShaderStage::PIXEL, SHADER_SOURCE_UNLITMESH_FRAG,
sizeof(SHADER_SOURCE_UNLITMESH_FRAG), 1, 2, 0, 0);
sizeof(SHADER_SOURCE_UNLITMESH_FRAG), 1, 1, 0, 0);
SDL_GPUColorTargetDescription colorTargets[] = {{
.format = SDL_GetGPUSwapchainTextureFormat(g_gpuDevice, g_windowHandle),
@ -55,6 +55,10 @@ namespace ia::iae
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = sizeof(glm::vec3)},
{.location = 2,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4,
.offset = sizeof(glm::vec3) + sizeof(glm::vec2)},
};
SDL_GPUGraphicsPipelineCreateInfo createInfo = {
.vertex_shader = (SDL_GPUShader *) vertexShader,

View File

@ -40,7 +40,9 @@ namespace ia::iae
BOOL FlippedH{false};
BOOL FlippedV{false};
BOOL CameraRelative{true};
BOOL ScissorEnabled{false};
glm::vec2 TextureOffset{0.0f, 0.0f};
SDL_Rect Scissor{0, 0, 0, 0};
};
Vector<Mesh> g_meshes{};
@ -77,8 +79,12 @@ namespace ia::iae
glm::mat4 matIdentity{1.0f};
SDL_Rect g_defaultScissor{};
Handle g_meshHandleQuad{};
RefPtr<GPUTexture> g_whiteTexture{};
BOOL Renderer::Initialize()
{
SDL_GetWindowSizeInPixels(g_windowHandle, &s_width, &s_height);
@ -139,12 +145,26 @@ namespace ia::iae
matProjection = glm::orthoLH(0.0f, (FLOAT32) s_width, (FLOAT32) s_height, 0.0f, -1000.0f, 1000.0f);
g_defaultScissor.x = 0;
g_defaultScissor.y = 0;
g_defaultScissor.w = s_width;
g_defaultScissor.h = s_height;
{
constexpr auto l = 100;
const auto data = new UINT32[l * l];
for (SIZE_T i = 0; i < l * l; i++)
data[i] = 0xFFFFFFFF;
g_whiteTexture = GPUTexture::Create((PCUINT8) data, l, l);
delete[] data;
}
g_meshHandleQuad = CreateMesh(
{
{glm::vec3{0, 1, 0}, glm::vec2{0, 1}},
{glm::vec3{1, 1, 0}, glm::vec2{1, 1}},
{glm::vec3{1, 0, 0}, glm::vec2{1, 0}},
{glm::vec3{0, 0, 0}, glm::vec2{0, 0}},
{glm::vec3{0, 1, 0}, glm::vec2{0, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}},
{glm::vec3{1, 1, 0}, glm::vec2{1, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}},
{glm::vec3{1, 0, 0}, glm::vec2{1, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}},
{glm::vec3{0, 0, 0}, glm::vec2{0, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}},
},
{0, 1, 2, 2, 3, 0});
@ -163,6 +183,8 @@ namespace ia::iae
g_pipelineUnlitMesh.reset();
g_whiteTexture.reset();
GPUTexture::Terminate();
GPUBuffer::TerminateStagingBuffer();
@ -267,6 +289,19 @@ namespace ia::iae
g_renderState.CameraRelative = value;
}
VOID Renderer::SetState_ScissorEnabled(IN BOOL value)
{
g_renderState.ScissorEnabled = value;
}
VOID Renderer::SetState_Scissor(IN CONST glm::vec4 &region)
{
g_renderState.Scissor.x = region.x;
g_renderState.Scissor.y = region.y;
g_renderState.Scissor.w = region.z;
g_renderState.Scissor.h = region.w;
}
VOID Renderer::SetState_TextureOffset(IN FLOAT32 u, IN FLOAT32 v)
{
g_renderState.TextureOffset = {u, v};
@ -319,7 +354,7 @@ namespace ia::iae
SDL_PushGPUVertexUniformData(g_cmdBuffer, 1, &matView, sizeof(matView));
else
SDL_PushGPUVertexUniformData(g_cmdBuffer, 1, &matIdentity, sizeof(matIdentity));
if(Engine::GetActiveScene()->YSortingEnabled())
if (Engine::GetActiveScene()->YSortingEnabled())
sortIndex += static_cast<INT16>(position.y);
matModel =
glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y,
@ -332,11 +367,16 @@ namespace ia::iae
s_fragmentUniform.FlippedH = g_renderState.FlippedH;
s_fragmentUniform.FlippedV = g_renderState.FlippedV;
s_fragmentUniform.TextureOffset = g_renderState.TextureOffset;
SDL_PushGPUFragmentUniformData(g_cmdBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform));
SDL_GPUTextureSamplerBinding textureBinding{.texture = (SDL_GPUTexture *) textureHandle,
SDL_GPUTextureSamplerBinding textureBinding{
.texture = (SDL_GPUTexture *) (textureHandle ? textureHandle : g_whiteTexture->GetHandle()),
.sampler = (SDL_GPUSampler *) GPUTexture::GetDefaultSampler()};
SDL_BindGPUFragmentSamplers(g_renderPass, 0, &textureBinding, 1);
SDL_PushGPUFragmentUniformData(g_cmdBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform));
if (g_renderState.ScissorEnabled)
SDL_SetGPUScissor(g_renderPass, &g_renderState.Scissor);
else
SDL_SetGPUScissor(g_renderPass, &g_defaultScissor);
const auto &mesh = g_meshes[meshHandle];
SDL_GPUBufferBinding bufferBindings[] = {

View File

@ -21,7 +21,7 @@
namespace ia::iae
{
Texture::Texture()
Texture::Texture() : m_handle(0), m_extent({100.0f, 100.0f})
{
}

View File

@ -14,9 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <IAEngine/IAEngine.hpp>
#include <IAEngine/Rendering/GPUTexture.hpp>
#include <IAEngine/Rendering/Renderer.hpp>
#include <IAEngine/UI.hpp>
#include <RmlUi/Core.h>
#include <RmlUi/Debugger.h>
#include <SDL3/SDL_events.h>
namespace ia::iae
{
@ -35,38 +41,325 @@ namespace ia::iae
void SetScissorRegion(Rml::Rectanglei region);
};
//RmlUIRenderInterface g_rmlUIRenderInterface{};
Vector<Texture> g_textures;
RmlUIRenderInterface g_rmlUIRenderInterface{};
/* Taken from https://github.com/mikke89/RmlUi/blob/master/Backends/RmlUi_Platform_SDL.cpp */
INT32 GetKeyModifierState()
{
SDL_Keymod sdl_mods = SDL_GetModState();
INT32 keymods = 0;
if (sdl_mods & SDL_KMOD_CTRL)
keymods |= Rml::Input::KM_CTRL;
if (sdl_mods & SDL_KMOD_SHIFT)
keymods |= Rml::Input::KM_SHIFT;
if (sdl_mods & SDL_KMOD_ALT)
keymods |= Rml::Input::KM_ALT;
if (sdl_mods & SDL_KMOD_NUM)
keymods |= Rml::Input::KM_NUMLOCK;
if (sdl_mods & SDL_KMOD_CAPS)
keymods |= Rml::Input::KM_CAPSLOCK;
return keymods;
}
/* Taken from https://github.com/mikke89/RmlUi/blob/master/Backends/RmlUi_Platform_SDL.cpp */
INT32 SDLMouseButtonToRml(IN INT32 button)
{
switch (button)
{
case SDL_BUTTON_LEFT:
return 0;
case SDL_BUTTON_RIGHT:
return 1;
case SDL_BUTTON_MIDDLE:
return 2;
default:
break;
}
return 3;
}
/* Taken from https://github.com/mikke89/RmlUi/blob/master/Backends/RmlUi_Platform_SDL.cpp */
Rml::Input::KeyIdentifier SDLKeyToRml(int sdlkey)
{
switch (sdlkey)
{
case SDLK_UNKNOWN:
return Rml::Input::KI_UNKNOWN;
case SDLK_ESCAPE:
return Rml::Input::KI_ESCAPE;
case SDLK_SPACE:
return Rml::Input::KI_SPACE;
case SDLK_0:
return Rml::Input::KI_0;
case SDLK_1:
return Rml::Input::KI_1;
case SDLK_2:
return Rml::Input::KI_2;
case SDLK_3:
return Rml::Input::KI_3;
case SDLK_4:
return Rml::Input::KI_4;
case SDLK_5:
return Rml::Input::KI_5;
case SDLK_6:
return Rml::Input::KI_6;
case SDLK_7:
return Rml::Input::KI_7;
case SDLK_8:
return Rml::Input::KI_8;
case SDLK_9:
return Rml::Input::KI_9;
case SDLK_A:
return Rml::Input::KI_A;
case SDLK_B:
return Rml::Input::KI_B;
case SDLK_C:
return Rml::Input::KI_C;
case SDLK_D:
return Rml::Input::KI_D;
case SDLK_E:
return Rml::Input::KI_E;
case SDLK_F:
return Rml::Input::KI_F;
case SDLK_G:
return Rml::Input::KI_G;
case SDLK_H:
return Rml::Input::KI_H;
case SDLK_I:
return Rml::Input::KI_I;
case SDLK_J:
return Rml::Input::KI_J;
case SDLK_K:
return Rml::Input::KI_K;
case SDLK_L:
return Rml::Input::KI_L;
case SDLK_M:
return Rml::Input::KI_M;
case SDLK_N:
return Rml::Input::KI_N;
case SDLK_O:
return Rml::Input::KI_O;
case SDLK_P:
return Rml::Input::KI_P;
case SDLK_Q:
return Rml::Input::KI_Q;
case SDLK_R:
return Rml::Input::KI_R;
case SDLK_S:
return Rml::Input::KI_S;
case SDLK_T:
return Rml::Input::KI_T;
case SDLK_U:
return Rml::Input::KI_U;
case SDLK_V:
return Rml::Input::KI_V;
case SDLK_W:
return Rml::Input::KI_W;
case SDLK_X:
return Rml::Input::KI_X;
case SDLK_Y:
return Rml::Input::KI_Y;
case SDLK_Z:
return Rml::Input::KI_Z;
case SDLK_SEMICOLON:
return Rml::Input::KI_OEM_1;
case SDLK_PLUS:
return Rml::Input::KI_OEM_PLUS;
case SDLK_COMMA:
return Rml::Input::KI_OEM_COMMA;
case SDLK_MINUS:
return Rml::Input::KI_OEM_MINUS;
case SDLK_PERIOD:
return Rml::Input::KI_OEM_PERIOD;
case SDLK_SLASH:
return Rml::Input::KI_OEM_2;
case SDLK_GRAVE:
return Rml::Input::KI_OEM_3;
case SDLK_LEFTBRACKET:
return Rml::Input::KI_OEM_4;
case SDLK_BACKSLASH:
return Rml::Input::KI_OEM_5;
case SDLK_RIGHTBRACKET:
return Rml::Input::KI_OEM_6;
case SDLK_DBLAPOSTROPHE:
return Rml::Input::KI_OEM_7;
case SDLK_KP_0:
return Rml::Input::KI_NUMPAD0;
case SDLK_KP_1:
return Rml::Input::KI_NUMPAD1;
case SDLK_KP_2:
return Rml::Input::KI_NUMPAD2;
case SDLK_KP_3:
return Rml::Input::KI_NUMPAD3;
case SDLK_KP_4:
return Rml::Input::KI_NUMPAD4;
case SDLK_KP_5:
return Rml::Input::KI_NUMPAD5;
case SDLK_KP_6:
return Rml::Input::KI_NUMPAD6;
case SDLK_KP_7:
return Rml::Input::KI_NUMPAD7;
case SDLK_KP_8:
return Rml::Input::KI_NUMPAD8;
case SDLK_KP_9:
return Rml::Input::KI_NUMPAD9;
case SDLK_KP_ENTER:
return Rml::Input::KI_NUMPADENTER;
case SDLK_KP_MULTIPLY:
return Rml::Input::KI_MULTIPLY;
case SDLK_KP_PLUS:
return Rml::Input::KI_ADD;
case SDLK_KP_MINUS:
return Rml::Input::KI_SUBTRACT;
case SDLK_KP_PERIOD:
return Rml::Input::KI_DECIMAL;
case SDLK_KP_DIVIDE:
return Rml::Input::KI_DIVIDE;
case SDLK_KP_EQUALS:
return Rml::Input::KI_OEM_NEC_EQUAL;
case SDLK_BACKSPACE:
return Rml::Input::KI_BACK;
case SDLK_TAB:
return Rml::Input::KI_TAB;
case SDLK_CLEAR:
return Rml::Input::KI_CLEAR;
case SDLK_RETURN:
return Rml::Input::KI_RETURN;
case SDLK_PAUSE:
return Rml::Input::KI_PAUSE;
case SDLK_CAPSLOCK:
return Rml::Input::KI_CAPITAL;
case SDLK_PAGEUP:
return Rml::Input::KI_PRIOR;
case SDLK_PAGEDOWN:
return Rml::Input::KI_NEXT;
case SDLK_END:
return Rml::Input::KI_END;
case SDLK_HOME:
return Rml::Input::KI_HOME;
case SDLK_LEFT:
return Rml::Input::KI_LEFT;
case SDLK_UP:
return Rml::Input::KI_UP;
case SDLK_RIGHT:
return Rml::Input::KI_RIGHT;
case SDLK_DOWN:
return Rml::Input::KI_DOWN;
case SDLK_INSERT:
return Rml::Input::KI_INSERT;
case SDLK_DELETE:
return Rml::Input::KI_DELETE;
case SDLK_HELP:
return Rml::Input::KI_HELP;
case SDLK_F1:
return Rml::Input::KI_F1;
case SDLK_F2:
return Rml::Input::KI_F2;
case SDLK_F3:
return Rml::Input::KI_F3;
case SDLK_F4:
return Rml::Input::KI_F4;
case SDLK_F5:
return Rml::Input::KI_F5;
case SDLK_F6:
return Rml::Input::KI_F6;
case SDLK_F7:
return Rml::Input::KI_F7;
case SDLK_F8:
return Rml::Input::KI_F8;
case SDLK_F9:
return Rml::Input::KI_F9;
case SDLK_F10:
return Rml::Input::KI_F10;
case SDLK_F11:
return Rml::Input::KI_F11;
case SDLK_F12:
return Rml::Input::KI_F12;
case SDLK_F13:
return Rml::Input::KI_F13;
case SDLK_F14:
return Rml::Input::KI_F14;
case SDLK_F15:
return Rml::Input::KI_F15;
case SDLK_NUMLOCKCLEAR:
return Rml::Input::KI_NUMLOCK;
case SDLK_SCROLLLOCK:
return Rml::Input::KI_SCROLL;
case SDLK_LSHIFT:
return Rml::Input::KI_LSHIFT;
case SDLK_RSHIFT:
return Rml::Input::KI_RSHIFT;
case SDLK_LCTRL:
return Rml::Input::KI_LCONTROL;
case SDLK_RCTRL:
return Rml::Input::KI_RCONTROL;
case SDLK_LALT:
return Rml::Input::KI_LMENU;
case SDLK_RALT:
return Rml::Input::KI_RMENU;
case SDLK_LGUI:
return Rml::Input::KI_LMETA;
case SDLK_RGUI:
return Rml::Input::KI_RMETA;
default:
break;
}
return Rml::Input::KI_UNKNOWN;
}
} // namespace ia::iae
namespace ia::iae
{
//Rml::Context* g_context{};
Rml::Context *g_context{};
VOID UI::Initialize(IN INT32 width, IN INT32 height)
{
//Rml::SetRenderInterface(&g_rmlUIRenderInterface);
//Rml::Initialise();
//g_context = Rml::CreateContext("main", Rml::Vector2i(width, height));
Rml::SetRenderInterface(&g_rmlUIRenderInterface);
Rml::Initialise();
g_context = Rml::CreateContext("main", Rml::Vector2i(width, height));
//Rml::Debugger::Initialise(g_context);
//Rml::Debugger::SetVisible(true);
//Rml::LoadFontFace("Roboto-Black.ttf");
}
VOID UI::Terminate()
{
//Rml::Shutdown();
Rml::Shutdown();
}
VOID UI::Update()
{
//g_context->Update();
g_context->Update();
}
VOID UI::Draw()
{
//g_context->Render();
g_context->Render();
}
VOID UI::OnEvent(IN PVOID event)
VOID UI::OnEvent(IN PVOID _event)
{
const auto keymods = GetKeyModifierState();
const auto event = (SDL_Event *) _event;
switch (event->type)
{
case SDL_EventType::SDL_EVENT_MOUSE_MOTION:
g_context->ProcessMouseMove(event->motion.x, event->motion.y, keymods);
break;
case SDL_EventType::SDL_EVENT_MOUSE_BUTTON_UP:
g_context->ProcessMouseButtonUp(SDLMouseButtonToRml(event->button.button), keymods);
break;
case SDL_EventType::SDL_EVENT_MOUSE_BUTTON_DOWN:
g_context->ProcessMouseButtonDown(SDLMouseButtonToRml(event->button.button), keymods);
break;
case SDL_EventType::SDL_EVENT_KEY_DOWN:
g_context->ProcessKeyDown(SDLKeyToRml(event->key.key), keymods);
break;
case SDL_EventType::SDL_EVENT_KEY_UP:
g_context->ProcessKeyUp(SDLKeyToRml(event->key.key), keymods);
break;
}
}
VOID UI::OnResize(IN INT32 width, IN INT32 height)
@ -76,14 +369,31 @@ namespace ia::iae
namespace ia::iae
{
/*Rml::CompiledGeometryHandle RmlUIRenderInterface::CompileGeometry(Rml::Span<const Rml::Vertex> vertices,
Rml::CompiledGeometryHandle RmlUIRenderInterface::CompileGeometry(Rml::Span<const Rml::Vertex> vertices,
Rml::Span<const int> indices)
{
Vector<MeshVertex> _vertices;
Vector<INT32> _indices;
for (const auto &v : vertices)
_vertices.pushBack({glm::vec3{v.position.x, v.position.y, 0.0f}, glm::vec2{v.tex_coord.x, v.tex_coord.y},
glm::vec4{v.colour.red / 255.0f, v.colour.green / 255.0f, v.colour.blue / 255.0f,
v.colour.alpha / 255.0f}});
for (const auto &v : indices)
_indices.pushBack(v);
return Renderer::CreateMesh(_vertices, _indices);
}
void RmlUIRenderInterface::RenderGeometry(Rml::CompiledGeometryHandle geometry, Rml::Vector2f translation,
Rml::TextureHandle texture)
{
Renderer::SetState_FlippedH(false);
Renderer::SetState_FlippedV(false);
Renderer::SetState_CameraRelative(false);
Renderer::SetState_TextureOffset(0, 0);
if (texture)
Renderer::Draw(geometry, g_textures[texture - 1].GetHandle(), {translation.x, translation.y}, {1.0f, 1.0f});
else
Renderer::Draw(geometry, 0, {translation.x, translation.y}, {1.0f, 1.0f});
}
void RmlUIRenderInterface::ReleaseGeometry(Rml::CompiledGeometryHandle geometry)
@ -92,11 +402,15 @@ namespace ia::iae
Rml::TextureHandle RmlUIRenderInterface::LoadTexture(Rml::Vector2i &texture_dimensions, const Rml::String &source)
{
return 0;
}
Rml::TextureHandle RmlUIRenderInterface::GenerateTexture(Rml::Span<const Rml::byte> source,
Rml::Vector2i source_dimensions)
{
g_textures.pushBack(
Engine::CreateTexture((PCUINT8) source.data(), (INT32) source_dimensions.x, (INT32) source_dimensions.y));
return g_textures.size();
}
void RmlUIRenderInterface::ReleaseTexture(Rml::TextureHandle texture)
@ -105,9 +419,11 @@ namespace ia::iae
void RmlUIRenderInterface::EnableScissorRegion(bool enable)
{
Renderer::SetState_ScissorEnabled(enable);
}
void RmlUIRenderInterface::SetScissorRegion(Rml::Rectanglei region)
{
}*/
Renderer::SetState_Scissor({region.Left(), region.Top(), region.Right(), region.Bottom()});
}
} // namespace ia::iae

View File

@ -2,6 +2,7 @@
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec2 inTexCoord;
layout(location = 1) in vec4 inVertexColor;
layout(location = 0) out vec4 outColor;
@ -19,7 +20,7 @@ void main()
uv += ubo.uvOffset;
if(ubo.flippedH) uv.x = 1.0 - uv.x;
if(ubo.flippedV) uv.y = 1.0 - uv.y;
outColor = texture(texSampler, uv) * ubo.colorOverlay;
outColor = texture(texSampler, uv) * inVertexColor * ubo.colorOverlay;
if(outColor.w < 0.1)
discard;
}

View File

@ -3,8 +3,10 @@
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inTexCoord;
layout (location = 2) in vec4 inVertexColor;
layout(location = 0) out vec2 outTexCoord;
layout(location = 1) out vec4 outVertexColor;
layout(set = 1, binding = 0) uniform UBO_Vertex_PerScene {
mat4 projection;
@ -20,4 +22,5 @@ void main()
{
gl_Position = uboPerScene.projection * uboPerFrame.view * uboPerDraw.model * vec4(inPosition, 1.0f);
outTexCoord = inTexCoord;
outVertexColor = inVertexColor;
}

File diff suppressed because one or more lines are too long

View File

@ -47,6 +47,8 @@ namespace ia::iae
STATIC VOID SetState_FlippedH(IN BOOL value);
STATIC VOID SetState_FlippedV(IN BOOL value);
STATIC VOID SetState_CameraRelative(IN BOOL value);
STATIC VOID SetState_ScissorEnabled(IN BOOL value);
STATIC VOID SetState_Scissor(IN CONST glm::vec4& region);
STATIC VOID SetState_TextureOffset(IN FLOAT32 u, IN FLOAT32 v);
public:

View File

@ -24,5 +24,6 @@ namespace ia::iae
{
glm::vec3 Position{};
glm::vec2 UV{};
glm::vec4 Color{};
};
}

View File

@ -23,8 +23,8 @@ namespace ia::iae
class Texture
{
public:
Texture(IN Handle handle, IN INT32 width, IN INT32 height);
Texture();
Texture(IN Handle handle, IN INT32 width, IN INT32 height);
~Texture();
public: