#define GLFW_INCLUDE_NONE #include #include "glad.h" #include "Renderer.h" #include "Win32AssetManager.h" #include "TouchInput.h" #include "Position.h" #include "GameState.h" #include "Profiling.h" #undef APIENTRY #define WIN32_LEAN_AND_MEAN #include #include struct CodePointsArray { unsigned int* cps; // codepoints unsigned int count; unsigned int cap; }; struct UserData { CodePointsArray cp_array; double scroll_offset; }; static void errorCallback(int error, const char* desc) { MessageBoxA(NULL, desc, "Error", MB_ICONERROR | MB_OK); } static void charCallback(GLFWwindow* window, unsigned int cp) { ZoneScoped; UserData* ud = reinterpret_cast(glfwGetWindowUserPointer(window)); assert(ud != nullptr); if (ud->cp_array.count < ud->cp_array.cap) ud->cp_array.cps[ud->cp_array.count++] = cp; } static void scrollCallback(GLFWwindow* window, double /* xoffset */, double yoffset) { ZoneScoped; UserData* ud = reinterpret_cast(glfwGetWindowUserPointer(window)); assert(ud != nullptr); ud->scroll_offset = yoffset; } int main() { glfwSetErrorCallback(errorCallback); if (!glfwInit()) { return 1; } unsigned int pressed_codepoints[100]; UserData ud = {}; ud.cp_array = {pressed_codepoints, 0, 100}; glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); GLFWwindow* window = glfwCreateWindow(1024, 768, "Krimi Dinner", nullptr, nullptr); if (!window) { glfwTerminate(); return 1; } glfwSetWindowUserPointer(window, &ud); glfwSetCharCallback(window, charCallback); glfwSetScrollCallback(window, scrollCallback); glfwMakeContextCurrent(window); int ret = gladLoadGLES2Loader((GLADloadproc)glfwGetProcAddress); if (!ret) { MessageBoxA(nullptr, "Failed to load GLES3", "Error", MB_ICONERROR | MB_OK); glfwDestroyWindow(window); glfwTerminate(); return 1; } GameState state = {}; const char* asset_dir = "app\\src\\main\\assets"; Win32AssetManager::create(asset_dir); Renderer::create(); // BEISPIELCODE Position smiley_pos = {512, 384}; StringHandle smiley = StringRepository::global->internString("smiley_PNG42.png"); StringHandle ttf = StringRepository::global->internString("Milky Honey.ttf"); FontData fd; AssetManager::ptr->loadFontData("Milky Honey.ttf", 24.f, &fd); // ENDE BEISPIELCODE glfwSwapInterval(1); while (!glfwWindowShouldClose(window)) { /* Reset the pressed codepoints array and scroll offset * because glfwPollEvents() will call our callbacks */ ud.cp_array.count = 0; ud.scroll_offset = 0.0; glfwPollEvents(); /* Gather keyboard input */ int pressed_keys[GLFW_KEY_LAST + 1]; unsigned int pressed_key_count = 0; for (int key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; ++key) { if (glfwGetKey(window, key) == GLFW_PRESS) { pressed_keys[pressed_key_count++] = key; } } /* Gather mouse input */ TouchInputEvent input_events[1] = {}; int input_event_count = 0; if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) { double x, y; glfwGetCursorPos(window, &x, &y); input_events[0].kind = TouchInputEventKind::Tap; input_events[0].start = {static_cast(x), static_cast(y)}; input_events[0].end = input_events[0].start; input_event_count = 1; } int w, h; glfwGetFramebufferSize(window, &w, &h); float display_width = static_cast(w); float display_height = static_cast(h); // INTEGRATION Rufe hier deine "gameloop"/"update" funktion auf, die als Parameter // den GameState, input_events und input_event_count und die Displaygröße bekommen sollte: // // kUpdate(&state, input_events, input_event_count, // ud.scroll_offset, // ud.cp_array.cps, ud.cp_array.count, // pressed_keys, pressed_key_count, // display_width, display_height) // // // Die Funktion könnte folgende Definition haben: // void kUpdate(GameState* state, // const TouchInputEvent* touch_events, // unsigned int touch_event_count, // double scroll_offset, // const unsigned int* pressed_codepoints, // unsigned int codepoint_count, // const int* pressed_keys, // unsigned int pressed_key_count, // float display_width, // float display_height) // ENDE INTEGRATION // BEISPIELCODE static float x = 1.f; static float d = -0.01f; x += d; if (x <= 0.f) d *= -1.f; else if (x >= 1.f) d *= -1.f; if (input_event_count > 0) { smiley_pos = input_events[0].end; smiley_pos.x -= 250; smiley_pos.y -= 250; } if (ud.scroll_offset != 0) { smiley_pos.y += ud.scroll_offset; } if (pressed_key_count > 0) { for (unsigned int i = 0; i < pressed_key_count; ++i) { if (pressed_keys[i] == GLFW_KEY_LEFT_CONTROL) smiley_pos = {100, 100}; } } Renderer::ptr->addRect(100, 100, 500, 500, 0.3f, 0.3f, 0.3f, 1.f); Renderer::ptr->addRect(smiley_pos.x, smiley_pos.y, 500, 500, 0.f, x * x, 1.f - x * x, 1.f, smiley); const char* text = "Hello, Sailor!"; float tx = 100, ty = 200; while (*text) { if (*text >= 32 && *text < 128) { stbtt_aligned_quad q; stbtt_GetBakedQuad(fd.char_data, 1024, 1024, *text - 32, &tx, &ty, &q, 1); float w = q.x1 - q.x0, h = q.y1 - q.y0; Renderer::ptr->addFontRect(q.x0, q.y0, w, h, fd.char_height, ttf, StringRepository::global->internString("1"), q.s0, q.t0, q.s1, q.t1); } ++text; } // ENDE BEISPIELCODE Renderer::ptr->renderFrame(static_cast(w), static_cast(h)); glfwSwapBuffers(window); FrameMark; } glfwDestroyWindow(window); glfwTerminate(); return 0; }