#include /* TODO: REMOVE THIS INCLUSION */ #include #include #include #define ENGINE_RENDERING_WINDOW_H_EXCLUDE_EXTERNS #include #undef ENGINE_RENDERING_WINDOW_H_EXCLUDE_EXTERNS #undef GLFW_INCLUDE_NONE #include #include extern Instance* GLOBAL_PLATFORM; static inline u64 platform_get_time_usec(void) { struct timespec t; int res = clock_gettime(CLOCK_MONOTONIC, &t); if (res != 0) { // TODO: Check errno WARN("Failed to get system time"); } return (u64)(t.tv_sec * 1000000 + t.tv_nsec / 1000); } /* wrapper to get time in ms */ u64 (*get_time)(void) = platform_get_time_usec; #define DAW_WINDOW_VSYNC (1 << 0) #define DAW_WINDOW_FULLSCREEN (1 << 1) #define DAW_WINDOW_RESIZEABLE (1 << 2) // Wrapper to get a specific window and set up related structures. // What the fuck is this doing here. Window* Window_new(const struct Platform* p, const char *restrict title, Window_framework framework, Window_renderer renderer, ivec2 size, u32 flags) { Window* w = NULL; switch (framework) { case WINDOW_FRAMEWORK_GLFW: switch (renderer) { case WINDOW_RENDERER_OPENGL: /* For now, pass instance as NULL, fix it once all the necessary bs is * out of struct Instance */ w = p->window_init(title, size, flags); // Manually reset bindings et. al. w->bindings = NULL; w->bindings_sz = 0; w->bindings_len = 0; w->render_targets = NULL; return w; default: ERROR("Unsupported renderer."); } break; default: ERROR("Unsupported framework."); } return NULL; } void window_reset_cameras(Window* w, RenderTargets* restrict targets) { // Question, would it be better to check both callbacks and continue early, // instead of resizing the texture first, then check the camera callback? for (usize i = 0; i < targets->framebuffer_len; i++) { //if (targets->framebuffer_size_callback[i] == NULL) continue; //ivec2 newsz; //targets->framebuffer_size_callback[i](&newsz, w->windowsize); // Destroy & Create framebuffers (and related buffers?) if (targets->camera_reset_callback[i] == NULL) continue; (*targets->camera_reset_callback)(&targets->cam[i], w->windowsize); } } //void window_reset_texture_sizes(Window* w, RenderTargets* restrict targets) { // // Question, would it be more efficient to just wipe all of them at once // // instead of doing this? Not all are necessarily deleted. // for (usize i = 0; i < targets->texture_len; i++) { // if (targets->framebuffer_size_callback[i] == NULL) continue; // // ivec2 newsz; // targets->framebuffer_size_callback[i](&newsz, w->windowsize); // // r_destroy_framebuffers(w->context, targets->framebuffer, 1); // r_create_framebuffers(w->context, &targets->framebuffer[i], &targets->framebuffer_parameters[i].framebuffer_type, &newsz, 1); // } //} void get_mousepos(double *x, double *y) { Window* w = GLOBAL_PLATFORM->window; switch(w->framework) { case WINDOW_FRAMEWORK_GLFW: glfwGetCursorPos(GLOBAL_PLATFORM->window->window, x, y); break; default: ERROR("get_mouse_pos not implemented for chosen framework."); } } void window_get_size(ivec2* dst) { glm_ivec2_copy(GLOBAL_PLATFORM->window->windowsize, *dst); } // Assume framebuffer_len and texture_len is already set void window_init_renderstack(Window *restrict w, usize num_fbuf, usize num_buf, FramebufferParameters *restrict fb_params, u32 *restrict buffer_params ) { ASSERT(w != NULL); ASSERT(fb_params != NULL); ASSERT(buffer_params != NULL); RenderTargets *t = NULL; void* allocation = malloc( sizeof(RenderTargets) + sizeof(*t->framebuffer) * num_fbuf + sizeof(*t->buffer) * num_buf + sizeof(*t->framebuffer_parameters) * num_fbuf + sizeof(*t->buffer_parameters) * num_buf + sizeof(*t->cam) * num_fbuf // TODO: callbacks ); #define ADVANCE_PTR(target, count)\ t->target = (void*)((u64)allocation + acc); \ acc += sizeof(*t->target) * count t = allocation; t->framebuffer_len = num_fbuf; t->buffer_len = num_buf; u64 acc = sizeof(RenderTargets); ADVANCE_PTR(framebuffer, num_fbuf); ADVANCE_PTR(buffer, num_buf); ADVANCE_PTR(framebuffer_parameters, num_fbuf); ADVANCE_PTR(buffer_parameters, num_buf); ADVANCE_PTR(cam, num_fbuf); // TODO: callbacks #undef ADVANCE_PTR memcpy(t->framebuffer_parameters, fb_params, sizeof(*t->framebuffer_parameters) * num_fbuf); memcpy(t->buffer_parameters, buffer_params, sizeof(*t->buffer_parameters) * num_buf); // Iteratively set up each framebuffer and framebuffer-attached objects usize buffer_offset = 0; for (usize fb_idx = 0; fb_idx < num_fbuf; fb_idx++) { FramebufferParameters *p = &t->framebuffer_parameters[fb_idx]; // Check everything is a texture, cuz rn. we don't support anything else for (isize buffer_idx = 0; buffer_idx < p->num_attached_buffers; buffer_idx++) { ASSERT(BUFFERPARAMETER_GET_TYPE(t->buffer_parameters[buffer_idx + buffer_offset]) == BufferType_texture); } r_create_textures(w->context, &t->buffer[buffer_offset], &t->buffer_parameters[buffer_offset], &t->framebuffer_parameters[fb_idx].dimensions, t->framebuffer_parameters[fb_idx].num_attached_buffers); //if (BUFFERPARAMETER_GET_TYPE(buffer_params[i]) != BufferType_texture) continue; //u32 texture_type = BUFFERPARAMETER_GET_PARAMETER(buffer_params[i]); //usize span = 0; //while ( // (i + span < targets->buffer_len) && // (BUFFERPARAMETER_GET_TYPE(buffer_params[i + span]) == BufferType_texture) && // (buffer_params[i + span].buffer_param & 3) == textureType //) { // span++; //} //if (span == 0) continue; //r_create_textures(w->context, &targets->buffer[i], texture_type, texturesizes, span); } //r_create_renderbuffers(c, targets->renderbuffer, renderbuffertypes, renderbuffersizes, targets->renderbuffer_len); // Skip `texture` (??) w->render_targets = t; } void window_free_renderstack(RenderTargets *restrict t) { // Everything is in the same buffer anyways free(t->framebuffer); }