Created
October 1, 2025 04:47
-
-
Save Lightnet/e4b03d0bf7d982bc9d3b0663c02f316a to your computer and use it in GitHub Desktop.
Revisions
-
Lightnet created this gist
Oct 1, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,8 @@ Flecs: 4.1 Glad: 2.0.8 opengl: 330 sdl: 3.2 just sample test. cimgui: 1.92 This is just cube render set up test. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,243 @@ // module_font.c #include "module_font.h" #include <stdio.h> #include <stdlib.h> #define STB_TRUETYPE_IMPLEMENTATION #include "stb_truetype.h" // Define FontData locally struct FontData { GLuint texture; // Font texture ID stbtt_bakedchar* cdata; // Character data (ASCII 32..127) int bitmap_w, bitmap_h; // Bitmap dimensions }; // Static FontData for alternative functions static struct FontData* global_font_data = NULL; // Initialize font: Load TTF and bake bitmap int init_font(const char* font_path, float font_size, float scale, FontData** font_data) { *font_data = (struct FontData*)malloc(sizeof(struct FontData)); if (!*font_data) { printf("Error: Failed to allocate FontData\n"); return 0; } unsigned char* ttf_buffer = (unsigned char*)malloc(1 << 20); if (!ttf_buffer) { printf("Error: Failed to allocate TTF buffer\n"); free(*font_data); *font_data = NULL; return 0; } FILE* ff = fopen(font_path, "rb"); if (!ff) { printf("Error: Failed to open font file '%s'\n", font_path); free(ttf_buffer); free(*font_data); *font_data = NULL; return 0; } fread(ttf_buffer, 1, 1 << 20, ff); fclose(ff); (*font_data)->bitmap_w = 512; (*font_data)->bitmap_h = 512; unsigned char* bitmap = (unsigned char*)malloc((*font_data)->bitmap_w * (*font_data)->bitmap_h); if (!bitmap) { printf("Error: Failed to allocate bitmap\n"); free(ttf_buffer); free(*font_data); *font_data = NULL; return 0; } (*font_data)->cdata = (stbtt_bakedchar*)malloc(96 * sizeof(stbtt_bakedchar)); if (!(*font_data)->cdata) { printf("Error: Failed to allocate cdata\n"); free(bitmap); free(ttf_buffer); free(*font_data); *font_data = NULL; return 0; } stbtt_BakeFontBitmap(ttf_buffer, 0, font_size * scale, bitmap, (*font_data)->bitmap_w, (*font_data)->bitmap_h, 32, 96, (*font_data)->cdata); free(ttf_buffer); // Create OpenGL texture glGenTextures(1, &(*font_data)->texture); glBindTexture(GL_TEXTURE_2D, (*font_data)->texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, (*font_data)->bitmap_w, (*font_data)->bitmap_h, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); free(bitmap); return 1; } // Render text void render_text(FontData* font_data, GLuint program, GLuint vao, GLuint vbo, const char* text, float x, float y, int ww, int hh, float r, float g, float b, float a) { if (!font_data) return; float vertices[1024 * 4]; // Enough for simple text int vert_count = 0; for (const char* p = text; *p; p++) { if (*p >= 32 && *p < 128) { stbtt_aligned_quad q; stbtt_GetBakedQuad(font_data->cdata, font_data->bitmap_w, font_data->bitmap_h, *p - 32, &x, &y, &q, 1); float nx0 = 2.0f * q.x0 / ww - 1.0f; float ny0 = 1.0f - 2.0f * q.y0 / hh; float nx1 = 2.0f * q.x1 / ww - 1.0f; float ny1 = 1.0f - 2.0f * q.y1 / hh; // Triangle 1 vertices[vert_count++] = nx0; vertices[vert_count++] = ny0; vertices[vert_count++] = q.s0; vertices[vert_count++] = q.t0; vertices[vert_count++] = nx1; vertices[vert_count++] = ny0; vertices[vert_count++] = q.s1; vertices[vert_count++] = q.t0; vertices[vert_count++] = nx1; vertices[vert_count++] = ny1; vertices[vert_count++] = q.s1; vertices[vert_count++] = q.t1; // Triangle 2 vertices[vert_count++] = nx0; vertices[vert_count++] = ny0; vertices[vert_count++] = q.s0; vertices[vert_count++] = q.t0; vertices[vert_count++] = nx1; vertices[vert_count++] = ny1; vertices[vert_count++] = q.s1; vertices[vert_count++] = q.t1; vertices[vert_count++] = nx0; vertices[vert_count++] = ny1; vertices[vert_count++] = q.s0; vertices[vert_count++] = q.t1; } } glUseProgram(program); glUniform1i(glGetUniformLocation(program, "textTexture"), 0); glUniform4f(glGetUniformLocation(program, "textColor"), r, g, b, a); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, font_data->texture); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, vert_count * sizeof(float), vertices, GL_DYNAMIC_DRAW); glDrawArrays(GL_TRIANGLES, 0, vert_count / 4); glBindVertexArray(0); } // Clean up font resources void cleanup_font(FontData* font_data) { if (!font_data) return; glDeleteTextures(1, &font_data->texture); free(font_data->cdata); free(font_data); } // Alternative functions using a static FontData int init_font_alt(const char* font_path, float font_size, float scale) { if (global_font_data) { cleanup_font(global_font_data); } return init_font(font_path, font_size, scale, &global_font_data); } void render_text_alt(GLuint program, GLuint vao, GLuint vbo, const char* text, float x, float y, int ww, int hh, float r, float g, float b, float a) { if (global_font_data) { render_text(global_font_data, program, vao, vbo, text, x, y, ww, hh, r, g, b, a); } } void cleanup_font_alt(void) { if (global_font_data) { cleanup_font(global_font_data); global_font_data = NULL; } } // Initialize shaders and VAO/VBO int init_font_shaders_and_buffers(GLuint* program, GLuint* vao, GLuint* vbo) { const char* vs_src = "#version 330 core\n" "layout(location = 0) in vec2 position;\n" "layout(location = 1) in vec2 texCoord;\n" "out vec2 TexCoord;\n" "void main() {\n" " gl_Position = vec4(position, 0.0, 1.0);\n" " TexCoord = texCoord;\n" "}\n"; const char* fs_src = "#version 330 core\n" "in vec2 TexCoord;\n" "out vec4 FragColor;\n" "uniform sampler2D textTexture;\n" "uniform vec4 textColor;\n" "void main() {\n" " float alpha = texture(textTexture, TexCoord).r;\n" " FragColor = vec4(textColor.rgb, alpha * textColor.a);\n" "}\n"; GLuint vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, &vs_src, NULL); glCompileShader(vs); GLint success; glGetShaderiv(vs, GL_COMPILE_STATUS, &success); if (!success) { char info_log[512]; glGetShaderInfoLog(vs, 512, NULL, info_log); printf("Vertex shader compilation failed: %s\n", info_log); return 0; } GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, &fs_src, NULL); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &success); if (!success) { char info_log[512]; glGetShaderInfoLog(fs, 512, NULL, info_log); printf("Fragment shader compilation failed: %s\n", info_log); glDeleteShader(vs); return 0; } *program = glCreateProgram(); glAttachShader(*program, vs); glAttachShader(*program, fs); glLinkProgram(*program); glGetProgramiv(*program, GL_LINK_STATUS, &success); if (!success) { char info_log[512]; glGetProgramInfoLog(*program, 512, NULL, info_log); printf("Program linking failed: %s\n", info_log); glDeleteShader(vs); glDeleteShader(fs); return 0; } glDeleteShader(vs); glDeleteShader(fs); glGenVertexArrays(1, vao); glGenBuffers(1, vbo); glBindVertexArray(*vao); glBindBuffer(GL_ARRAY_BUFFER, *vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glBindVertexArray(0); return 1; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ // module_font.h #pragma once // #ifndef MODULE_FONT_H // #define MODULE_FONT_H #include <glad/gl.h> // Opaque pointer to FontData typedef struct FontData FontData; int init_font_shaders_and_buffers(GLuint* program, GLuint* vao, GLuint* vbo); // Functions using FontData int init_font(const char* font_path, float font_size, float scale, FontData** font_data); void render_text(FontData* font_data, GLuint program, GLuint vao, GLuint vbo, const char* text, float x, float y, int ww, int hh, float r, float g, float b, float a); void cleanup_font(FontData* font_data); // Alternative functions (no FontData, for internal management) int init_font_alt(const char* font_path, float font_size, float scale); void render_text_alt(GLuint program, GLuint vao, GLuint vbo, const char* text, float x, float y, int ww, int hh, float r, float g, float b, float a); void cleanup_font_alt(void); // #endif // MODULE_FONT_H /* // refs typedef struct { GLuint texture; stbtt_bakedchar* cdata; int bitmap_w, bitmap_h; } FontData; render_text(&font_data, text_program, text_vao, text_vbo, text, 25.0f, 150.0f, ww, hh, 1.0f, 1.0f, 1.0f, 1.0f); */ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,596 @@ // #include <SDL3/SDL.h> #include <glad/gl.h> #include <stdio.h> #include <stdlib.h> #include <cimgui.h> #include <cimgui_impl.h> #include "module_font.h" #include <cglm/cglm.h> // Include CGLM #include "flecs.h" #define igGetIO igGetIO_Nil typedef struct { float x; float y; } Position; typedef struct { float x; float y; } Velocity; typedef struct { vec3 position; // Vector3 for position (x, y, z) vec3 rotation; // Euler angles in degrees (x, y, z) vec3 scale; // Scale (x, y, z) mat4 local; // Local transformation matrix mat4 world; // World transformation matrix bool isDirty; // Flag to indicate if transform needs recalculation } Transform3D; ECS_COMPONENT_DECLARE(Transform3D); typedef struct { GLuint vao, vbo, ebo; // OpenGL buffer objects GLuint shaderProgram; // Shader program for the cube int indexCount; // Number of indices for rendering } CubeContext; // Cube vertices: position (x, y, z) static const float cubeVertices[] = { // Front face -0.5f, -0.5f, 0.5f, // 0 0.5f, -0.5f, 0.5f, // 1 0.5f, 0.5f, 0.5f, // 2 -0.5f, 0.5f, 0.5f, // 3 // Back face -0.5f, -0.5f, -0.5f, // 4 0.5f, -0.5f, -0.5f, // 5 0.5f, 0.5f, -0.5f, // 6 -0.5f, 0.5f, -0.5f // 7 }; // Indices for the cube (6 faces, 2 triangles per face, 3 vertices per triangle) static const unsigned int cubeIndices[] = { // Front 0, 1, 2, 2, 3, 0, // Right 1, 5, 6, 6, 2, 1, // Back 5, 4, 7, 7, 6, 5, // Left 4, 0, 3, 3, 7, 4, // Top 3, 2, 6, 6, 7, 3, // Bottom 4, 5, 1, 1, 0, 4 }; bool init_cube_mesh(CubeContext* cube) { // Vertex Shader const char* vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "uniform mat4 model;\n" "uniform mat4 view;\n" "uniform mat4 projection;\n" "void main() {\n" " gl_Position = projection * view * model * vec4(aPos, 1.0);\n" "}\n"; // Fragment Shader (simple color) const char* fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "void main() {\n" " FragColor = vec4(1.0, 0.5, 0.2, 1.0);\n" // Orange color "}\n"; // Compile shaders GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); GLint success; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { char infoLog[512]; glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); printf("Vertex Shader Compilation Failed: %s\n", infoLog); return false; } GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { char infoLog[512]; glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); printf("Fragment Shader Compilation Failed: %s\n", infoLog); return false; } cube->shaderProgram = glCreateProgram(); glAttachShader(cube->shaderProgram, vertexShader); glAttachShader(cube->shaderProgram, fragmentShader); glLinkProgram(cube->shaderProgram); glGetProgramiv(cube->shaderProgram, GL_LINK_STATUS, &success); if (!success) { char infoLog[512]; glGetProgramInfoLog(cube->shaderProgram, 512, NULL, infoLog); printf("Shader Program Linking Failed: %s\n", infoLog); return false; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Setup VAO, VBO, EBO glGenVertexArrays(1, &cube->vao); glGenBuffers(1, &cube->vbo); glGenBuffers(1, &cube->ebo); glBindVertexArray(cube->vao); glBindBuffer(GL_ARRAY_BUFFER, cube->vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube->ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); cube->indexCount = sizeof(cubeIndices) / sizeof(cubeIndices[0]); return true; } void update_transform_system(ecs_iter_t *it) { Transform3D *transforms = ecs_field(it, Transform3D, 0); for (int i = 0; i < it->count; i++) { if (!transforms[i].isDirty) continue; mat4 local; glm_mat4_identity(local); glm_scale(local, transforms[i].scale); glm_rotate_x(local, glm_rad(transforms[i].rotation[0]), local); glm_rotate_y(local, glm_rad(transforms[i].rotation[1]), local); glm_rotate_z(local, glm_rad(transforms[i].rotation[2]), local); glm_translate(local, transforms[i].position); glm_mat4_copy(local, transforms[i].local); glm_mat4_copy(local, transforms[i].world); // No parent transform transforms[i].isDirty = false; printf("Updated transform %d: Pos=(%.2f, %.2f, %.2f)\n", i, transforms[i].position[0], transforms[i].position[1], transforms[i].position[2]); } } // void update_transform_system(ecs_iter_t *it) { // Transform3D *transforms = ecs_field(it, Transform3D, 0); // for (int i = 0; i < it->count; i++) { // if (!transforms[i].isDirty) continue; // // Calculate local matrix // mat4 local; // glm_mat4_identity(local); // // Apply scale // glm_scale(local, transforms[i].scale); // // Apply rotation (Euler angles in degrees) // glm_rotate_x(local, glm_rad(transforms[i].rotation[0]), local); // glm_rotate_y(local, glm_rad(transforms[i].rotation[1]), local); // glm_rotate_z(local, glm_rad(transforms[i].rotation[2]), local); // // Apply translation // glm_translate(local, transforms[i].position); // glm_mat4_copy(local, transforms[i].local); // // Check for parent transform // ecs_entity_t parent = ecs_get_parent(it->world, it->entities[i]); // if (parent && ecs_has(it->world, parent, Transform3D)) { // Transform3D *parent_transform = ecs_get_mut(it->world, parent, Transform3D); // mat4 world; // glm_mat4_mul(parent_transform->world, local, world); // glm_mat4_copy(world, transforms[i].world); // } else { // glm_mat4_copy(local, transforms[i].world); // } // transforms[i].isDirty = false; // } // } void render_3d_cube_system(ecs_iter_t *it) { Transform3D *transforms = ecs_field(it, Transform3D, 0); CubeContext *cube = (CubeContext *)ecs_get_ctx(it->world); if (!cube) { printf("CubeContext is NULL in render_3d_cube_system!\n"); return; } printf("Rendering %d cubes\n", it->count); if (it->count == 0) { printf("No entities with Transform3D found!\n"); return; } glUseProgram(cube->shaderProgram); // Ensure depth testing is enabled glEnable(GL_DEPTH_TEST); // Setup view and projection matrices mat4 view, projection; glm_mat4_identity(view); glm_lookat((vec3){0.0f, 0.0f, 5.0f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){0.0f, 1.0f, 0.0f}, view); int ww, hh; SDL_GetWindowSize(SDL_GL_GetCurrentWindow(), &ww, &hh); glm_perspective(glm_rad(45.0f), (float)ww / hh, 0.1f, 100.0f, projection); GLint modelLoc = glGetUniformLocation(cube->shaderProgram, "model"); GLint viewLoc = glGetUniformLocation(cube->shaderProgram, "view"); GLint projLoc = glGetUniformLocation(cube->shaderProgram, "projection"); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, (float*)view); glUniformMatrix4fv(projLoc, 1, GL_FALSE, (float*)projection); glBindVertexArray(cube->vao); for (int i = 0; i < it->count; i++) { printf("Rendering cube %d: Pos=(%.2f, %.2f, %.2f), Rot=(%.2f, %.2f, %.2f), Scale=(%.2f, %.2f, %.2f)\n", i, transforms[i].position[0], transforms[i].position[1], transforms[i].position[2], transforms[i].rotation[0], transforms[i].rotation[1], transforms[i].rotation[2], transforms[i].scale[0], transforms[i].scale[1], transforms[i].scale[2]); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, (float*)transforms[i].world); glDrawElements(GL_TRIANGLES, cube->indexCount, GL_UNSIGNED_INT, 0); } glBindVertexArray(0); // Check for OpenGL errors GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { printf("OpenGL Error in render_3d_cube_system: %u\n", err); } } // nope error on attach child // void start_up_system(ecs_iter_t *it) { // printf("start up\n"); // // Create parent cube // ecs_entity_t parent = ecs_entity(it->world, { .name = "ParentCube" }); // ecs_set(it->world, parent, Transform3D, { // .position = {0.0f, 0.0f, 0.0f}, // .rotation = {0.0f, 0.0f, 0.0f}, // .scale = {1.0f, 1.0f, 1.0f}, // .isDirty = true // }); // // Create child cube // ecs_entity_t child = ecs_entity(it->world, { .name = "ChildCube" }); // ecs_set(it->world, child, Transform3D, { // .position = {2.0f, 0.0f, 0.0f}, // Offset from parent // .rotation = {0.0f, 45.0f, 0.0f}, // .scale = {0.5f, 0.5f, 0.5f}, // .isDirty = true // }); // ecs_add_pair(it->world, child, EcsChildOf, parent); // // Initialize cube mesh // CubeContext* cube = malloc(sizeof(CubeContext)); // if (!init_cube_mesh(cube)) { // printf("Failed to initialize cube mesh\n"); // return; // } // ecs_set_ctx(it->world, cube, NULL); // } int main() { if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) { fprintf(stderr, "Failed to init video! %s\n", SDL_GetError()); return 1; } float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_OPENGL; SDL_Window* window = SDL_CreateWindow("SDL3 OpenGL Font Tranformer 3d", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags); if (!window) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); SDL_Quit(); return -1; } SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_ShowWindow(window); // Create OpenGL context 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, 3); SDL_GLContext gl_context = SDL_GL_CreateContext(window); if (!gl_context) { printf("Error: SDL_GL_CreateContext(): %s\n", SDL_GetError()); SDL_DestroyWindow(window); SDL_Quit(); return -1; } SDL_GL_MakeCurrent(window, gl_context); int version = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress); if (version == 0) { printf("Failed to initialize GLAD\n"); SDL_GL_DestroyContext(gl_context); SDL_DestroyWindow(window); SDL_Quit(); return 1; } printf("OpenGL loaded: version %s\n", glGetString(GL_VERSION)); FontData *font_data = NULL; if (!init_font("resources/Kenney Mini.ttf", 32.0f, main_scale, &font_data)) { SDL_GL_DestroyContext(gl_context); SDL_DestroyWindow(window); SDL_Quit(); return -1; } // Initialize shaders and buffers GLuint program, vao, vbo; if (!init_font_shaders_and_buffers(&program, &vao, &vbo)) { // cleanup_font(&font_data); cleanup_font(font_data); SDL_GL_DestroyContext(gl_context); SDL_DestroyWindow(window); SDL_Quit(); return -1; } // Setup Dear ImGui context igCreateContext(NULL); ImGuiIO* io = igGetIO(); io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Setup Dear ImGui style igStyleColorsDark(NULL); ImGuiStyle* style = igGetStyle(); ImGuiStyle_ScaleAllSizes(style, main_scale); // Setup Platform/Renderer backends ImGui_ImplSDL3_InitForOpenGL(window, gl_context); ImGui_ImplOpenGL3_Init("#version 330"); // Our state bool show_demo_window = true; bool show_another_window = false; float clear_colorE4[4] = {0.45f, 0.55f, 0.60f, 1.00f}; ImVec4 clearColorE3; clearColorE3.x = 0.45f; clearColorE3.y = 0.55f; clearColorE3.z = 0.60f; clearColorE3.w = 1.00f; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f}; bool done = false; const char* text = "Hello World! Glad 2.0.8"; ecs_world_t *world = ecs_init(); CubeContext* cube; ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); // ECS_COMPONENT(world, CubeContext); ECS_COMPONENT(world, Transform3D); // EcsOnStart // EcsPreUpdate // EcsOnUpdate // EcsPostUpdate // start up system // ECS_SYSTEM(world, start_up_system, EcsOnStart); ECS_SYSTEM(world, update_transform_system, EcsPreUpdate, Transform3D); //render 3d cube ECS_SYSTEM(world, render_3d_cube_system, EcsOnUpdate, Transform3D); // Create parent cube ecs_entity_t parent = ecs_entity(world, { .name = "ParentCube" }); ecs_set(world, parent, Transform3D, { .position = {0.0f, 0.0f, 0.0f}, .rotation = {0.0f, 0.0f, 0.0f}, .scale = {1.0f, 1.0f, 1.0f}, .isDirty = true }); // Create child cube ecs_entity_t child = ecs_entity(world, { .name = "ChildCube" }); ecs_set(world, child, Transform3D, { // .position = {2.0f, 0.0f, 0.0f}, // Offset from parent .position = {0.0f, 0.0f, 0.0f}, // Offset from parent // .rotation = {0.0f, 0.0f, 0.0f}, .rotation = {0.0f, 45.0f, 0.0f}, .scale = {1.0f, 1.0f, 1.0f}, .isDirty = true }); ecs_add_pair(world, child, EcsChildOf, parent); // Initialize cube mesh cube = malloc(sizeof(CubeContext)); if (!init_cube_mesh(cube)) { printf("Failed to initialize cube mesh\n"); // return; } ecs_set_ctx(world, cube, NULL); // Do the ECS stuff ecs_entity_t e = ecs_entity(world, { .name = "Bob" }); printf("Entity name: %s\n", ecs_get_name(world, e)); // glEnable(GL_DEPTH_TEST); while (!done) { SDL_Event event; while (SDL_PollEvent(&event)) { ImGui_ImplSDL3_ProcessEvent(&event); if (event.type == SDL_EVENT_QUIT) done = true; if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window)) done = true; } if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) { SDL_Delay(10); continue; } // Start the Dear ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplSDL3_NewFrame(); igNewFrame(); // Simple window { static float f = 0.0f; static int counter = 0; // igBegin("Hello, world!", NULL, 0); // igText("This is some useful text."); // igCheckbox("Demo Window", &show_demo_window); // igCheckbox("Another Window", &show_another_window); // igSliderFloat("float", &f, 0.0f, 1.0f, "%.3f", 0); // igText("Choose a color:"); // if(igColorEdit4("clear color E4", (float*)&clear_colorE4, 0)){ // // Log the new color values whenever they change // printf("Color changed to: R=%.2f, G=%.2f, B=%.2f, A=%.2f\n", // clear_colorE4[0], clear_colorE4[1], clear_colorE4[2], clear_colorE4[3]); // } // igColorEdit3("clear color E3", (float *)&clearColorE3, 0); // ImVec2 buttonSize = {0, 0}; // if (igButton("Button", buttonSize)) // counter++; // igSameLine(0.0f, -1.0f); // igText("counter = %d", counter); // igText("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io->Framerate, io->Framerate); // igEnd(); } { igBegin("transform3d", NULL, 0); ImVec2 buttonSize = {0, 0}; if (igButton("query", buttonSize)){ } igEnd(); } // Rendering igRender(); int ww, hh; SDL_GetWindowSize(window, &ww, &hh); glViewport(0, 0, ww, hh); glViewport(0, 0, (int)io->DisplaySize.x, (int)io->DisplaySize.y); //cimgui glClearColor(clear_colorE4[0], clear_colorE4[1], clear_colorE4[2], clear_colorE4[3]); // glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); // glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Enable depth testing for 3D rendering glEnable(GL_DEPTH_TEST); // Test cube rendering // { // printf("Test cube rendering\n"); // glUseProgram(cube->shaderProgram); // // Setup view and projection matrices (same as render_3d_cube_system) // mat4 view, projection; // glm_mat4_identity(view); // glm_lookat((vec3){0.0f, 0.0f, 5.0f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){0.0f, 1.0f, 0.0f}, view); // glm_perspective(glm_rad(45.0f), (float)ww / hh, 0.1f, 100.0f, projection); // // Simple model matrix (e.g., translate to (0, 0, 0) with no rotation or scale) // mat4 model; // glm_mat4_identity(model); // // Optional: Translate to make sure it’s visible // glm_translate(model, (vec3){0.0f, 0.0f, 0.0f}); // // Set uniforms // GLint modelLoc = glGetUniformLocation(cube->shaderProgram, "model"); // GLint viewLoc = glGetUniformLocation(cube->shaderProgram, "view"); // GLint projLoc = glGetUniformLocation(cube->shaderProgram, "projection"); // glUniformMatrix4fv(modelLoc, 1, GL_FALSE, (float*)model); // glUniformMatrix4fv(viewLoc, 1, GL_FALSE, (float*)view); // glUniformMatrix4fv(projLoc, 1, GL_FALSE, (float*)projection); // // Draw the cube // glBindVertexArray(cube->vao); // glDrawElements(GL_TRIANGLES, cube->indexCount, GL_UNSIGNED_INT, 0); // glBindVertexArray(0); // // Check for OpenGL errors // GLenum err; // while ((err = glGetError()) != GL_NO_ERROR) { // printf("OpenGL Error during test render: %u\n", err); // } // } ecs_progress(world, 0); // run systems in default pipeline // Render 2D text // render_text(&font_data, program, vao, vbo, text, 25.0f, 150.0f, ww, hh, 1.0f, 1.0f, 1.0f, 1.0f);// test render_text(font_data, program, vao, vbo, "Hello, World!", 100.0f, 100.0f, ww, hh, 1.0f, 1.0f, 1.0f, 1.0f); ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); SDL_GL_SwapWindow(window); } // Cleanup // CubeContext* cube = ecs_get_ctx(world); // cube = ecs_get_ctx(world); if (cube) { glDeleteVertexArrays(1, &cube->vao); glDeleteBuffers(1, &cube->vbo); glDeleteBuffers(1, &cube->ebo); glDeleteProgram(cube->shaderProgram); free(cube); } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplSDL3_Shutdown(); igDestroyContext(NULL); cleanup_font(font_data); // conflict due cimgui modified font match data type. glDeleteProgram(program); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); ecs_fini(world); SDL_GL_DestroyContext(gl_context); SDL_DestroyWindow(window); SDL_Quit(); return 0; }