From a4ae1cf214fc241ee4cd8e15e5edd87cda973dd9 Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Tue, 25 Jul 2023 15:55:09 +0200 Subject: [PATCH] [win32, surface] Fix auto-selecting surface when first creating one ; checking why smooth resize still doesn't work even though we receive events and draw in a separate thread --- examples/smooth_resize/build.bat | 4 + examples/smooth_resize/main.c | 256 +++++++++++++------------------ src/gl_canvas.c | 4 - src/graphics_surface.c | 2 + 4 files changed, 110 insertions(+), 156 deletions(-) create mode 100644 examples/smooth_resize/build.bat diff --git a/examples/smooth_resize/build.bat b/examples/smooth_resize/build.bat new file mode 100644 index 0000000..4f2c691 --- /dev/null +++ b/examples/smooth_resize/build.bat @@ -0,0 +1,4 @@ + +set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers /I ..\..\..\..\vcpkg\packages\pthreads_x64-windows\include + +cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /LIBPATH:..\..\..\..\vcpkg\packages\pthreads_x64-windows\lib pthreadVC3.lib /out:../../bin/example_smooth_resize.exe diff --git a/examples/smooth_resize/main.c b/examples/smooth_resize/main.c index 645828d..276c0e4 100644 --- a/examples/smooth_resize/main.c +++ b/examples/smooth_resize/main.c @@ -6,6 +6,7 @@ * @revision: * *****************************************************************/ +#include #include #include #include @@ -13,45 +14,55 @@ #define _USE_MATH_DEFINES //NOTE: necessary for MSVC #include +#define MG_INCLUDE_GL_API #include"milepost.h" #include -#define LOG_SUBSYSTEM "Main" +unsigned int program; +const char* vshaderSource = + "#version 430\n" + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; -mg_font create_font() +const char* fshaderSource = + "#version 430\n" + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; + +void compile_shader(GLuint shader, const char* source) { - //NOTE(martin): create font - str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); - char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); - FILE* fontFile = fopen(fontPathCString, "r"); - if(!fontFile) + int err = glGetError(); + if(err) { - log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); - return(mg_font_nil()); + printf("gl error: %i\n", err); } - unsigned char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = (unsigned char*)malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); - unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, - UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - UNICODE_RANGE_LATIN_EXTENDED_A, - UNICODE_RANGE_LATIN_EXTENDED_B, - UNICODE_RANGE_SPECIALS}; - - mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); - free(fontData); - - return(font); + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("shader error: %.*s\n", size, buffer); + } } +GLfloat vertices[] = { + -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + typedef struct app_data { mp_window window; @@ -59,13 +70,7 @@ typedef struct app_data mg_canvas canvas; mg_font font; - f32 x; - f32 y; - f32 dx; - f32 dy; - f32 speed; - f32 frameTime; - + GLuint vertexBuffer; } app_data; void process_event(app_data* app, mp_event event) @@ -79,33 +84,7 @@ void process_event(app_data* app, mp_event event) case MP_EVENT_WINDOW_RESIZE: { - mp_rect frame = {0, 0, event.frame.rect.w, event.frame.rect.h}; - mg_surface_set_frame(app->surface, frame); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - if(event.key.action == MP_KEY_PRESS || event.key.action == MP_KEY_REPEAT) - { - f32 factor = (event.key.mods & MP_KEYMOD_SHIFT) ? 10 : 1; - - if(event.key.code == MP_KEY_LEFT) - { - app->x-=0.3*factor; - } - else if(event.key.code == MP_KEY_RIGHT) - { - app->x+=0.3*factor; - } - else if(event.key.code == MP_KEY_UP) - { - app->y-=0.3*factor; - } - else if(event.key.code == MP_KEY_DOWN) - { - app->y+=0.3*factor; - } - } + log_info("resizing window!\n"); } break; default: @@ -115,95 +94,89 @@ void process_event(app_data* app, mp_event event) void update_and_render(app_data* app) { - mp_rect contentRect = mp_window_get_content_rect(app->window); - - if(app->x-200 < 0) - { - app->x = 200; - app->dx = app->speed; - } - if(app->x+200 > contentRect.w) - { - app->x = contentRect.w - 200; - app->dx = -app->speed; - } - if(app->y-200 < 0) - { - app->y = 200; - app->dy = app->speed; - } - if(app->y+200 > contentRect.h) - { - app->y = contentRect.h - 200; - app->dy = -app->speed; - } - app->x += app->dx; - app->y += app->dy; - - f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); - mg_surface_prepare(app->surface); - // background - mg_set_color_rgba(0, 1, 1, 1); - mg_clear(); + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); - // head - mg_set_color_rgba(1, 1, 0, 1); + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800/(f32)600; - mg_circle_fill(app->x, app->y, 200); + GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, + -sinf(alpha)/aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; - // smile - f32 frown = app->frameTime > 0.033 ? -100 : 0; + alpha += 2*M_PI/120; - mg_set_color_rgba(0, 0, 0, 1); - mg_set_width(20); - mg_move_to(app->x-100, app->y+100); - mg_cubic_to(app->x-50, app->y+150+frown, app->x+50, app->y+150+frown, app->x+100, app->y+100); - mg_stroke(); + glUniformMatrix4fv(0, 1, false, matrix); - // eyes - mg_ellipse_fill(app->x-70, app->y-50, 30, 50); - mg_ellipse_fill(app->x+70, app->y-50, 30, 50); - // text - mg_set_color_rgba(0, 0, 1, 1); - mg_set_font(app->font); - mg_set_font_size(12); - mg_move_to(50, 600-50); + glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); - str8 text = str8_pushf(mem_scratch(), - "Milepost vector graphics test program (frame time = %fs, fps = %f)...", - app->frameTime, - 1./app->frameTime); - mg_text_outlines(text); - mg_fill(); + glDrawArrays(GL_TRIANGLES, 0, 3); - printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", - app->frameTime, - 1./app->frameTime); - - mg_flush(); mg_surface_present(app->surface); mem_arena_clear(mem_scratch()); - app->frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; } void* render(void* user) { app_data* app = (app_data*)user; - mg_canvas_prepare(app->canvas); + //NOTE: init shader and gl state + mg_surface_prepare(app->surface); + + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + glGenBuffers(1, &app->vertexBuffer); + + GLfloat vertices[] = { + -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + + glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + + unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); + unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); + program = glCreateProgram(); + + compile_shader(vshader, vshaderSource); + compile_shader(fshader, fshaderSource); + + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); + + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + printf("link error: %.*s\n", size, buffer); + } + + glUseProgram(program); while(!mp_should_quit()) { - mp_event event = {0}; - while(mp_next_event(&event)) + mp_event* event = 0; + + while((event = mp_next_event(mem_scratch())) != 0) { - process_event(app, event); + process_event(app, *event); } update_and_render(app); + mem_arena_clear(mem_scratch()); } return(0); @@ -211,8 +184,6 @@ void* render(void* user) int main() { - LogLevel(LOG_LEVEL_WARNING); - mp_init(); mp_clock_init(); //TODO put that in mp_init()? @@ -220,19 +191,16 @@ int main() mp_window window = mp_window_create(windowRect, "test", 0); //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_DEFAULT); - mg_surface_swap_interval(surface, 0); - - //TODO: create canvas - mg_canvas canvas = mg_canvas_create(surface); - - if(mg_canvas_is_nil(canvas)) + mg_surface surface = mg_surface_create_for_window(window, MG_GL); + if(mg_surface_is_nil(surface)) { - printf("Error: couldn't create canvas\n"); + printf("Error: couldn't create surface\n"); return(-1); } - mg_font font = create_font(); + mg_surface_swap_interval(surface, 1); + mg_surface_deselect(); + // start app mp_window_bring_to_front(window); @@ -240,13 +208,7 @@ int main() //TODO: start thread app_data app = {.window = window, - .surface = surface, - .canvas = canvas, - .font = font, - .x = 400, - .y = 300, - .dx = 0, - .dy = 0}; + .surface = surface}; pthread_t renderThread; pthread_create(&renderThread, 0, render, &app); @@ -254,21 +216,11 @@ int main() while(!mp_should_quit()) { mp_pump_events(0); - /* - mp_event event = {0}; - while(mp_next_event(&event)) - { - process_event(&app, event); - } - update_and_render(&app); - //*/ } void* res; pthread_join(renderThread, &res); - mg_font_destroy(font); - mg_canvas_destroy(canvas); mg_surface_destroy(surface); mp_window_destroy(window); diff --git a/src/gl_canvas.c b/src/gl_canvas.c index bff7ea7..30c6b35 100644 --- a/src/gl_canvas.c +++ b/src/gl_canvas.c @@ -1258,10 +1258,6 @@ void mg_gl_canvas_render(mg_canvas_backend* interface, mg_gl_canvas_resize(backend, viewportSize); } - ///////////////////////////////////////////////////////////////////////////////////////////////////// - //TODO: the surface's frame and the underlying window/view rect are not necessarily the same. - // we should set the viewport to cover the whole surface's frame, so it might not start at (0, 0) - ///////////////////////////////////////////////////////////////////////////////////////////////////// glViewport(0, 0, viewportSize.x, viewportSize.y); //NOTE: clear screen and reset input buffer offsets diff --git a/src/graphics_surface.c b/src/graphics_surface.c index 9acc7a9..e3d3023 100644 --- a/src/graphics_surface.c +++ b/src/graphics_surface.c @@ -147,6 +147,7 @@ mg_surface mg_surface_create_for_window(mp_window window, mg_surface_api api) if(surface) { surfaceHandle = mg_surface_handle_alloc(surface); + mg_surface_prepare(surfaceHandle); } return(surfaceHandle); } @@ -174,6 +175,7 @@ mg_surface mg_surface_create_remote(u32 width, u32 height, mg_surface_api api) if(surface) { surfaceHandle = mg_surface_handle_alloc(surface); + mg_surface_prepare(surfaceHandle); } return(surfaceHandle); }