#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" #include "render_opengl.cpp" bool AppIsRunning = true; bool WaitForEvents = false; int64_t FrameID; 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 450"; 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, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5); 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_HIGH_PIXEL_DENSITY; SDL_Window *window = SDL_CreateWindow("Text editor", 1280, 720, 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; } SDL_GL_SetSwapInterval(1); // vsync glDebugMessageCallback(&GLDebugCallback, NULL); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); { Scratch scratch; Atlas atlas = CreateAtlas(scratch, {1024, 1024}); MainFont = 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); } MainFont.texture_id = atlas.texture_id; } InitRender(); while (AppIsRunning) { FrameID += 1; int window_x, window_y; SDL_GetWindowSize(window, &window_x, &window_y); Vec2 window_size = {(float)window_x, (float)window_y}; BeginFrameRender(window_size); SDL_Event event; if (WaitForEvents) { SDL_WaitEvent(&event); ProcessSDLEvent(&event); } while (SDL_PollEvent(&event)) { ProcessSDLEvent(&event); } { Scratch scratch; uint64_t ms = SDL_GetTicks(); double time = (double)ms / 1000.0; String string = Format(scratch, "%d %f %f", (int)FrameID, time, (time / (double)FrameID)); DrawString(&MainFont, ToString16(scratch, string), {0, 0}, {255, 0, 0, 255}); } EndFrameRender({0, 0, 0, 1}); SDL_GL_SwapWindow(window); } SDL_DestroyWindow(window); SDL_Quit(); return 0; }