This commit is contained in:
Vicente Ferrari Smith 2026-02-01 15:48:33 +01:00
parent f93505cd26
commit e2bee553b0
5 changed files with 93 additions and 56 deletions

View File

@ -8,7 +8,7 @@ include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
raylib raylib
GIT_REPOSITORY https://github.com/raysan5/raylib.git GIT_REPOSITORY https://github.com/raysan5/raylib.git
GIT_TAG c1ab645ca298a2801097931d1079b10ff7eb9df8 GIT_TAG 242dfee5ef022cbd5ba3e7dcdbed4b51d83ebf7e
) )
FetchContent_MakeAvailable(raylib) FetchContent_MakeAvailable(raylib)
@ -79,6 +79,15 @@ if(NOT TARGET kb)
target_include_directories(kb INTERFACE "${kb_SOURCE_DIR}") target_include_directories(kb INTERFACE "${kb_SOURCE_DIR}")
endif() endif()
FetchContent_Declare(
enet
GIT_REPOSITORY https://github.com/lsalzman/enet.git
GIT_TAG master
)
FetchContent_MakeAvailable(enet)
target_include_directories(enet INTERFACE "${enet_SOURCE_DIR}/include")
add_executable(game src/main.cpp add_executable(game src/main.cpp
src/font.cpp src/font.cpp
src/misc.cpp src/misc.cpp
@ -86,13 +95,31 @@ add_executable(game src/main.cpp
src/entity.cpp src/entity.cpp
src/entity.h src/entity.h
src/font.h) src/font.h)
target_link_libraries(game PRIVATE raylib freetype harfbuzz stb Tracy::TracyClient kb)
target_link_libraries(game PRIVATE raylib freetype harfbuzz stb Tracy::TracyClient kb enet)
target_compile_definitions(game PUBLIC TRACY_ENABLE) target_compile_definitions(game PUBLIC TRACY_ENABLE)
file(GLOB_RECURSE ASSET_FILES "assets/*")
set(ASSET_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/assets")
set(ALL_COPIED_ASSETS "")
# 2. Create a specific copy command for every file
foreach(ASSET_PATH ${ASSET_FILES})
# Get the relative path so we can recreate the folder structure
file(RELATIVE_PATH REL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/assets" ${ASSET_PATH})
set(DEST_PATH "${ASSET_OUTPUT_DIR}/${REL_PATH}")
add_custom_command( add_custom_command(
TARGET game POST_BUILD OUTPUT ${DEST_PATH}
COMMAND ${CMAKE_COMMAND} -E copy_directory COMMAND ${CMAKE_COMMAND} -E copy ${ASSET_PATH} ${DEST_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/assets DEPENDS ${ASSET_PATH}
${CMAKE_CURRENT_BINARY_DIR}/assets COMMENT "Syncing ${REL_PATH}"
COMMENT "Copying assets to build directory"
) )
list(APPEND ALL_COPIED_ASSETS ${DEST_PATH})
endforeach()
# 3. Create a "dummy" target that the game depends on
add_custom_target(copy_assets_target DEPENDS ${ALL_COPIED_ASSETS})
add_dependencies(game copy_assets_target)

View File

@ -68,6 +68,6 @@ void main() {
// float x = fract(fragTexCoord.s); // float x = fract(fragTexCoord.s);
// float final = smoothstep(divider - 0.1, divider + 0.1, x); // float final = smoothstep(divider - 0.1, divider + 0.1, x);
finalColor = vec4(1, 1, 1, float_to_srgb(texelColor0.r)); //xelColor0; finalColor = vec4(1, 1, 1, texelColor0.r); //xelColor0;
// finalColor = vec4(1, 1, 0.0, 1.0); // finalColor = vec4(1, 1, 0.0, 1.0);
} }

View File

@ -3,26 +3,27 @@
// //
#include "font.h" #include "font.h"
#include <print> #include <print>
#include <fstream> #include <fstream>
#include <rlgl.h> #include <rlgl.h>
#include <stdexcept> #include <stdexcept>
#include <stb_rect_pack.h> #include <stb_rect_pack.h>
#include <tracy/Tracy.hpp> #include <tracy/Tracy.hpp>
#include <raymath.h>
#include "raymath.h"
#include "tracy/TracyC.h"
FT_Library ft_lib; FT_Library ft_lib;
Shader shader; Shader shader;
extern Vector2 DPI;
const int32_t ATLAS_SIZE = 4096; const int32_t ATLAS_SIZE = 4096;
MyFont::MyFont(const std::string& filename, int size) { MyFont::MyFont(const std::string& filename, int size) {
// Load file data // Load file data
std::ifstream file(filename, std::ios::binary | std::ios::ate); std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (!file.is_open()) throw std::runtime_error("Failed to open font file"); if (!file.is_open()) std::println("Couldn't open the file! {}", filename);
std::streamsize file_size = file.tellg(); std::streamsize file_size = file.tellg();
std::vector<uint8_t> file_data(file_size); std::vector<uint8_t> file_data(file_size);
@ -36,8 +37,9 @@ MyFont::MyFont(const std::string& filename, int size) {
throw std::runtime_error("Failed to create FreeType face"); throw std::runtime_error("Failed to create FreeType face");
} }
Vector2 dpi = GetWindowScaleDPI(); std::println("DPI: {}, {}", DPI.x, DPI.y);
FT_Set_Char_Size(face, 0, size * 64, 0, (FT_UInt)(96 * dpi.y));
FT_Set_Char_Size(face, 0, size * 64, 0, 96.0 * DPI.y);
FT_Select_Charmap(face, FT_ENCODING_UNICODE); FT_Select_Charmap(face, FT_ENCODING_UNICODE);
std::vector<stbrp_rect> rects; std::vector<stbrp_rect> rects;
@ -77,12 +79,12 @@ MyFont::MyFont(const std::string& filename, int size) {
g.index = rect.id; g.index = rect.id;
g.width = bmp.width; g.width = bmp.width;
g.height = bmp.rows; g.height = bmp.rows;
g.dpi_width = (float)g.width / dpi.x; g.dpi_width = g.width * DPI.x;
g.dpi_height = (float)g.height / dpi.y; g.dpi_height = (g.height) * DPI.y;
g.bearing_x = face->glyph->bitmap_left; g.bearing_x = face->glyph->bitmap_left;
g.bearing_y = face->glyph->bitmap_top; g.bearing_y = face->glyph->bitmap_top;
g.dpi_bearing_x = (float)g.bearing_x / dpi.x; g.dpi_bearing_x = g.bearing_x * DPI.x;
g.dpi_bearing_y = (float)g.bearing_y / dpi.y; g.dpi_bearing_y = g.bearing_y * DPI.y;
g.descent = g.height - g.bearing_y; g.descent = g.height - g.bearing_y;
g.ascent = g.height - g.descent; g.ascent = g.height - g.descent;
g.dpi_descent = g.dpi_height - g.dpi_bearing_y; g.dpi_descent = g.dpi_height - g.dpi_bearing_y;
@ -154,9 +156,9 @@ void MyFont::render_text(const std::string_view text, const Vector2 pos, const C
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
const float font_ascent = face->size->metrics.ascender >> 6; const float font_ascent = face->size->metrics.ascender >> 6;
const float dpi_font_ascent = font_ascent / GetWindowScaleDPI().y; const float dpi_font_ascent = font_ascent * DPI.y;
render_pos.y += dpi_font_ascent; render_pos.y += font_ascent;
kbts_shape_context *Context = kbts_CreateShapeContext(nullptr, nullptr); kbts_shape_context *Context = kbts_CreateShapeContext(nullptr, nullptr);
const kbts_font *kb_font = kbts_ShapePushFont(Context, &kbts); const kbts_font *kb_font = kbts_ShapePushFont(Context, &kbts);
@ -165,12 +167,9 @@ void MyFont::render_text(const std::string_view text, const Vector2 pos, const C
return; return;
} }
{
ZoneScopedN("font")
kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, KBTS_LANGUAGE_DONT_KNOW); kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, KBTS_LANGUAGE_DONT_KNOW);
kbts_ShapeUtf8(Context, text.data(), text.size(), KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX); kbts_ShapeUtf8(Context, text.data(), text.size(), KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX);
kbts_ShapeEnd(Context); kbts_ShapeEnd(Context);
}
float cursor_x = 0; float cursor_x = 0;
float cursor_y = 0; float cursor_y = 0;
@ -180,9 +179,9 @@ void MyFont::render_text(const std::string_view text, const Vector2 pos, const C
ZoneScopedN("shape run") ZoneScopedN("shape run")
if ((Run.Flags & KBTS_BREAK_FLAG_LINE_HARD) != 0) { if ((Run.Flags & KBTS_BREAK_FLAG_LINE_HARD) != 0) {
const float font_linegap = face->size->metrics.height >> 6; const float font_linegap = face->size->metrics.height >> 6;
const float dpi_font_linegap = font_linegap / GetWindowScaleDPI().y; const float dpi_font_linegap = font_linegap * DPI.y;
cursor_y += dpi_font_linegap; cursor_y += font_linegap;
cursor_x = 0; cursor_x = 0;
} }
@ -197,26 +196,26 @@ void MyFont::render_text(const std::string_view text, const Vector2 pos, const C
const float advance_x = FT_MulFix(RunGlyph->AdvanceX, face->size->metrics.x_scale) >> 6; const float advance_x = FT_MulFix(RunGlyph->AdvanceX, face->size->metrics.x_scale) >> 6;
const float advance_y = FT_MulFix(RunGlyph->AdvanceY, face->size->metrics.y_scale) >> 6; const float advance_y = FT_MulFix(RunGlyph->AdvanceY, face->size->metrics.y_scale) >> 6;
const float dpi_advance_x = advance_x / GetWindowScaleDPI().x; const float dpi_advance_x = advance_x * DPI.x;
const float dpi_advance_y = advance_y / GetWindowScaleDPI().y; const float dpi_advance_y = advance_y * DPI.y;
const float offset_x = FT_MulFix(RunGlyph->OffsetX, face->size->metrics.x_scale) >> 6; const float offset_x = FT_MulFix(RunGlyph->OffsetX, face->size->metrics.x_scale) >> 6;
const float offset_y = FT_MulFix(RunGlyph->OffsetY, face->size->metrics.y_scale) >> 6; const float offset_y = FT_MulFix(RunGlyph->OffsetY, face->size->metrics.y_scale) >> 6;
const float dpi_offset_x = offset_x / GetWindowScaleDPI().x; const float dpi_offset_x = offset_x * DPI.x;
const float dpi_offset_y = offset_y / GetWindowScaleDPI().y; const float dpi_offset_y = offset_y * DPI.y;
if (auto it = glyphs.find(RunGlyph->Id); it != glyphs.end()) { if (auto it = glyphs.find(RunGlyph->Id); it != glyphs.end()) {
auto &glyph = it->second; auto &glyph = it->second;
const Vector2 v0 = Vector2Add(render_pos, { .x = cursor_x + glyph.dpi_bearing_x + dpi_offset_x, const Vector2 v0 = Vector2Add(render_pos, { .x = cursor_x + glyph.bearing_x + offset_x,
.y = cursor_y - glyph.dpi_bearing_y - dpi_offset_y }); .y = cursor_y - glyph.bearing_y - offset_y });
const Vector2 v1 = Vector2Add(v0, Vector2{ .x = glyph.dpi_width, .y = glyph.dpi_height }); const Vector2 v1 = Vector2Add(v0, Vector2{ .x = (float) glyph.width, .y = (float) glyph.height });
const Vector4 p0 = { .x = v0.x, .y = v0.y, .z = 0.0, .w = 1.0 }; const Vector4 p0 = { .x = v0.x, .y = v0.y, .z = 0.0, .w = 1.0 };
const Vector4 p1 = { .x = v1.x, .y = v1.y, .z = 0.0, .w = 1.0 }; const Vector4 p1 = { .x = v1.x, .y = v1.y, .z = 0.0, .w = 1.0 };
cursor_x += dpi_advance_x; cursor_x += advance_x;
cursor_y += dpi_advance_y; cursor_y += advance_y;
const Vector2 st0 = glyph.st0; const Vector2 st0 = glyph.st0;
const Vector2 st1 = glyph.st1; const Vector2 st1 = glyph.st1;
@ -284,7 +283,7 @@ MyFont::size_ret MyFont::size_row(std::string_view str, int32_t n, float max_wid
if (auto it = glyphs.find(RunGlyph->Id); it != glyphs.end()) { if (auto it = glyphs.find(RunGlyph->Id); it != glyphs.end()) {
const float advance_x = FT_MulFix(RunGlyph->AdvanceX, face->size->metrics.x_scale) >> 6; const float advance_x = FT_MulFix(RunGlyph->AdvanceX, face->size->metrics.x_scale) >> 6;
const float dpi_advance_x = advance_x / GetWindowScaleDPI().x; const float dpi_advance_x = advance_x * DPI.x;
size.y = std::max(size.y, it->second.dpi_height); size.y = std::max(size.y, it->second.dpi_height);
size.x += dpi_advance_x; size.x += dpi_advance_x;

View File

@ -34,9 +34,9 @@ struct Glyph {
struct MyFont { struct MyFont {
FT_Face face; FT_Face face;
std::unordered_map<uint32_t, Glyph> glyphs; std::unordered_map<uint32_t, Glyph> glyphs;
Texture2D texture; Texture2D texture{};
std::vector<uint8_t> kb_file_data; std::vector<uint8_t> kb_file_data;
kbts_font kbts; kbts_font kbts{};
MyFont(const std::string& filename, int size); MyFont(const std::string& filename, int size);
void deinit(); void deinit();

View File

@ -1,13 +1,14 @@
#include <print>
#include <raylib.h>
#include <freetype/freetype.h>
#include <hb.h>
#include "font.h" #include "font.h"
#include "misc.h" #include "misc.h"
#include <stb_rect_pack.h> #include <print>
#include <external/fix_win32_compatibility.h>
#include <freetype/freetype.h>
#include <hb.h>
#include <enet/enet.h>
#include <raylib.h>
#define KB_TEXT_SHAPE_IMPLEMENTATION #define KB_TEXT_SHAPE_IMPLEMENTATION
#include <kb_text_shape.h> #include <kb_text_shape.h>
#include <tracy/Tracy.hpp> #include <tracy/Tracy.hpp>
@ -19,6 +20,11 @@ float accumulator = 0;
float k = 1; float k = 1;
int32_t frame = 0; int32_t frame = 0;
Vector2 DPI = {};
constexpr int32_t screenwidth = 1280;
constexpr int32_t screenheight = 720;
int main() { int main() {
ZoneScoped ZoneScoped
@ -28,20 +34,24 @@ int main() {
} }
const int32_t screenwidth = 1280; if (enet_initialize() != 0) {
const int32_t screenheight = 720; fprintf (stderr, "An error occurred while initializing ENet.\n");
return EXIT_FAILURE;
}
SetConfigFlags(FLAG_WINDOW_HIGHDPI);
InitWindow(screenwidth, screenheight, "raylib"); InitWindow(screenwidth, screenheight, "raylib");
DPI = GetWindowScaleDPI();
MyFont vollkorn("assets/fonts/Vollkorn/static/Vollkorn-Regular.ttf", 42); MyFont vollkorn("assets/fonts/Vollkorn/static/Vollkorn-Regular.ttf", 68);
MyFont arabic("assets/fonts/Amiri/Amiri-Regular.ttf", 28); MyFont arabic("assets/fonts/Amiri/Amiri-Regular.ttf", 28);
shader = LoadShader(nullptr, "assets/text.frag"); shader = LoadShader(nullptr, "assets/text.frag");
float old_time = GetTime(); float old_time = GetTime();
while (!WindowShouldClose()) { while (!WindowShouldClose()) {
float new_time = GetTime(); float new_time = GetTime();
// const new_time : f32 = @floatCast(rl.getTime());
float frame_time = new_time - old_time; float frame_time = new_time - old_time;
old_time = new_time; old_time = new_time;
@ -64,16 +74,16 @@ int main() {
ClearBackground(SKYBLUE); ClearBackground(SKYBLUE);
//DrawText("Hello, Sailor!", 150, 150, 20, RAYWHITE); //DrawText("Hello, Sailor!", 150, 150, 20, RAYWHITE);
// vollkorn.render_text("The night is long and cold outside", {0 ,0}, WHITE); vollkorn.render_text("The night is long and cold outside", {0 ,0}, WHITE);
arabic.render_text("الليل طويل وبارد في الخارج", Vector2{ .x = 0, .y = 100}, WHITE); // arabic.render_text("الليل طويل وبارد في الخارج", Vector2{ .x = 0, .y = 100}, WHITE);
misc::drawFPS(0, 0, frame_time); misc::drawFPS(0, 0, frame_time);
EndDrawing(); EndDrawing();
{ {
ZoneScopedN("SwapScreenBuffer") ZoneScopedN("SwapScreenBufferZone")
SwapScreenBuffer(); SwapScreenBuffer();
} }
@ -86,6 +96,7 @@ int main() {
CloseWindow(); CloseWindow();
FT_Done_FreeType(ft_lib); FT_Done_FreeType(ft_lib);
enet_deinitialize();
return 0; return 0;
} }