Implemented batched text rendering
This commit is contained in:
parent
ceb25e8e38
commit
17fdf08a20
10 changed files with 722 additions and 943 deletions
BIN
extra/FreeSans.ttf
Normal file
BIN
extra/FreeSans.ttf
Normal file
Binary file not shown.
|
|
@ -5,7 +5,7 @@ $accentColor = Color(rgba(255, 0, 255, 255))
|
|||
const $color2 = Color(#0000FFFF)
|
||||
% -------------------
|
||||
|
||||
window.backgroundColor = Color(rgba(0, 0, 0, 255))
|
||||
window.backgroundColor = Color(rgba(160, 160, 160, 255))
|
||||
|
||||
$accentColor = Color(rgb(255, 0, 0))
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ $accentColor = Color(rgb(255, 0, 0))
|
|||
textColor = $accentColor
|
||||
backgroundColor = Color(#000000FF)
|
||||
borderColor = $accentColor
|
||||
fontSize = 50
|
||||
fontSize = 20
|
||||
borderRadius = 0
|
||||
borderWidth = 2
|
||||
showBackground = true
|
||||
|
|
@ -65,7 +65,7 @@ $accentColor = Color(rgb(255, 0, 0))
|
|||
(@testLabel label) {
|
||||
textColor = $color2
|
||||
backgroundColor = Color(#000000FF)
|
||||
fontSize = 20
|
||||
fontSize = 50
|
||||
}
|
||||
|
||||
(@testLabel2 label) {
|
||||
|
|
@ -108,7 +108,6 @@ $accentColor = Color(rgb(255, 0, 0))
|
|||
(@label3 label) {
|
||||
textColor = $color2
|
||||
backgroundColor = Color(#000000FF)
|
||||
fontSize = 20
|
||||
borderColor = Color(#FF0000FF)
|
||||
borderWidth = 4
|
||||
borderRadius = 15
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ Add theme caching
|
|||
Implement callback for state changes in checkbox
|
||||
FIX: WindowOutputHandler text rendering
|
||||
find a way to add fixed update to gui::Window
|
||||
Implement global scale (probably query desktop scale and adjust accordingly)
|
||||
Fix: Text rendering bug in labels
|
||||
Implement show/hide functionality for widgets
|
||||
Implement wrappers in Renderer2D to take a center and size for rects
|
||||
|
||||
|
||||
|
||||
Implement following widgets:
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2060
|
||||
2061
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ namespace ogfx
|
|||
|
||||
void CheckBox::onMouseReleased(const Event& event)
|
||||
{
|
||||
if (!isMouseInside())
|
||||
return;
|
||||
m_checked = !m_checked;
|
||||
setThemeQualifier("active", m_checked);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,21 +1,21 @@
|
|||
/*
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
|
||||
This file is part of OmniaFramework.
|
||||
This file is part of OmniaFramework.
|
||||
|
||||
OmniaFramework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OmniaFramework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OmniaFramework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
OmniaFramework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
@ -68,7 +68,7 @@ namespace ogfx
|
|||
int32_t openFont(const ostd::String& fontPath, int32_t fontSize = 0);
|
||||
int32_t openFont(const ostd::UByte resource_data[], uint32_t data_size, int32_t fontSize = 0);
|
||||
int32_t setFontSize(int32_t fontSize);
|
||||
ostd::IPoint getStringDimensions(const ostd::String& message, int32_t fontSize = 0);
|
||||
ostd::Vec2 getStringDimensions(const ostd::String& message, int32_t fontSize = 0, TTF_Font* font = nullptr);
|
||||
|
||||
inline uint32_t getDrawCallCount(void) { return m_drawCallCount; }
|
||||
inline bool hasOpenFont(void) { return m_fontOpen; }
|
||||
|
|
@ -80,11 +80,13 @@ namespace ogfx
|
|||
inline bool isInitialized(void) { return m_initialized; }
|
||||
inline FontGlyphAtlas& getFontGlyphAtlas(void) { return m_fontGlyphAtlas; }
|
||||
|
||||
void drawImage(const ogfx::Image& image, const ostd::Vec2& position, const ostd::Vec2& size = { 0, 0 }, const ostd::Rectangle& srcRect = { 0, 0, 0, 0 });
|
||||
void drawAnimation(const Animation& anim, const ostd::Vec2& position, const ostd::Vec2& size = { 0, 0 });
|
||||
void drawImage(const ogfx::Image& image, const ostd::Vec2& position, const ostd::Vec2& size = { 0, 0 }, const ostd::Rectangle& srcRect = { 0, 0, 0, 0 });
|
||||
void drawAnimation(const Animation& anim, const ostd::Vec2& position, const ostd::Vec2& size = { 0, 0 });
|
||||
|
||||
void drawString(const ostd::String& str, const ostd::Vec2& position, const ostd::Color& color, int32_t fontSize = 0, float scale = 1.0f);
|
||||
void drawCenteredString(const ostd::String& str, const ostd::Vec2& center, const ostd::Color& color, int32_t fontSize = 0, float scale = 1.0f);
|
||||
void drawCenteredString(const ostd::String& str, const ostd::Rectangle& bounds, const ostd::Color& color, int32_t fontSize = 0, float scale = 1.0f);
|
||||
|
||||
void drawString(const ostd::String& str, const ostd::Vec2& position, const ostd::Color& color, int32_t fontSize = 0);
|
||||
void drawCenteredString(const ostd::String& str, const ostd::Vec2& center, const ostd::Color& color, int32_t fontSize = 0);
|
||||
|
||||
void drawLine(const ostd::FLine& line, const ostd::Color& color, int32_t thickness = 1, bool rounded = true);
|
||||
|
||||
|
|
@ -106,7 +108,7 @@ namespace ogfx
|
|||
void outlinedCircle(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1);
|
||||
void outlinedEllipse(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1);
|
||||
|
||||
public:
|
||||
private:
|
||||
void init_arrays(void);
|
||||
void generate_half_circle(const ostd::Vec2& center, const ostd::Vec2& dir, float radius, int segments, const ostd::Color& color);
|
||||
void generate_quarter_circle(const ostd::Vec2& center, float radius, float thickness, float startAngle, const ostd::Color& color, int segments);
|
||||
|
|
@ -117,8 +119,6 @@ namespace ogfx
|
|||
void push_polygon(const ostd::Vec2* verts, const ostd::Vec2* texCoords, uint32_t vertCount, const uint32_t* inds, uint32_t indexCount, const ostd::Color& color, SDL_Texture* texture);
|
||||
void print_ttf_error(const ostd::String& funcName);
|
||||
inline int32_t set_error_state(int32_t err) { m_errorState = err; return m_errorState; }
|
||||
void renderText(const ostd::String& message, int32_t x, int32_t y, const ostd::Color& color, int32_t fontSize = 0);
|
||||
void renderCenteredText(const ostd::String& message, int32_t center_x, int32_t center_y, const ostd::Color& color, int32_t fontSize = 0);
|
||||
|
||||
public:
|
||||
inline static constexpr int32_t MaxVertices { 8192 };
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <SDL3/SDL_pixels.h>
|
||||
#include <SDL3/SDL_render.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#include <SDL3_ttf/SDL_ttf.h>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
|
|
@ -37,45 +38,67 @@ namespace ogfx
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool FontGlyphAtlas::rasterize_glyph(const ostd::String& glyphStr, TTF_Font* font, uint32_t fontSize)
|
||||
const std::vector<const FontGlyphAtlas::GlyphInfo*> FontGlyphAtlas::processString(const ostd::String& str, TTF_Font* font, uint32_t fontSize)
|
||||
{
|
||||
if (m_currentAtlasCount <= 0)
|
||||
return {};
|
||||
|
||||
// Pass 1: ensure all glyphs are rasterized (map may rehash here)
|
||||
for (auto& c : str)
|
||||
{
|
||||
const GlyphInfo* dummy;
|
||||
if (!rasterize_glyph(ostd::String("").addChar(c), font, fontSize, &dummy))
|
||||
return {};
|
||||
}
|
||||
|
||||
// Pass 2: collect stable pointers (no more insertions, no rehash risk)
|
||||
std::vector<const GlyphInfo*> glyphs;
|
||||
glyphs.reserve(str.len());
|
||||
for (auto& c : str)
|
||||
{
|
||||
auto cps = ostd::String("").addChar(c).getUTF8Codepoints();
|
||||
if (cps.size() != 1) return {};
|
||||
GlyphKey key { cps[0], uint64_t(font), fontSize };
|
||||
glyphs.push_back(&m_uvs[key]);
|
||||
}
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
bool FontGlyphAtlas::rasterize_glyph(const ostd::String& glyphStr, TTF_Font* font, uint32_t fontSize, const GlyphInfo** outGlyph)
|
||||
{
|
||||
if (!font || m_currentAtlasCount <= 0)
|
||||
return false;
|
||||
|
||||
// 1. Extract codepoint from the ostd::String
|
||||
auto cps = glyphStr.getUTF8Codepoints();
|
||||
if (cps.size() != 1)
|
||||
return false; // must be exactly one character
|
||||
return false;
|
||||
|
||||
uint32_t codepoint = cps[0];
|
||||
|
||||
GlyphKey key { codepoint, uint64_t(font), fontSize };
|
||||
if (auto it = m_uvs.find(key) != m_uvs.end())
|
||||
auto it = m_uvs.find(key);
|
||||
if (it != m_uvs.end())
|
||||
{
|
||||
*outGlyph = &(it->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. Convert the ostd::String to UTF-8 for SDL_ttf
|
||||
std::string utf8 = glyphStr.cpp_str();
|
||||
|
||||
// 3. Rasterize glyph using SDL_ttf
|
||||
SDL_Surface* surf = TTF_RenderText_Blended(font, utf8.c_str(), utf8.length(), SDL_Color{255, 255, 255, 255});
|
||||
|
||||
SDL_Surface* surf = TTF_RenderText_Blended(font, glyphStr.c_str(), glyphStr.len(), SDL_Color{255, 255, 255, 255});
|
||||
if (!surf)
|
||||
return false;
|
||||
|
||||
// SDL_Surface* converted = SDL_ConvertSurface(surf, SDL_PIXELFORMAT_RGBA32);
|
||||
// SDL_DestroySurface(surf);
|
||||
// surf = converted;
|
||||
|
||||
int gw = surf->w;
|
||||
int gh = surf->h;
|
||||
|
||||
// 4. Get current atlas
|
||||
int minx, maxx, miny, maxy, advance;
|
||||
TTF_GetGlyphMetrics(font, codepoint, &minx, &maxx, &miny, &maxy, &advance);
|
||||
|
||||
GlyphInfo glyph;
|
||||
glyph.advance = advance;
|
||||
glyph.codepoint = codepoint;
|
||||
|
||||
SDL_Texture* atlas = m_atlases[m_currentAtlasCount - 1];
|
||||
|
||||
// SDL_Log("atlas format = %s", SDL_GetPixelFormatName(atlas->format));
|
||||
// SDL_Log("surf format = %s", SDL_GetPixelFormatName(surf->format));
|
||||
|
||||
// 5. Shelf packing: move to next row if needed
|
||||
if (m_penX + gw > int(AtlasTextureDimension))
|
||||
{
|
||||
m_penX = 0;
|
||||
|
|
@ -83,13 +106,12 @@ namespace ogfx
|
|||
m_rowHeight = 0;
|
||||
}
|
||||
|
||||
// 6. If still doesn't fit → create new atlas
|
||||
if (m_penY + gh > int(AtlasTextureDimension))
|
||||
{
|
||||
SDL_DestroySurface(surf);
|
||||
|
||||
if (!create_new_atlas())
|
||||
return false; // no more atlases available
|
||||
return false;
|
||||
|
||||
atlas = m_atlases[m_currentAtlasCount - 1];
|
||||
m_penX = 0;
|
||||
|
|
@ -97,74 +119,28 @@ namespace ogfx
|
|||
m_rowHeight = 0;
|
||||
}
|
||||
|
||||
uint8_t* pixels = (uint8_t*)surf->pixels;
|
||||
int pitch = surf->pitch;
|
||||
|
||||
// for (int y = 0; y < surf->h; y++)
|
||||
// {
|
||||
// uint32_t* row = (uint32_t*)(pixels + y * pitch);
|
||||
|
||||
// for (int x = 0; x < surf->w; x++)
|
||||
// {
|
||||
// uint32_t px = row[x];
|
||||
|
||||
// uint8_t a = (px >> 24) & 0xFF; // ABGR → A is highest byte
|
||||
// uint8_t r = (px >> 16) & 0xFF;
|
||||
// uint8_t g = (px >> 8) & 0xFF;
|
||||
// uint8_t b = (px) & 0xFF;
|
||||
|
||||
// std::cout << (int)r << "," << (int)g << "," << (int)b << "," << (int)a << " ";
|
||||
|
||||
// row[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 7. Upload glyph bitmap into atlas
|
||||
SDL_Rect dstRect { m_penX, m_penY, gw, gh };
|
||||
|
||||
SDL_LockSurface(surf);
|
||||
SDL_UpdateTexture(atlas, &dstRect, surf->pixels, surf->pitch);
|
||||
SDL_UnlockSurface(surf);
|
||||
SDL_DestroySurface(surf);
|
||||
|
||||
// void* lockedPixels = nullptr;
|
||||
// int lockedPitch = 0;
|
||||
// if (SDL_LockTexture(atlas, &dstRect, &lockedPixels, &lockedPitch))
|
||||
// {
|
||||
// SDL_LockSurface(surf);
|
||||
// uint8_t* src = (uint8_t*)surf->pixels;
|
||||
// uint8_t* dst = (uint8_t*)lockedPixels;
|
||||
// for (int y = 0; y < gh; y++)
|
||||
// {
|
||||
// memcpy(dst, src, gw * 4); // 4 bytes per pixel (ARGB8888)
|
||||
// src += surf->pitch;
|
||||
// dst += lockedPitch;
|
||||
// }
|
||||
// SDL_UnlockSurface(surf);
|
||||
// SDL_UnlockTexture(atlas);
|
||||
// }
|
||||
|
||||
// // SDL_UpdateTexture(atlas, &dstRect, surf->pixels, surf->pitch);
|
||||
// SDL_DestroySurface(surf);
|
||||
|
||||
// 8. Compute UVs
|
||||
float u0 = float(m_penX) / float(AtlasTextureDimension);
|
||||
float v0 = float(m_penY) / float(AtlasTextureDimension);
|
||||
float u1 = float(m_penX + gw) / float(AtlasTextureDimension);
|
||||
float v1 = float(m_penY + gh) / float(AtlasTextureDimension);
|
||||
|
||||
GlyphUV uv;
|
||||
uv.atlas = atlas;
|
||||
uv.uvs[0] = { u0, v0 };
|
||||
uv.uvs[1] = { u1, v0 };
|
||||
uv.uvs[2] = { u1, v1 };
|
||||
uv.uvs[3] = { u0, v1 };
|
||||
uv.size = { static_cast<float>(gw), static_cast<float>(gh) };
|
||||
glyph.atlas = atlas;
|
||||
glyph.uvs[0] = { u0, v0 };
|
||||
glyph.uvs[1] = { u1, v0 };
|
||||
glyph.uvs[2] = { u1, v1 };
|
||||
glyph.uvs[3] = { u0, v1 };
|
||||
glyph.size = { static_cast<float>(gw), static_cast<float>(gh) };
|
||||
|
||||
// 9. Store in hashmap
|
||||
m_uvs[key] = uv;
|
||||
m_uvs[key] = glyph;
|
||||
*outGlyph = &(m_uvs[key]);
|
||||
|
||||
// 10. Advance shelf packing cursor
|
||||
m_penX += gw;
|
||||
m_rowHeight = std::max(m_rowHeight, gh);
|
||||
return true;
|
||||
|
|
@ -172,7 +148,6 @@ namespace ogfx
|
|||
|
||||
bool FontGlyphAtlas::create_new_atlas(void)
|
||||
{
|
||||
// 1. Check if we can create another atlas
|
||||
if (m_currentAtlasCount >= int(MaxAtlasCount))
|
||||
return false;
|
||||
|
||||
|
|
@ -183,18 +158,15 @@ namespace ogfx
|
|||
if (!sdlRenderer)
|
||||
return false;
|
||||
|
||||
// 2. Create the texture
|
||||
SDL_Texture* tex = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, AtlasTextureDimension, AtlasTextureDimension);
|
||||
|
||||
SDL_Texture* tex = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, AtlasTextureDimension, AtlasTextureDimension);
|
||||
if (!tex)
|
||||
return false;
|
||||
|
||||
// 3. Set blend mode (important for alpha glyphs)
|
||||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_LINEAR);
|
||||
|
||||
// 4. Clear the texture to transparent
|
||||
{
|
||||
|
||||
{ // Clear the texture to transparent
|
||||
void* pixels = nullptr;
|
||||
int pitch = 0;
|
||||
if (SDL_LockTexture(tex, nullptr, &pixels, &pitch) == 0)
|
||||
|
|
@ -204,52 +176,13 @@ namespace ogfx
|
|||
}
|
||||
}
|
||||
|
||||
// 5. Store the atlas
|
||||
m_atlases[m_currentAtlasCount] = tex;
|
||||
m_currentAtlasCount++;
|
||||
|
||||
// 6. Reset packing cursor for this new atlas
|
||||
m_penX = 0;
|
||||
m_penY = 0;
|
||||
m_rowHeight = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FontGlyphAtlas::save_atlas_to_png(SDL_Renderer* renderer, SDL_Texture* atlas, const char* filename)
|
||||
{
|
||||
// 1. Get texture dimensions and format
|
||||
float w, h;
|
||||
SDL_GetTextureSize(atlas, &w, &h);
|
||||
int iw = (int)w, ih = (int)h;
|
||||
|
||||
// 2. Create a target surface
|
||||
SDL_Surface* surf = SDL_CreateSurface(iw, ih, SDL_PIXELFORMAT_ARGB8888);
|
||||
if (!surf) return;
|
||||
|
||||
// 3. Read pixels back from the texture
|
||||
SDL_Rect rect { 0, 0, iw, ih };
|
||||
|
||||
// For STREAMING textures, lock/read directly:
|
||||
void* pixels = nullptr;
|
||||
int pitch = 0;
|
||||
if (SDL_LockTexture(atlas, nullptr, &pixels, &pitch))
|
||||
{
|
||||
uint8_t* src = (uint8_t*)pixels;
|
||||
uint8_t* dst = (uint8_t*)surf->pixels;
|
||||
for (int y = 0; y < ih; y++)
|
||||
{
|
||||
memcpy(dst, src, iw * 4);
|
||||
src += pitch;
|
||||
dst += surf->pitch;
|
||||
}
|
||||
SDL_UnlockTexture(atlas);
|
||||
}
|
||||
|
||||
// 4. Save
|
||||
IMG_SavePNG(surf, filename); // needs SDL3_image
|
||||
// or: SDL_SaveBMP(surf, "atlas_debug.bmp");
|
||||
|
||||
SDL_DestroySurface(surf);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@ namespace ogfx
|
|||
class BasicRenderer2D;
|
||||
class FontGlyphAtlas
|
||||
{
|
||||
public: struct GlyphUV
|
||||
public: struct GlyphInfo
|
||||
{
|
||||
ostd::Vec2 uvs[4];
|
||||
SDL_Texture* atlas { nullptr };
|
||||
ostd::Vec2 size;
|
||||
uint32_t codepoint { 0 };
|
||||
int32_t advance { 0 };
|
||||
};
|
||||
struct GlyphKey
|
||||
{
|
||||
|
|
@ -62,18 +64,18 @@ namespace ogfx
|
|||
inline FontGlyphAtlas(void) { }
|
||||
inline FontGlyphAtlas(BasicRenderer2D& renderer) { init(renderer); }
|
||||
FontGlyphAtlas init(BasicRenderer2D& renderer);
|
||||
const std::vector<const GlyphInfo*> processString(const ostd::String& str, TTF_Font* font, uint32_t fontSize);
|
||||
|
||||
public:
|
||||
bool rasterize_glyph(const ostd::String& glyphStr, TTF_Font* font, uint32_t fontSize);
|
||||
private:
|
||||
bool rasterize_glyph(const ostd::String& glyphStr, TTF_Font* font, uint32_t fontSize, const GlyphInfo** outGlyph);
|
||||
bool create_new_atlas(void);
|
||||
void save_atlas_to_png(SDL_Renderer* renderer, SDL_Texture* atlas, const char* filename);
|
||||
|
||||
public:
|
||||
inline static constexpr uint32_t AtlasTextureDimension { 8192 };
|
||||
inline static constexpr uint32_t MaxAtlasCount { 16 };
|
||||
|
||||
public:
|
||||
std::unordered_map<GlyphKey, GlyphUV, GlyphKeyHasher> m_uvs;
|
||||
std::unordered_map<GlyphKey, GlyphInfo, GlyphKeyHasher> m_uvs;
|
||||
SDL_Texture* m_atlases[FontGlyphAtlas::MaxAtlasCount];
|
||||
int32_t m_currentAtlasCount { 0 };
|
||||
BasicRenderer2D* m_renderer { nullptr };
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
/*
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
|
||||
This file is part of OmniaFramework.
|
||||
This file is part of OmniaFramework.
|
||||
|
||||
OmniaFramework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OmniaFramework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OmniaFramework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
OmniaFramework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gui/Events.hpp"
|
||||
|
|
@ -25,42 +25,39 @@
|
|||
|
||||
ostd::ConsoleOutputHandler out;
|
||||
|
||||
void drawTexturedQuad(SDL_Renderer* renderer,
|
||||
SDL_Texture* tex,
|
||||
const ostd::Rectangle& rect,
|
||||
const ostd::Vec2 uvs[4])
|
||||
void drawTexturedQuad(SDL_Renderer* renderer, SDL_Texture* tex, const ostd::Rectangle& rect, const ostd::Vec2 uvs[4])
|
||||
{
|
||||
SDL_Vertex verts[4];
|
||||
SDL_Vertex verts[4];
|
||||
|
||||
// Expand rectangle into quad corners
|
||||
const float x = rect.x;
|
||||
const float y = rect.y;
|
||||
const float w = rect.w;
|
||||
const float h = rect.h;
|
||||
// Expand rectangle into quad corners
|
||||
const float x = rect.x;
|
||||
const float y = rect.y;
|
||||
const float w = rect.w;
|
||||
const float h = rect.h;
|
||||
|
||||
const ostd::Vec2 quad[4] = {
|
||||
{ x, y },
|
||||
{ x + w, y },
|
||||
{ x + w, y + h },
|
||||
{ x, y + h }
|
||||
};
|
||||
const ostd::Vec2 quad[4] = {
|
||||
{ x, y },
|
||||
{ x + w, y },
|
||||
{ x + w, y + h },
|
||||
{ x, y + h }
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
verts[i].position.x = quad[i].x;
|
||||
verts[i].position.y = quad[i].y;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
verts[i].position.x = quad[i].x;
|
||||
verts[i].position.y = quad[i].y;
|
||||
|
||||
verts[i].tex_coord.x = uvs[i].x;
|
||||
verts[i].tex_coord.y = uvs[i].y;
|
||||
verts[i].tex_coord.x = uvs[i].x;
|
||||
verts[i].tex_coord.y = uvs[i].y;
|
||||
|
||||
auto crim = ostd::Colors::Crimson.getNormalizedColor();
|
||||
verts[i].color = SDL_FColor{crim.r, crim.g, crim.b, crim.a};
|
||||
}
|
||||
auto crim = ostd::Colors::Crimson.getNormalizedColor();
|
||||
verts[i].color = SDL_FColor{crim.r, crim.g, crim.b, crim.a};
|
||||
}
|
||||
|
||||
// Two triangles: (0,1,2) and (2,3,0)
|
||||
const int indices[6] = { 0, 1, 2, 2, 3, 0 };
|
||||
// Two triangles: (0,1,2) and (2,3,0)
|
||||
const int indices[6] = { 0, 1, 2, 2, 3, 0 };
|
||||
|
||||
SDL_RenderGeometry(renderer, tex, verts, 4, indices, 6);
|
||||
SDL_RenderGeometry(renderer, tex, verts, 4, indices, 6);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -105,14 +102,14 @@ class Window : public ogfx::gui::Window
|
|||
m_label1.setMouseScrolledCallback([&](const ogfx::gui::Event& event) -> void {
|
||||
std::cout << "SCROLL!\n";
|
||||
});
|
||||
// addWidget(m_label1);
|
||||
addWidget(m_label1);
|
||||
m_panel2.addChild(m_panel1);
|
||||
// addWidget(m_panel2);
|
||||
addWidget(m_panel2);
|
||||
|
||||
|
||||
m_check1.setPosition(30, 30);
|
||||
m_check1.setText("Check this out!");
|
||||
// addWidget(m_check1);
|
||||
addWidget(m_check1);
|
||||
|
||||
m_label2.setPosition(0, 0);
|
||||
m_label2.setText("Ciccia Bella!");
|
||||
|
|
@ -156,63 +153,7 @@ class Window : public ogfx::gui::Window
|
|||
m_panel1.addChild(m_label3);
|
||||
|
||||
setTheme(m_theme);
|
||||
|
||||
m_gfx.setFontSize(fs);
|
||||
m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar('H'), m_gfx.getSDLFont(), fs);
|
||||
m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar('e'), m_gfx.getSDLFont(), fs);
|
||||
m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar('l'), m_gfx.getSDLFont(), fs);
|
||||
m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar('o'), m_gfx.getSDLFont(), fs);
|
||||
|
||||
// int32_t count = 0;
|
||||
// for (char c = 'A'; c <= 'Z'; c++)
|
||||
// {
|
||||
// for (int32_t i = 0; i < 200; i++)
|
||||
// {
|
||||
// count++;
|
||||
// uint32_t _fs = ostd::Random::getui32(8, 200);
|
||||
// m_gfx.setFontSize(_fs);
|
||||
// m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar(c), m_gfx.getSDLFont(), _fs);
|
||||
// }
|
||||
// }
|
||||
// for (char c = '0'; c <= '9'; c++)
|
||||
// {
|
||||
// for (int32_t i = 0; i < 200; i++)
|
||||
// {
|
||||
// count++;
|
||||
// uint32_t _fs = ostd::Random::getui32(8, 200);
|
||||
// m_gfx.setFontSize(_fs);
|
||||
// m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar(c), m_gfx.getSDLFont(), _fs);
|
||||
// }
|
||||
// }
|
||||
// for (char c = 'a'; c <= 'z'; c++)
|
||||
// {
|
||||
// count++;
|
||||
// for (int32_t i = 0; i < 200; i++)
|
||||
// {
|
||||
// uint32_t _fs = ostd::Random::getui32(8, 200);
|
||||
// m_gfx.setFontSize(_fs);
|
||||
// m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar(c), m_gfx.getSDLFont(), _fs);
|
||||
// }
|
||||
// }
|
||||
// for (char c = '0'; c <= '9'; c++)
|
||||
// {
|
||||
// for (int32_t i = 0; i < 200; i++)
|
||||
// {
|
||||
// count++;
|
||||
// uint32_t _fs = ostd::Random::getui32(8, 200);
|
||||
// m_gfx.setFontSize(_fs);
|
||||
// m_gfx.getFontGlyphAtlas().rasterize_glyph(ostd::String("").addChar(c), m_gfx.getSDLFont(), _fs);
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (int32_t i = 0; i < m_gfx.getFontGlyphAtlas().m_currentAtlasCount; i++)
|
||||
// {
|
||||
// ostd::String file("./atlas");
|
||||
// file.add(i).add(".png");
|
||||
// m_gfx.getFontGlyphAtlas().save_atlas_to_png(m_gfx.getSDLRenderer(), m_gfx.getFontGlyphAtlas().m_atlases[i], file);
|
||||
// }
|
||||
// std::cout << "Atlas cound: " << (int)count << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
inline void onSignal(ostd::Signal& signal) override
|
||||
{
|
||||
|
|
@ -226,39 +167,6 @@ class Window : public ogfx::gui::Window
|
|||
|
||||
void onRedraw(ogfx::BasicRenderer2D& gfx) override
|
||||
{
|
||||
// auto l_rndPoint = [&](void) -> ostd::FPoint {
|
||||
// using rnd = ostd::Random;
|
||||
// return rnd::getVec2({ 0, (float)getWindowWidth() / 2 }, { 0, (float)getWindowHeight() / 2 });
|
||||
// };
|
||||
// for (int32_t i = 0; i < 1000; i++)
|
||||
// gfx.drawLine({ l_rndPoint(), l_rndPoint() }, ostd::Colors::Crimson, 10);
|
||||
// gfx.drawLine({ { 10, 10 }, { 200, 100 } }, ostd::Colors::Crimson, 3);
|
||||
// gfx.drawRect({ 50, 50, 200, 120 }, ostd::Colors::Aquamarine, 1);
|
||||
|
||||
// std::cout << (int)(gfx.getDrawCallCount() + 1) << "\n";
|
||||
|
||||
gfx.endFrame();
|
||||
|
||||
auto l_renderGlyph = [&](char c, float x, float y, float scale = 1) -> ostd::Vec2 {
|
||||
auto& tex = m_gfx.getFontGlyphAtlas().m_atlases[0];
|
||||
auto glyph = m_gfx.getFontGlyphAtlas().m_uvs[ { static_cast<uint32_t>(c), (uint64_t)gfx.getSDLFont(), fs }];
|
||||
drawTexturedQuad(getSDLRenderer(), tex, { x, y, glyph.size.x * scale, glyph.size.y * scale }, glyph.uvs);
|
||||
return glyph.size;
|
||||
};
|
||||
auto l_renderString = [&](const ostd::String& str, const ostd::Vec2& pos, float scale = 1.0f) -> void {
|
||||
float x = pos.x;
|
||||
float y = pos.y;
|
||||
for (auto& c : str)
|
||||
{
|
||||
auto size = l_renderGlyph(c, x, y, scale);
|
||||
x += (size.x * scale);
|
||||
}
|
||||
};
|
||||
|
||||
l_renderString("Hello", { 10, 140 });
|
||||
|
||||
gfx.renderText("Hello", 10, 100, ostd::Colors::Crimson, fs);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -270,7 +178,6 @@ class Window : public ogfx::gui::Window
|
|||
ogfx::gui::widgets::CheckBox m_check1 { *this };
|
||||
ostd::Stylesheet m_theme;
|
||||
ostd::Vec2 pos { 0, 0 };
|
||||
uint32_t fs = 30;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
|
|
|||
Loading…
Reference in a new issue