From 37a9f55ecd39f99aa800adc875555ecd613722c4 Mon Sep 17 00:00:00 2001 From: 0scar Date: Thu, 1 Feb 2024 22:27:06 +0100 Subject: Fixme! --- src/engine.c | 765 ++++++++++++++++++++++++--------------------------- src/rendering.c | 93 +++---- src/ui_positioning.c | 90 +++--- src/ui_rendering.c | 187 +------------ 4 files changed, 436 insertions(+), 699 deletions(-) (limited to 'src') diff --git a/src/engine.c b/src/engine.c index 4c4f0cb..0c56b90 100644 --- a/src/engine.c +++ b/src/engine.c @@ -3,21 +3,20 @@ #include #include -#include -#define GLFW_INCLUDE_NONE +//#define GLAD_GL_IMPLEMENTATION +//#include +//#define GLFW_INCLUDE_NONE #include -#include -#include -#include - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) /* include winapi */ +#include #elif defined(__APPLE__) /* mac includes */ #elif defined(__linux) || defined(__linux__) || defined(linux) #include +#include #endif @@ -36,8 +35,8 @@ #ifdef BENCHMARK #define BENCHEXPR(timevar, expr) \ { \ - u32 t = SDL_GetTicks(); \ - expr timevar += SDL_GetTicks() - t; \ + u32 t = glfwGetTime(); \ + expr timevar += glfwGetTime() - t; \ } extern i32 drawcall_len; @@ -46,13 +45,146 @@ extern i32 drawcall_len; #define BENCHEXPR(timevar, expr) expr #endif + +// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/ +GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){ + + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + char* VertexShaderCode; + FILE* VertexShaderStream = fopen(vertex_file_path, "r"); + if(VertexShaderStream != NULL){ + fseek(VertexShaderStream, 0, SEEK_END); + const i64 size = ftell(VertexShaderStream); + rewind(VertexShaderStream); + VertexShaderCode = calloc(size + 1, sizeof(char)); + + // Assume the whole file is successfully read + fread(VertexShaderCode, sizeof(char), size, VertexShaderStream); + //LOG("vertex source is %d bytes\n%s\n", size, VertexShaderCode); + + fclose(VertexShaderStream); + } else { + ERROR("Impossible to open %s. Are you in the right directory?\n", vertex_file_path); + getchar(); + return 0; + } + + // Read the Fragment Shader code from the file + char* FragmentShaderCode; + FILE* FragmentShaderStream = fopen(fragment_file_path, "r"); + if(FragmentShaderStream != NULL){ + fseek(FragmentShaderStream, 0, SEEK_END); + const i64 size = ftell(FragmentShaderStream); + rewind(FragmentShaderStream); + FragmentShaderCode = calloc(size + 1, sizeof(char)); + + // Assume the whole file is successfully read + fread(FragmentShaderCode, sizeof(char), size, FragmentShaderStream); + LOG("fragment source is %d bytes", size); + + fclose(FragmentShaderStream); + } else { + ERROR("Impossible to open %s. Are you in the right directory?\n", fragment_file_path); + getchar(); + return 0; + } + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + INFO("Compiling shader: %s\n", vertex_file_path); + char const * VertexSourcePointer = VertexShaderCode; + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ) { + char* msg = calloc(InfoLogLength + 1, sizeof(char)); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, msg); + ERROR("Compiling shader: %s\n", msg); + free(msg); + } + + // Compile Fragment Shader + INFO("Compiling shader: %s\n", fragment_file_path); + char const * FragmentSourcePointer = FragmentShaderCode; + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + char* msg = calloc(InfoLogLength + 1, sizeof(char)); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, msg); + ERROR("Compiling shader: %s\n", msg); + free(msg); + } + + // Link the program + INFO("Linking program\n"); + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + char* msg = calloc(InfoLogLength + 1, sizeof(char)); + glGetShaderInfoLog(ProgramID, InfoLogLength, NULL, msg); + ERROR("Compiling shader: %s\n", msg); + free(msg); + } + + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + + free(VertexShaderCode); + free(FragmentShaderCode); + return ProgramID; +} + + + + + + + + + + + static u64 FPS_CAP = 50; Platform* GLOBAL_PLATFORM = NULL; input_callback_t* callbacks[128]; usize callbacks_len; -i32 nproc(void) { return SDL_GetCPUCount(); } +i32 nproc(void) { + return get_nprocs(); +} + +void delay( uint32_t ms ) +{ +#ifdef _WIN32 + Sleep( ms ); +#else + usleep( ms * 1000 ); +#endif +} i32 cmp_int(const void* a, const void* b) { const i32* x = a; @@ -61,17 +193,15 @@ i32 cmp_int(const void* a, const void* b) { return *x - *y; } -v2_i32 get_canvas_size(SDL_Renderer* renderer) { +v2_i32 get_canvas_size(void* window) { v2_i32 realsize; - SDL_GetRendererOutputSize(renderer, &(realsize.x), &(realsize.y)); + glfwGetWindowSize(window, &(realsize.x), &(realsize.y)); /* Set logical render size */ return realsize; } -Texture* load_texture(SDL_Renderer* render, const Asset_TextureSpec* ts) { - SDL_Texture* new_texture = NULL; - SDL_Surface* loaded_surface = NULL; +Texture* load_texture(void* render, const Asset_TextureSpec* ts) { Texture* t = NULL; if (ts == NULL) { @@ -79,134 +209,28 @@ Texture* load_texture(SDL_Renderer* render, const Asset_TextureSpec* ts) { return NULL; } - loaded_surface = IMG_Load(ts->path); - if (loaded_surface == NULL) { - ERROR("Unable to load image \"%s\"!\n", ts->path); - ERROR("SDL_image Error: %s\n", IMG_GetError()); - return NULL; - } - - const i32 tw = loaded_surface->w / ts->width; - - SDL_SetColorKey(loaded_surface, SDL_TRUE, - SDL_MapRGB(loaded_surface->format, 0xFF, 0x00, 0xFF)); - - /*Create texture from surface pixels */ - new_texture = SDL_CreateTextureFromSurface(render, loaded_surface); - if (new_texture == NULL) { - ERROR("Unable to create texture from \"%s\"!\n", ts->path); - ERROR("SDL Error: %s\n", SDL_GetError()); - } - - /*Get rid of old loaded surface */ - SDL_FreeSurface(loaded_surface); - - t = (Texture*)malloc(sizeof(Texture)); - t->texture = new_texture; - /* Assigning const value */ - *(i32*)&t->tilesize = tw; - *(i32*)&t->width = ts->width; - *(i32*)&t->height = ts->height; + //t = (Texture*)malloc(sizeof(Texture)); + //t->texture = new_texture; + ///* Assigning const value */ + //*(i32*)&t->tilesize = tw; + //*(i32*)&t->width = ts->width; + //*(i32*)&t->height = ts->height; return t; } -void engine_update_window(Window* w, SDL_WindowEvent* e) { - switch (e->event) { - case SDL_WINDOWEVENT_NONE: - case SDL_WINDOWEVENT_SHOWN: - case SDL_WINDOWEVENT_HIDDEN: - case SDL_WINDOWEVENT_EXPOSED: - case SDL_WINDOWEVENT_MOVED: - break; - case SDL_WINDOWEVENT_RESIZED: - w->windowsize = get_canvas_size(w->renderer); - LOG("Resized window to %dx%d", w->windowsize.x, w->windowsize.y); - ui_resolve_constraints(); - if (w->game_w != NULL && w->game_h != NULL) { - *w->game_h = w->windowsize.x; - *w->game_w = w->windowsize.y; - } - break; - case SDL_WINDOWEVENT_SIZE_CHANGED: - case SDL_WINDOWEVENT_MINIMIZED: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: - case SDL_WINDOWEVENT_ENTER: - case SDL_WINDOWEVENT_LEAVE: - case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_FOCUS_LOST: - case SDL_WINDOWEVENT_CLOSE: - case SDL_WINDOWEVENT_TAKE_FOCUS: - case SDL_WINDOWEVENT_HIT_TEST: - break; +void engine_update_window(Window* w, void* e) { + switch ((i32)e) { default: - WARN("Unhandled window event 0x%04x", (i32)e->event); + WARN("Unhandled window event 0x%04x", (i32)e); break; } return; } -struct sdl_ctx {SDL_Window* w; SDL_Renderer* r;} sdl_ctx; -struct glfw_ctx {GLFWwindow* w;} glfw_ctx; - -struct sdl_ctx initialize_SDL( - const char* windowtitle, v2_i32 windowsize, - const u32 flags - ) { - SDL_Window* window = NULL; - SDL_Renderer* renderer = NULL; - - INFO_("initializing sdl..."); - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - ERROR("failed to initialize sdl: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } else - printf("ok\n"); - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - - INFO_("creating window..."); - window = SDL_CreateWindow( - windowtitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - windowsize.x, windowsize.y, - SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_FOCUS | - SDL_WINDOW_MOUSE_FOCUS | flags); - - if (window == NULL) { - ERROR("failed to create window: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } else - printf("ok\n"); - - INFO_("creating renderer..."); - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - if (renderer == NULL) { - ERROR("failed to create renderer: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } else - printf("ok\n"); - - INFO_("initializing sdl_image..."); - if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) { - ERROR("failed to initialize sdl_image png support\n"); - exit(EXIT_FAILURE); - } else - printf("ok\n"); - - INFO_("initializing sdl_ttf..."); - if (TTF_Init() == -1) { - ERROR("failed to initialize sdl_ttf: %s\n", TTF_GetError()); - exit(EXIT_FAILURE); - } else - printf("ok\n"); - - return (struct sdl_ctx){.w = window,.r = renderer}; -} - +struct glfw_ctx { + GLFWwindow* w; +} glfw_ctx; /* GLFW And vulkan spaghetti boiler */ void glfw_err_callback(int code, const char* description) { @@ -220,7 +244,17 @@ struct QueueFamilyIndices { int64_t presentFamily; }; - +//GladGLContext* create_context(GLFWwindow *window) { +// glfwMakeContextCurrent(window); +// +// GladGLContext* context = (GladGLContext*) calloc(1, sizeof(GladGLContext)); +// if (!context) return NULL; +// +// int version = gladLoadGLContext(context, glfwGetProcAddress); +// INFO("Loaded OpenGL %d.%d", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version)); +// +// return context; +//} struct glfw_ctx initialize_GLFW( const char* windowtitle, v2_i32 windowsize, @@ -244,13 +278,24 @@ struct glfw_ctx initialize_GLFW( //glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - glfwWindowHint(GLFW_SAMPLES, 0); // Disable anti aliasing + glfwWindowHint(GLFW_SAMPLES, 4); // Disable anti aliasing + + // Use a modern opengl version + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); +#ifdef __APPLE__ + // To make MacOS happy; should not be needed + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); +#endif + + + /* "On Wayland specifically, you need to swap the buffers + * of a window for it to become visible." */ window = glfwCreateWindow(windowsize.x, windowsize.y, windowtitle, NULL, NULL); if (window == NULL) { ERROR("Failed to create GLFW window!\n"); @@ -263,26 +308,30 @@ struct glfw_ctx initialize_GLFW( glfwMakeContextCurrent(window); + // Remember to load GL :) (hours wasted because i forgot: approx 4) + int version = gladLoadGL(glfwGetProcAddress); + //printf("GL %d.%d\n", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version)); - gladLoadGL(glfwGetProcAddress); + +#ifdef _DEBUG + glClearColor((float)0x10 / 255.f, (float)0x0a / 255.f, (float)0x33 / 255.f, 0.f); +#else + glClearColor(0x0, 0x0, 0x0, 0.f); +#endif // TODO: Replace with callback //glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); - //while(!(glfwWindowShouldClose(window) && glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS)) { + //while(!(glfwWindowShouldClose(window) && glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS)) { - // glClear( GL_COLOR_BUFFER_BIT ); + //glClear( GL_COLOR_BUFFER_BIT ); - // glfwSwapBuffers(window); + //glfwSwapBuffers(window); - // glfwPollEvents(); + //glfwPollEvents(); //} - //glfwDestroyWindow(window); - - //glfwTerminate(); - - return (struct glfw_ctx){.w = NULL}; + return (struct glfw_ctx){.w = window}; } @@ -294,7 +343,7 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, const Asset_TextureSpec* textures[]) { #ifdef BENCHMARK - u32 init_start = SDL_GetTicks(); + u32 init_start = glfwGetTime(); #endif #if defined(__linux) || defined(__linux__) || defined(linux) @@ -306,8 +355,6 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, Platform* p = (Platform*)malloc(sizeof(Platform)); Window* w = (Window*)malloc(sizeof(Window)); - SDL_Window* window = NULL; - SDL_Renderer* renderer = NULL; /* initialize resources */ struct Resources* resources = @@ -319,21 +366,42 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, resources->texture_paths = NULL; resources->font_paths = NULL; resources->textures = NULL; - resources->fonts = NULL; + //resources->fonts = NULL; - /* Init subsystems */ - //{ - // struct sdl_ctx sdl_ctx = initialize_SDL(windowtitle, windowsize, flags); - // window = sdl_ctx.w; - // renderer = sdl_ctx.r; - //} - /* Init glfw haha */ { struct glfw_ctx ctx = initialize_GLFW(windowtitle, windowsize, flags); + w->window = ctx.w; } - exit(0); + struct RenderObject *testobject = malloc(sizeof(struct RenderObject)); + + glGenVertexArrays(1, &(testobject->vao)); + glBindVertexArray(testobject->vao); + + p->testobject = testobject; + + testobject->g_vertex_buffer_data[0] = -1.0f; + testobject->g_vertex_buffer_data[1] = -1.0f; + testobject->g_vertex_buffer_data[2] = 0.0f; + + testobject->g_vertex_buffer_data[3] = 1.0f; + testobject->g_vertex_buffer_data[4] = -1.0f; + testobject->g_vertex_buffer_data[5] = 0.0f; + + testobject->g_vertex_buffer_data[6] = 0.0f; + testobject->g_vertex_buffer_data[7] = -1.0f; + testobject->g_vertex_buffer_data[8] = 0.0f; + + testobject->shaderprogram = LoadShaders("shader.vertexshader", "shader.fragmentshader"); + INFO("Shaderprogram %d", testobject->shaderprogram); + + // Generate 1 buffer, put the resulting identifier in vertexbuffer + glGenBuffers(1, &(testobject->vbo)); + // The following commands will talk about our 'vertexbuffer' buffer + glBindBuffer(GL_ARRAY_BUFFER, testobject->vbo); + // Give our vertices to OpenGL. + glBufferData(GL_ARRAY_BUFFER, sizeof(testobject->g_vertex_buffer_data), testobject->g_vertex_buffer_data, GL_STATIC_DRAW); { /* Resource loading */ @@ -356,11 +424,11 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, /* Allocate memory for textures and fonts */ resources->textures = (Texture**)malloc(sizeof(Texture*) * n_textures); - resources->fonts = (TTF_Font**)malloc(sizeof(TTF_Font*) * n_fonts); + //resources->fonts = (TTF_Font**)malloc(sizeof(TTF_Font*) * n_fonts); resources->textures_size = n_textures; for (usize i = 0; i < n_textures; i++) resources->textures[i] = NULL; - for (usize i = 0; i < n_fonts; i++) resources->fonts[i] = NULL; + //for (usize i = 0; i < n_fonts; i++) resources->fonts[i] = NULL; /* Load textures */ for (usize i = 0; i < n_textures; i++) { @@ -369,27 +437,27 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, "\"...", textures[i]->path); - t = load_texture(renderer, textures[i]); - if (t == NULL) { - puts(""); - ERROR("failed to load texture\n"); - exit(EXIT_FAILURE); - } - - if (t->tilesize < 8) { - puts(""); - ERROR("texture too small!\n"); - exit(EXIT_FAILURE); - } - - if (t->texture == NULL) { - puts(""); - ERROR("failed to load texture\n"); - } else { - printf("ok\n"); - resources->textures[i] = t; - resources->textures_len++; - } +// t = load_texture(renderer, textures[i]); +// if (t == NULL) { +// puts(""); +// ERROR("failed to load texture\n"); +// exit(EXIT_FAILURE); +// } +// +// if (t->tilesize < 8) { +// puts(""); +// ERROR("texture too small!\n"); +// exit(EXIT_FAILURE); +// } +// + //if (t->texture == NULL) { + // puts(""); + // ERROR("failed to load texture\n"); + //} else { + // printf("ok\n"); + // resources->textures[i] = t; + // resources->textures_len++; + //} } /* Load fonts */ @@ -397,14 +465,14 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, INFO_("loading font \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET "\"...", fonts[i]->font_path); - TTF_Font* font = TTF_OpenFont(fonts[i]->font_path, fonts[i]->ptsize); - if (!font) { - ERROR("failed to load font: %s\n", TTF_GetError()); - } else { - printf("ok\n"); - resources->fonts[i] = font; - resources->fonts_len++; - } + //TTF_Font* font = TTF_OpenFont(fonts[i]->font_path, fonts[i]->ptsize); + //if (!font) { + // ERROR("failed to load font: %s\n", TTF_GetError()); + //} else { + // printf("ok\n"); + // resources->fonts[i] = font; + // resources->fonts_len++; + //} } if (resources->textures_len != n_textures) { @@ -425,17 +493,14 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, { /* Adjust window and such */ /* Set actual windowsize, which might be forced by OS */ - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); INFO("Adjusting window size..."); - windowsize = get_canvas_size(renderer); - - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + //windowsize = get_canvas_size(renderer); INFO("Windowsize: <%d,%d>", windowsize.x, windowsize.y); } - w->renderer = renderer; - w->window = window; + //w->renderer = renderer; + //w->window = window; w->render_scale = render_scale; w->windowsize = windowsize; w->game_w = NULL; @@ -453,7 +518,6 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, /* Getting the mouse coords now resolves the issue where a click "isn't * registered" when the mouse isn't moved before the user clicks */ - SDL_GetMouseState(&p->mouse_pos.x, &p->mouse_pos.y); p->mousedown = (v2_i32){-1, -1}; p->mouseup = (v2_i32){-1, -1}; @@ -474,7 +538,7 @@ Platform* engine_init(const char* windowtitle, v2_i32 windowsize, // TODO: Add global bindings #ifdef BENCHMARK - u32 init_stop = SDL_GetTicks(); + u32 init_stop = glfwGetTime(); INFO("Initialization took %dms", init_stop - init_start); #endif @@ -509,13 +573,13 @@ i32 engine_run(Platform* p, StateType initial_state) { StateType state = initial_state; { - u32 state_init_time = SDL_GetTicks(); + u32 state_init_time = glfwGetTime(); State_init(state, mem); INFO("Initializing state \"%s\" took %ldms", StateTypeStr[state], - SDL_GetTicks() - state_init_time); + glfwGetTime() - state_init_time); } - u32 time = SDL_GetTicks(); + u32 time = glfwGetTime(); // Update ticks u64 ticks = 0; @@ -539,14 +603,15 @@ i32 engine_run(Platform* p, StateType initial_state) { StateType (*update_func)(void*) = State_updateFunc(state); /* Main loop */ + INFO("Program: %d", p->testobject->shaderprogram); do { - const u32 now = SDL_GetTicks(); + const u32 now = glfwGetTime(); const u64 dt = now - time; time = now; /* Wait frame_interval */ if (dt < frame_interval) { #ifndef BENCHMARK - SDL_Delay(frame_interval - dt); + delay(frame_interval - dt); #else /* We want to know how much time is spend sleeping */ @@ -590,194 +655,90 @@ i32 engine_run(Platform* p, StateType initial_state) { } #endif + glfwPollEvents(); /* Events */ - BENCHEXPR(profile_input, { - if (p->mouse_lclick) { - p->mouseup.x = -1; - p->mouseup.y = -1; - p->mousedown.x = -1; - p->mousedown.y = -1; - p->mouse_lclick = false; - } - if (p->mouse_rclick) { - p->mouse_rclick = false; - } - - /* Window events */ - SDL_Event e[8]; - i32 num_events; - SDL_PumpEvents(); - while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_FIRSTEVENT, - SDL_SYSWMEVENT)) > 0) { - for (i32 i = 0; i < num_events; i++) { - switch (e[i].type) { - case SDL_QUIT: - state = STATE_quit; - break; - case SDL_WINDOWEVENT: - engine_update_window(p->window, &e[i].window); - break; - default: - WARN("Unhandled event 0x%04x", (i32)e[i].type); - } - } - } - - /* Mouse events */ - while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_MOUSEMOTION, - SDL_MOUSEWHEEL)) > 0) { - for (i32 i = 0; i < num_events; i++) { - switch (e[i].type) { - case SDL_MOUSEWHEEL: - break; - case SDL_MOUSEMOTION: { - SDL_MouseMotionEvent m = e[i].motion; - /* In case of a first-person game, use xrel and yrel */ - p->mouse_pos.x = m.x; - p->mouse_pos.y = m.y; - } break; - case SDL_MOUSEBUTTONUP: { - switch (e[i].button.button) { - case SDL_BUTTON_LEFT: - p->mouseup = p->mouse_pos; - - p->mouse_lclick = true; - case SDL_BUTTON_RIGHT: - break; - default: - break; - } - } break; - case SDL_MOUSEBUTTONDOWN: - switch (e[i].button.button) { - case SDL_BUTTON_LEFT: - p->mousedown = p->mouse_pos; - break; - case SDL_BUTTON_RIGHT: - break; - default: - break; - } - break; - default: - WARN("Unhandled mouse event 0x%04x", (i32)e[i].type); - break; - } - } - } - - BENCHEXPR(profile_input_handling, { - if (p->bindings != NULL) { - const i_ctx* bindings = *p->bindings; - const usize bindings_len = p->bindings_len; - - while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_KEYDOWN, - SDL_KEYUP)) > 0) { - for (i32 i = 0; i < num_events; i++) { - switch (e[i].type) { - case SDL_KEYDOWN: - if (e[i].key.keysym.sym == SDLK_F7) { - INFO("Reloading %s", StateTypeStr[state]); - if (!State_reload(state, p->bindings, p->bindings_len)) { - ERROR("Failed to reload state library!"); - } else { - update_func = State_updateFunc(state); - } - break; - } - for (usize b = 0; b < bindings_len; b++) { - const action_t a = - i_get_action(&bindings[b], e[i].key.timestamp, - e[i].key.keysym.scancode); - - switch (a.type) { - case InputType_action: - if (a.action.callback != NULL) { - callbacks[callbacks_len++] = a.action.callback; - } - break; - - case InputType_state: - if (!e[i].key.repeat && a.state.activate != NULL) { - callbacks[callbacks_len++] = a.state.activate; - } - break; - - case InputType_range: - WARN("Range inputs not supported yet!"); - break; - case InputType_error: - WARN("Unhandled scancode: %lu", e[i].key.keysym.scancode); - - default: - break; - } - } - break; - - case SDL_KEYUP: - for (usize b = 0; b < bindings_len; b++) { - const action_t a = - i_get_action(&bindings[b], e[i].key.timestamp, - e[i].key.keysym.scancode); - if (a.type == InputType_state && a.state.deactivate != NULL && - !e[i].key.repeat) { - callbacks[callbacks_len++] = a.state.deactivate; - } - } - break; - default: - WARN("Unhandled mouse event 0x%04x", (i32)e[i].type); - break; - } - } - } - } - }); - }); - - i_flush_bindings(callbacks_len, mem->data, callbacks); - callbacks_len = 0; - - /* update */ - StateType next_state; - BENCHEXPR(profile_gameloop, { - next_state = update_func((void*)(mem->data)); - }); // State_update(state, mem);}); - - if (next_state != STATE_null) { - if (next_state == STATE_quit) break; - - drawcall_reset(); - - engine_window_resize_pointers_reset(); - State_free(state, mem); - memory_clear(mem); - - engine_input_ctx_reset(); - - state = next_state; - update_func = State_updateFunc(state); -#ifdef BENCHMARK - { - u32 t = SDL_GetTicks(); - State_init(state, mem); - LOG("Initializing %s took %dms", StateTypeStr[state], - SDL_GetTicks() - t); - } -#else - State_init(state, mem); -#endif - } else { -#ifdef BENCHMARK - profile_num_drawcalls += drawcall_len; -#endif - render_begin(p->window); - BENCHEXPR(profile_rendering, { render_present(p->window); }) - } +// if (p->mouse_lclick) { +// p->mouseup.x = -1; +// p->mouseup.y = -1; +// p->mousedown.x = -1; +// p->mousedown.y = -1; +// p->mouse_lclick = false; +// } +// if (p->mouse_rclick) { +// p->mouse_rclick = false; +// } +// +// /* Window events */ +// i32 num_events; +// +// /* Mouse events */ +// +// if (p->bindings != NULL) { +// const i_ctx* bindings = *p->bindings; +// const usize bindings_len = p->bindings_len; +// +// } +// +// i_flush_bindings(callbacks_len, mem->data, callbacks); +// callbacks_len = 0; +// +// /* update */ +// StateType next_state; +// next_state = update_func((void*)(mem->data)); +// +// if (next_state != STATE_null) { +// if (next_state == STATE_quit) break; +// +// drawcall_reset(); +// +// engine_window_resize_pointers_reset(); +// State_free(state, mem); +// memory_clear(mem); +// +// engine_input_ctx_reset(); +// +// state = next_state; +// update_func = State_updateFunc(state); +//#ifdef BENCHMARK +// { +// f64 t = glfwGetTime(); +// State_init(state, mem); +// LOG("Initializing %s took %dms", StateTypeStr[state], +// (int)((glfwGetTime() - t) * 1000.0)); +// } +//#else +// State_init(state, mem); +//#endif +// } else { +//#ifdef BENCHMARK +// profile_num_drawcalls += drawcall_len; +//#endif +// //render_begin(p->window); + glClear(GL_COLOR_BUFFER_BIT ); + + glUseProgram(p->testobject->shaderprogram); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, p->testobject->vbo); + glVertexAttribPointer( + 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // array buffer offset + ); + glUseProgram(p->testobject->shaderprogram); + // Draw the triangle ! + glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle + glDisableVertexAttribArray(0); + glfwSwapBuffers(p->window->window); + //render_present(p->window); +// } ticks++; - } while (state != STATE_quit); + } while( + !glfwWindowShouldClose(p->window->window) + && state != STATE_quit); return 0; } @@ -791,40 +752,18 @@ void stop(Platform* p) { /* Destroy textures */ for (usize i = 0; i < r->textures_len; i++) { if (r->textures[i] != NULL) { - SDL_DestroyTexture(r->textures[i]->texture); r->textures[i] = NULL; } } free(r->textures); /* Destroy Fonts */ - for (usize i = 0; i < r->fonts_len; i++) { - if (r->fonts[i] != NULL) { - TTF_CloseFont(r->fonts[i]); - r->fonts[i] = NULL; - } - } - free(r->fonts); } } - { /* Deallocate window */ - Window* w = p->window; - if (w != NULL) { - if (w->window != NULL) { - SDL_DestroyWindow(w->window); - w->window = NULL; - } - if (w->renderer != NULL) { - SDL_DestroyRenderer(w->renderer); - w->renderer = NULL; - } - } - } + glfwDestroyWindow(p->window->window); + glfwTerminate(); - TTF_Quit(); - IMG_Quit(); - SDL_Quit(); } /* Set the maximum framerate */ @@ -885,6 +824,6 @@ void engine_input_ctx_reset(void) { } } -u32 get_time(void) { return SDL_GetTicks(); } +u32 get_time(void) { return glfwGetTime(); } v2_i32 get_windowsize(void) { return GLOBAL_PLATFORM->window->windowsize; } v2_i32* get_mousepos(void) { return &GLOBAL_PLATFORM->mouse_pos; } diff --git a/src/rendering.c b/src/rendering.c index 100a19b..5d078fa 100644 --- a/src/rendering.c +++ b/src/rendering.c @@ -1,9 +1,11 @@ #include #include -#include -#include -#include +#define GLAD_GL_IMPLEMENTATION +#include +//#define GLFW_INCLUDE_NONE +#include + #define ENGINE_INTERNALS #include @@ -17,64 +19,51 @@ extern Platform* GLOBAL_PLATFORM; RenderDrawCall drawcalls[drawcall_limit]; i32 drawcall_len = 0; +//struct RenderObject; + /* Implementations */ /* Clear the screen, * To be used inbetween draw calls */ void render_begin(Window* w) { -#ifdef _DEBUG - SDL_SetRenderDrawColor(w->renderer, 0x10, 0x0a, 0x33, 0x00); -#else - SDL_SetRenderDrawColor(w->renderer, 0x00, 0x00, 0x00, 0x00); -#endif - SDL_RenderClear(w->renderer); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT ); } void render_present(Window* w) { - for (i32 i = 0; i < drawcall_len; i++) { - RenderDrawCall dc = drawcalls[i]; - switch (dc.type) { - case RenderDrawCallType_UITree: - render_uitree(w, dc.data.data); - break; - case RenderDrawCallType_Text: - LOG("RenderDrawCallType_Text rendering not implemented!"); - break; - case RenderDrawCallType_Sprite: { -#ifdef _DEBUG - if (dc.data.sprite.sprite == NULL) { - __asm__("int3;"); - WARN("Sprite %lx in drawcall %d/%d had NULL reference", - dc.data.sprite.sprite, i, drawcall_len); - - drawcall_len = 0; - SDL_RenderPresent(w->renderer); - exit(EXIT_FAILURE); - } -#endif - Sprite s = *dc.data.sprite.sprite; - Texture* t = - ((struct Resources*)GLOBAL_PLATFORM->data)->textures[s.texture_id]; - i32 ts = t->tilesize; - SDL_Rect src = {s.coord.x, s.coord.y, ts, ts}; - SDL_Rect dst = { - dc.data.sprite.x, - dc.data.sprite.y, - ts * dc.data.sprite.scale, - ts * dc.data.sprite.scale, - }; - SDL_SetTextureColorMod(t->texture, dc.data.sprite.mod.r, - dc.data.sprite.mod.g, dc.data.sprite.mod.b); - SDL_RenderCopy(w->renderer, t->texture, &src, &dst); - } break; - default: - break; - } - } +// for (i32 i = 0; i < drawcall_len; i++) { +// RenderDrawCall dc = drawcalls[i]; +// switch (dc.type) { +// case RenderDrawCallType_UITree: +// render_uitree(w, dc.data.data); +// break; +// case RenderDrawCallType_Text: +// LOG("RenderDrawCallType_Text rendering not implemented!"); +// break; +// case RenderDrawCallType_Sprite: { +//#ifdef _DEBUG +// if (dc.data.sprite.sprite == NULL) { +// __asm__("int3;"); +// WARN("Sprite %lx in drawcall %d/%d had NULL reference", +// dc.data.sprite.sprite, i, drawcall_len); +// +// drawcall_len = 0; +// exit(EXIT_FAILURE); +// } +//#endif +// Sprite s = *dc.data.sprite.sprite; +// Texture* t = +// ((struct Resources*)GLOBAL_PLATFORM->data)->textures[s.texture_id]; +// i32 ts = t->tilesize; +// } break; +// default: +// break; +// } +// } drawcall_len = 0; - SDL_RenderPresent(w->renderer); + glfwSwapBuffers(w->window); } void drawcall_reset(void) { drawcall_len = 0; } @@ -107,7 +96,7 @@ void engine_draw_sprite(Sprite* s, v2_i32* pos, f32 scale) { .x = pos->x, .y = pos->y, .scale = scale, - .mod = {0xFF, 0xFF, 0xFF, 0xFF}, + //.mod = {0xFF, 0xFF, 0xFF, 0xFF}, }}; } @@ -124,7 +113,7 @@ void engine_draw_sprite_ex(Sprite* s, v2_i32* pos, f32 scale, .x = pos->x, .y = pos->y, .scale = scale, - .mod = {colormod.r, colormod.g, colormod.b, colormod.a}, + //.mod = {colormod.r, colormod.g, colormod.b, colormod.a}, }}; } diff --git a/src/ui_positioning.c b/src/ui_positioning.c index 07d53a3..3db73fe 100644 --- a/src/ui_positioning.c +++ b/src/ui_positioning.c @@ -1,12 +1,9 @@ -#include -#include -#include - #include #define ENGINE_INTERNALS #include #include +#include static Engine_color DEFAULT_FG = {0xFF, 0xFF, 0xFF, 0xFF}; static Engine_color DEFAULT_BG = {0x00, 0x00, 0x00, 0xFF}; @@ -870,19 +867,15 @@ void ui_container_attach(UITree* root, UITree* child) { void ui_button_enable(UITree_button* b) { b->enabled = true; - SDL_Texture* t = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[b->text_texture_index] - ->texture; - SDL_SetTextureColorMod(t, 0xff, 0xff, 0xff); + // ->textures[b->text_texture_index] + // ->texture; } void ui_button_disable(UITree_button* b) { b->enabled = false; - SDL_Texture* t = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[b->text_texture_index] - ->texture; - SDL_SetTextureColorMod(t, 0x7f, 0x7f, 0x7f); + // ->textures[b->text_texture_index] + // ->texture; } void ui_set_default_colors(Engine_color fg, Engine_color bg) { @@ -895,50 +888,49 @@ void ui_set_default_padding(i32 padding) { DEFAULT_PADDING = padding; } Engine_color ui_get_default_fg(void) { return DEFAULT_FG; } Engine_color ui_get_default_bg(void) { return DEFAULT_BG; } -bool check_point_in_rect(const v2_i32* p, const SDL_Rect* r) { - if (p->x > r->x && p->x < r->x + r->w && p->y > r->y && p->y < r->y + r->h) - return true; +bool check_point_in_rect(const v2_i32* p, const /* */ int r) { + //if (p->x > r->x && p->x < r->x + r->w && p->y > r->y && p->y < r->y + r->h) + // return true; return false; } u64 ui_check_click_internal(UITree* root, v2_i32 pos) { v2_i32 ps = get_pos(root); v2_i32 sz = get_size(root); - SDL_Rect elem_rect = {.x = ps.x, .y = ps.y, .w = sz.x, .h = sz.y}; /* */ - switch (root->type) { - case uitype_container: - if (root->container.children != NULL && root->container.children_len > 0) { - const UITree_container* container = &root->container; - - if (check_point_in_rect(&pos, &elem_rect)) { - - for (usize i = 0; i < container->children_len; i++) { - u64 res = ui_check_click_internal(container->children[i], pos); - if (res != (u64)ELEM_NOT_FOUND) { - return res; - } - } - } - } - break; - case uitype_button: - if (root->button.enabled) { - WARN("Checking button"); - elem_rect.h += root->button.padding * 2; - elem_rect.w += root->button.padding * 2; - WARN("Button specs: <%d,%d>+%d,%d", elem_rect.w, elem_rect.h, - elem_rect.x, elem_rect.y); - if (check_point_in_rect(&pos, &elem_rect)) { - return root->button.id; - } - } - break; - case uitype_title: - case uitype_text: - default: - break; - } + //switch (root->type) { + //case uitype_container: + // if (root->container.children != NULL && root->container.children_len > 0) { + // const UITree_container* container = &root->container; + + // if (check_point_in_rect(&pos, &elem_rect)) { + + // for (usize i = 0; i < container->children_len; i++) { + // u64 res = ui_check_click_internal(container->children[i], pos); + // if (res != (u64)ELEM_NOT_FOUND) { + // return res; + // } + // } + // } + // } + // break; + //case uitype_button: + // if (root->button.enabled) { + // WARN("Checking button"); + // elem_rect.h += root->button.padding * 2; + // elem_rect.w += root->button.padding * 2; + // WARN("Button specs: <%d,%d>+%d,%d", elem_rect.w, elem_rect.h, + // elem_rect.x, elem_rect.y); + // if (check_point_in_rect(&pos, &elem_rect)) { + // return root->button.id; + // } + // } + // break; + //case uitype_title: + //case uitype_text: + //default: + // break; + //} return ELEM_NOT_FOUND; } diff --git a/src/ui_rendering.c b/src/ui_rendering.c index 8055db8..1516736 100644 --- a/src/ui_rendering.c +++ b/src/ui_rendering.c @@ -2,10 +2,6 @@ #include #include -#include -#include -#include - #define ENGINE_INTERNALS #include @@ -40,24 +36,6 @@ void render_uitree(Window* w, UITree* t) { } void render_container(Window* w, UITree_container* t) { - SDL_Rect r = {.x = t->x, .y = t->y, .w = t->w, .h = t->h}; - - SDL_SetRenderDrawColor(w->renderer, t->bg.r, t->bg.g, t->bg.b, t->bg.a); - - SDL_RenderFillRect(w->renderer, &r); - - SDL_SetRenderDrawColor(w->renderer, t->fg.r, t->fg.g, t->fg.b, t->fg.a); - - SDL_RenderDrawRect(w->renderer, &r); - -#ifdef _DEBUG - r.x += t->padding; - r.y += t->padding; - r.w -= t->padding * 2; - r.h -= t->padding * 2; - SDL_SetRenderDrawColor(w->renderer, 0xFF, 0xFF, 0xFF, 0x7A); - SDL_RenderDrawRect(w->renderer, &r); -#endif if (t->children != NULL && t->children_len > 0) { for (usize i = 0; i < t->children_len; i++) { @@ -67,180 +45,19 @@ void render_container(Window* w, UITree_container* t) { } void render_button(Window* w, UITree_button* t) { - - SDL_Rect inner_r = { - .x = t->x + t->padding + ((t->w - t->texture_size.x) / 2), - .y = t->y + t->padding + ((t->h - t->texture_size.y) / 2), - .w = t->texture_size.x, - .h = t->texture_size.y, - }; - - SDL_Rect outer_r = { - .x = t->x, - .y = t->y, - .w = t->w + t->padding * 2, - .h = t->h + t->padding * 2, - }; - - SDL_Color fg = { - t->fg.r, - t->fg.g, - t->fg.b, - t->fg.a, - }; - - if (t->enabled == false) { - fg.r /= 2; - fg.g /= 2; - fg.b /= 2; - } - - SDL_SetRenderDrawColor(w->renderer, t->bg.r, t->bg.g, t->bg.b, t->bg.a); - - SDL_RenderFillRect(w->renderer, &outer_r); - - SDL_SetRenderDrawColor(w->renderer, fg.r, fg.g, fg.b, fg.a); - - SDL_RenderDrawRect(w->renderer, &outer_r); - SDL_Texture* texture = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[t->text_texture_index] - ->texture; - SDL_RenderCopy(w->renderer, texture, NULL, &inner_r); } void render_title(Window* w, UITree_title* t) { - SDL_Rect r = { - .x = t->x, - .y = t->y, - .w = t->texture_size.x, - .h = t->texture_size.y, - }; - - SDL_SetRenderDrawColor(w->renderer, t->fg.r, t->fg.g, t->fg.b, t->fg.a); - - SDL_Texture* texture = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[t->text_texture_index] - ->texture; - - SDL_RenderCopy(w->renderer, texture, NULL, &r); - -#ifdef _DEBUG - SDL_SetRenderDrawColor(w->renderer, 0xFF, 0xFF, 0xFF, 0x7A); - - SDL_RenderDrawRect(w->renderer, &r); -#endif } void render_text(Window* w, UITree_text* t) { - SDL_Rect r = { - .x = t->x, - .y = t->y, - .w = t->texture_size.x, - .h = t->texture_size.y, - }; - - SDL_SetRenderDrawColor(w->renderer, t->fg.r, t->fg.g, t->fg.b, t->fg.a); - - SDL_Texture* texture = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[t->text_texture_index] - ->texture; - - SDL_RenderCopy(w->renderer, texture, NULL, &r); - -#ifdef _DEBUG - SDL_SetRenderDrawColor(w->renderer, 0xFF, 0xFF, 0xFF, 0x7A); - - SDL_RenderDrawRect(w->renderer, &r); -#endif } i64 add_texture(struct Resources* resptr, Texture* t) { - if (NULL == resptr || NULL == t) return -1; - - if (resptr->textures == NULL) { - resptr->textures = malloc(sizeof(Texture*) * TEXTURES_INCREMENT); - } else if (resptr->textures_len + 1 >= resptr->textures_size) { - resptr->textures_size += TEXTURES_INCREMENT; - resptr->textures = - realloc(resptr->textures, sizeof(Texture*) * resptr->textures_size); - memset(resptr->textures + resptr->textures_size - TEXTURES_INCREMENT, 0, - TEXTURES_INCREMENT); - } - - resptr->textures[resptr->textures_len] = t; - return resptr->textures_len++; + return 0; } i64 engine_render_text(i32 font_id, Engine_color fg, char* text, v2_i32* size_out, bool wrapped) { - const SDL_Color sdl_fg = {.r = fg.r, .g = fg.g, .b = fg.b, .a = fg.a}; - Texture* t = malloc(sizeof(Texture)); - struct Resources* r; - - if (t == NULL) { - ERROR("Failed to allocate memory for texture!\n"); - exit(EXIT_FAILURE); - } - - if (GLOBAL_PLATFORM == NULL) { - ERROR("Platform is uninitialized.\n"); - exit(EXIT_FAILURE); - } - - r = (struct Resources*)GLOBAL_PLATFORM->data; - - if (r == NULL) { - ERROR("Resources not loaded!\n"); - exit(EXIT_FAILURE); - } - - if (r->fonts == NULL) { - ERROR("No fonts are initialized!\n"); - exit(EXIT_FAILURE); - } - - if ((usize)font_id >= r->fonts_len) { - ERROR("font-id \"%d\" is out of bounds!\n", font_id); - ERROR("Couldn't render text \"%s\"\n", text); - } - - SDL_Surface* s = NULL; - - if (wrapped) { - s = TTF_RenderUTF8_Solid_Wrapped(r->fonts[font_id], text, sdl_fg, - size_out->x); - - if (s == NULL) { - ERROR("Failed call to TTF_RenderUTF8_Solid_Wrapped: %s\n", - TTF_GetError()); - exit(EXIT_FAILURE); - } - } else { - s = TTF_RenderUTF8_Solid(r->fonts[font_id], text, sdl_fg); - - if (s == NULL) { - ERROR("Failed call to TTF_RenderUTF8_Solid: %s\n", TTF_GetError()); - exit(EXIT_FAILURE); - } - } - - t->texture = - SDL_CreateTextureFromSurface(GLOBAL_PLATFORM->window->renderer, s); - - if (t->texture == NULL) { - ERROR("Failed call to SDL_CreateTextureFromSurface: %s\n", SDL_GetError()); - INFO("FontID: %d", font_id); - INFO("Text: \"%s\" [%lu]", text, strlen(text)); - exit(EXIT_FAILURE); - } - - *(i32*)&t->width = s->w; - *(i32*)&t->height = s->h; - - size_out->x = s->w; - size_out->y = s->h; - - SDL_FreeSurface(s); - - return add_texture(r, t); + return 0; } -- cgit v1.3