Begin move to SDL

This commit is contained in:
Krzosa Karol
2024-07-26 11:33:12 +02:00
parent a74409c3ec
commit ee6df45e2d
8 changed files with 344 additions and 10 deletions

View File

@@ -27,12 +27,34 @@ struct Library {
Array<S8_String> objects; Array<S8_String> objects;
Array<S8_String> include_paths; Array<S8_String> include_paths;
Array<S8_String> defines; Array<S8_String> defines;
Array<S8_String> link;
}; };
Library PrepareSDL() { Library PrepareSDL() {
Library l = {};
l.include_paths.add("../src/external/SDL/include");
l.objects.add("../src/external/SDL/VisualC/static_x64/Release/SDL3.lib");
l.link.add("/SUBSYSTEM:WINDOWS");
l.link.add("opengl32.lib");
l.link.add("imm32.lib");
l.link.add("gdi32.lib");
l.link.add("winmm.lib");
l.link.add("shell32.lib");
l.link.add("user32.lib");
l.link.add("advapi32.lib");
l.link.add("Setupapi.lib");
l.link.add("ole32.lib");
l.link.add("oleaut32.lib");
l.link.add("Version.lib");
return l;
}
Library PrepareSDLDynamic() {
Library l = {}; Library l = {};
l.include_paths.add("../src/external/SDL/include"); l.include_paths.add("../src/external/SDL/include");
l.objects.add("../src/external/SDL/VisualC/x64/Release/SDL3.lib"); l.objects.add("../src/external/SDL/VisualC/x64/Release/SDL3.lib");
l.link.add("/SUBSYSTEM:WINDOWS");
OS_CopyFile("../src/external/SDL/VisualC/x64/Release/SDL3.dll", "./SDL3.dll", false);
return l; return l;
} }
@@ -77,7 +99,7 @@ Library PrepareLua() {
Library PrepareGlad() { Library PrepareGlad() {
Library l = {}; Library l = {};
l.sources.add("../src/external/glad/glad.c"); l.sources.add("../src/external/glad/glad.c");
l.include_paths.add("../src/external/glad"); l.include_paths.add("../src/external/glad/");
l.objects.add("glad.obj"); l.objects.add("glad.obj");
if (!OS_FileExists(l.objects[0])) { if (!OS_FileExists(l.objects[0])) {
Array<S8_String> cmd = {}; Array<S8_String> cmd = {};
@@ -101,6 +123,7 @@ int CompileTextEditor() {
cmd.add("cl.exe"); cmd.add("cl.exe");
cmd.add("-Fe:te.exe"); cmd.add("-Fe:te.exe");
cmd.add("-Fd:te.pdb"); cmd.add("-Fd:te.pdb");
cmd.add("-I ../src");
AddCommonFlags(&cmd); AddCommonFlags(&cmd);
For2(lib, libs) For(lib.defines) cmd.add(it); For2(lib, libs) For(lib.defines) cmd.add(it);
@@ -122,10 +145,44 @@ int CompileTextEditor() {
return result; return result;
} }
int CompileNewPlatform() {
int result = 0;
Array<Library> libs = {};
libs.add(PrepareGlad());
libs.add(PrepareLua());
libs.add(PrepareSDLDynamic());
Array<S8_String> cmd = {};
cmd.add("cl.exe");
cmd.add("-Fe:te.exe");
cmd.add("-Fd:te.pdb");
cmd.add("-I ../src");
AddCommonFlags(&cmd);
For2(lib, libs) For(lib.defines) cmd.add(it);
cmd.add("../src/new_platform/new_platform.cpp");
cmd.add("../src/basic/win32.cpp");
For2(lib, libs) For(lib.include_paths) cmd.add(Fmt("-I %.*s", S8_Expand(it)));
cmd.add("/link");
cmd.add("/incremental:no");
For2(lib, libs) For(lib.link) cmd.add(it);
For(libs) For2(o, it.objects) cmd.add(o);
OS_DeleteFile("te.pdb");
// For(cmd) IO_Printf("%.*s\n", S8_Expand(it));
result += Run(cmd);
return result;
}
int main() { int main() {
MA_InitScratch(); MA_InitScratch();
SRC_InitCache(Perm, "te.cache"); SRC_InitCache(Perm, "te.cache");
int result = CompileTextEditor(); // int result = CompileTextEditor();
int result = CompileNewPlatform();
if (result != 0) { if (result != 0) {
OS_DeleteFile("te.cache"); OS_DeleteFile("te.cache");

149
src/new_platform/font.cpp Normal file
View File

@@ -0,0 +1,149 @@
struct Glyph {
Vec2I size;
Vec2I offset;
int32_t xadvance;
int32_t left_side_bearing;
Rect2 atlas_bounding_box;
};
struct Font {
Array<Glyph> glyphs;
uint32_t first_char, last_char;
uint32_t texture_id;
int32_t size;
int32_t descent;
int32_t ascent;
int32_t line_gap;
Rect2 white_texture_bounding_box;
};
struct Atlas {
uint8_t *bitmap;
Vec2I size;
Vec2 inverse_size;
int xcursor;
int ycursor;
int32_t biggest_height;
Rect2 white_texture_bounding_box;
uint32_t texture_id;
};
Atlas CreateAtlas(Allocator allocator, Vec2I size) {
Atlas result = {};
result.size = size;
result.inverse_size.x = 1.f / (float)result.size.x;
result.inverse_size.y = 1.f / (float)result.size.y;
result.bitmap = AllocArray(allocator, uint8_t, size.x * size.y);
// Add a whitebox first for rectangle rendering
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
uint8_t *dst = result.bitmap + x + y * result.size.x;
*dst = 0xff;
}
}
result.white_texture_bounding_box = {2.f * result.inverse_size.x, 2.f / (float)result.size.y, 14.f * result.inverse_size.x, 14.f / (float)result.size.y};
result.xcursor += 16;
result.biggest_height += 16;
return result;
}
Rect2 PackBitmap(Atlas *atlas, uint8_t *bitmap, int width, int height) {
// Packing into a texture atlas
// @Inefficient The algorithm is a simplest thing I had in mind, first we advance
// through the atlas in X packing consecutive glyphs. After we get to the end of the row
// we advance to the next row by the Y size of the biggest packed glyph. If we get to the
// end of atlas and fail to pack everything the app panics.
int spacing = 4;
if (atlas->xcursor + width > atlas->size.x) {
if (atlas->ycursor + height < atlas->size.y) {
atlas->xcursor = 0;
atlas->ycursor += atlas->biggest_height + spacing;
} else {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Font loading error!", "Error while packing a font into atlas. Atlas size for this font scale is a bit too small", NULL);
}
}
uint8_t *src = bitmap;
for (int y = atlas->ycursor; y < atlas->ycursor + height; y += 1) {
for (int x = atlas->xcursor; x < atlas->xcursor + width; x += 1) {
uint8_t *dst = atlas->bitmap + x + y * atlas->size.x;
*dst = *src++;
}
}
Vec2 size = {(float)width * atlas->inverse_size.x, (float)height * atlas->inverse_size.y};
Vec2 pos = {(float)atlas->xcursor * atlas->inverse_size.x, (float)atlas->ycursor * atlas->inverse_size.y};
Rect2 result = {pos.x, pos.y, pos.x + size.x, pos.y + size.y};
atlas->xcursor += width + spacing;
if (height > atlas->biggest_height) {
atlas->biggest_height = height;
}
return result;
}
Font CreateFont(Atlas *atlas, int32_t size, String path) {
Scratch scratch;
Font result = {};
String file = ReadFile(scratch, path);
if (file.len == 0) {
return result;
}
stbtt_fontinfo stb_font;
int success = stbtt_InitFont(&stb_font, (const unsigned char *)file.data, 0);
if (!success) {
return result;
}
float scale = stbtt_ScaleForPixelHeight(&stb_font, (float)result.size);
float em_scale = stbtt_ScaleForMappingEmToPixels(&stb_font, (float)result.size);
int ascent, descent, line_gap;
stbtt_GetFontVMetrics(&stb_font, &ascent, &descent, &line_gap);
result.ascent = (int32_t)((float)ascent * scale);
result.descent = (int32_t)((float)descent * scale);
result.line_gap = (int32_t)((float)line_gap * scale);
result.size = size;
result.first_char = ' ';
result.last_char = '~';
result.white_texture_bounding_box = atlas->white_texture_bounding_box;
for (uint32_t ascii_symbol = result.first_char; ascii_symbol <= result.last_char; ascii_symbol++) {
int width, height, xoff, yoff;
uint8_t *bitmap = (uint8_t *)stbtt_GetCodepointBitmap(&stb_font, 0, scale, ascii_symbol, &width, &height, &xoff, &yoff);
defer { stbtt_FreeBitmap(bitmap, 0); };
int xadvance, left_side_bearing;
stbtt_GetCodepointHMetrics(&stb_font, ascii_symbol, &xadvance, &left_side_bearing);
Glyph glyph = {};
glyph.atlas_bounding_box = PackBitmap(atlas, bitmap, width, height);
glyph.size = {width, height};
glyph.offset = {xoff, yoff};
glyph.xadvance = (int32_t)((float)xadvance * scale);
glyph.left_side_bearing = (int32_t)((float)left_side_bearing * scale);
Add(&result.glyphs, glyph);
}
return result;
}
Glyph *GetGlyph(Font *font, uint32_t codepoint) {
bool is_in_range = codepoint >= font->first_char && codepoint <= font->last_char;
if (is_in_range) {
uint32_t index = codepoint - font->first_char;
return &font->glyphs[index];
} else {
uint32_t index = '?' - font->first_char;
return &font->glyphs[index];
}
}

View File

@@ -0,0 +1,129 @@
#define BASIC_IMPL
#include "basic/basic.h"
#include "basic/filesystem.h"
#include "SDL3/SDL.h"
#include "external/glad/glad.h"
#include "external/stb_truetype.h"
#include "external/stb_truetype.c"
#include "basic/math_int.cpp"
#include "basic/math.cpp"
#include "font.cpp"
bool AppIsRunning = true;
void ProcessSDLEvent(SDL_Event *event) {
switch (event->type) {
case SDL_EVENT_QUIT: AppIsRunning = false; return;
case SDL_EVENT_KEY_DOWN: {
SDL_KeyboardEvent &key = event->key;
bool shift = key.mod & SDL_KMOD_SHIFT;
bool ctrl = key.mod & SDL_KMOD_CTRL;
bool alt = key.mod & SDL_KMOD_ALT;
bool super = key.mod & SDL_KMOD_GUI;
if (key.key == SDLK_F5) {
AppIsRunning = false;
return;
}
} break;
case SDL_EVENT_KEY_UP: {
SDL_KeyboardEvent &key = event->key;
bool shift = key.mod & SDL_KMOD_SHIFT;
bool ctrl = key.mod & SDL_KMOD_CTRL;
bool alt = key.mod & SDL_KMOD_ALT;
bool super = key.mod & SDL_KMOD_GUI;
} break;
case SDL_EVENT_TEXT_INPUT: {
} break;
case SDL_EVENT_MOUSE_MOTION: {
} break;
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
} break;
case SDL_EVENT_MOUSE_BUTTON_UP: {
} break;
case SDL_EVENT_MOUSE_WHEEL: {
} break;
}
}
void GLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *user) {
printf("%s", message);
if (severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_MEDIUM) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "OpenGL error", message, NULL);
}
}
#if _WIN32
int WinMain(void *hInstance, void *hPrevInstance, const char *lpCmdLine, int nShowCmd)
#else
int main()
#endif
{
InitScratch();
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
return 1;
}
const char *glsl_version = "#version 130";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
SDL_Window *window = SDL_CreateWindow("Text editor", 640, 480, window_flags);
if (window == NULL) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window!", SDL_GetError(), NULL);
return 1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
SDL_ShowWindow(window);
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load opengl!", SDL_GetError(), NULL);
return 1;
}
glDebugMessageCallback(&GLDebugCallback, NULL);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
Arena Perm = {};
InitArena(&Perm);
Atlas atlas = CreateAtlas(Perm, {1024, 1024});
Font font = CreateFont(&atlas, 16, "c:\\Windows\\Fonts\\consola.ttf");
{
glCreateTextures(GL_TEXTURE_2D, 1, &atlas.texture_id);
glTextureParameteri(atlas.texture_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTextureParameteri(atlas.texture_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextureParameteri(atlas.texture_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(atlas.texture_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureStorage2D(atlas.texture_id, 1, GL_R8, (GLsizei)atlas.size.x, (GLsizei)atlas.size.y);
glTextureSubImage2D(atlas.texture_id, 0, 0, 0, (GLsizei)atlas.size.x, (GLsizei)atlas.size.y, GL_RED, GL_UNSIGNED_BYTE, atlas.bitmap);
}
font.texture_id = atlas.texture_id;
while (AppIsRunning) {
glClearColor(255, 255, 255, 255);
glClear(GL_COLOR_BUFFER_BIT);
SDL_Event event;
SDL_WaitEvent(&event);
ProcessSDLEvent(&event);
SDL_GL_SwapWindow(window);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

View File

@@ -1,12 +1,12 @@
#define BASIC_IMPL #define BASIC_IMPL
#include "../basic/basic.h" #include "basic/basic.h"
#include "../basic/filesystem.h" #include "basic/filesystem.h"
#include "../profiler/profiler.cpp" #include "basic/string16.cpp"
#include "basic/math_int.cpp"
#include "basic/math.cpp"
#include "profiler/profiler.cpp"
#include "new_basic.cpp" #include "new_basic.cpp"
#include "string16.cpp"
#include <math.h> #include <math.h>
#include "math_int.cpp"
#include "math.cpp"
#include "raylib.h" #include "raylib.h"
#include "colors.cpp" #include "colors.cpp"
#include "raylib_utils.cpp" #include "raylib_utils.cpp"

View File

@@ -95,8 +95,7 @@ Int FontSpacing;
Int FontLineSpacing; Int FontLineSpacing;
Int FontCharSpacing; Int FontCharSpacing;
Int FrameID; Int FrameID;
String WorkingDir; String WorkingDir;
String16 EvalString(Allocator allocator, String16 string16); String16 EvalString(Allocator allocator, String16 string16);