diff --git a/build.bat b/build.bat index 6dd6a8f..ecaf302 100644 --- a/build.bat +++ b/build.bat @@ -1,6 +1,6 @@ - -if not exist bin mkdir bin - -set INCLUDES=/I src /I src/util /I src/platform /I ext -cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c -lib bin/milepost.obj /OUT:bin/milepost.lib + +if not exist bin mkdir bin + +set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers +cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c +lib bin/milepost.obj /OUT:bin/milepost.lib diff --git a/examples/triangleGL/main.c b/examples/triangleGL/main.c index 07fca9c..7139f1b 100644 --- a/examples/triangleGL/main.c +++ b/examples/triangleGL/main.c @@ -1,227 +1,228 @@ -/************************************************************//** -* -* @file: main.cpp -* @author: Martin Fouilleul -* @date: 30/07/2022 -* @revision: -* -*****************************************************************/ -#include -#include - -#define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include - -#include"milepost.h" - -#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"; - -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) -{ - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - - int err = glGetError(); - if(err) - { - printf("gl error: %i\n", err); - } - - 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); - } -} - -int main() -{ - LogLevel(LOG_LEVEL_DEBUG); - - mp_init(); - - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); - - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_GL); - - //NOTE: init shader and gl state - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - GLuint vertexBuffer; - glGenBuffers(1, &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, 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); - - mp_window_bring_to_front(window); -// mp_window_focus(window); - - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event event = {0}; - while(mp_next_event(&event)) - { - switch(event.type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - case MP_EVENT_WINDOW_RESIZE: - { - printf("resized, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_WINDOW_MOVE: - { - printf("moved, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_MOUSE_MOVE: - { - printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", - event.move.x, - event.move.y, - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - printf("mouse wheel, delta = {%f, %f}\n", - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_ENTER: - { - printf("mouse enter\n"); - } break; - - case MP_EVENT_MOUSE_LEAVE: - { - printf("mouse leave\n"); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - printf("mouse button %i: %i\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? 1 : 0); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - printf("key %i: %s\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat")); - } break; - - case MP_EVENT_KEYBOARD_CHAR: - { - printf("entered char %s\n", event.character.sequence); - } break; - - default: - break; - } - } - - mg_surface_prepare(surface); - - glClearColor(0.3, 0.3, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - - static float alpha = 0; - //f32 aspect = frameSize.x/frameSize.y; - f32 aspect = 800/(f32)600; - - glViewport(0, 0, 800, 600); - - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, - -sinf(alpha)/aspect, cosf(alpha), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; - - alpha += 2*M_PI/120; - - glUniformMatrix4fv(0, 1, false, matrix); - - - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); - - glDrawArrays(GL_TRIANGLES, 0, 3); - - mg_surface_present(surface); - } - - mp_terminate(); - - return(0); -} +/************************************************************//** +* +* @file: main.cpp +* @author: Martin Fouilleul +* @date: 30/07/2022 +* @revision: +* +*****************************************************************/ +#include +#include + +#define _USE_MATH_DEFINES //NOTE: necessary for MSVC +#include + +#include"milepost.h" +#include"win32_gl_surface.h" + +#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"; + +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) +{ + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); + + int err = glGetError(); + if(err) + { + printf("gl error: %i\n", err); + } + + 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); + } +} + +int main() +{ + LogLevel(LOG_LEVEL_DEBUG); + + mp_init(); + + mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; + mp_window window = mp_window_create(rect, "test", 0); + + //NOTE: create surface + mg_surface surface = mg_gl_surface_create_for_window(window); + + //NOTE: init shader and gl state + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + GLuint vertexBuffer; + glGenBuffers(1, &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, 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); + + mp_window_bring_to_front(window); +// mp_window_focus(window); + + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event event = {0}; + while(mp_next_event(&event)) + { + switch(event.type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } break; + + case MP_EVENT_WINDOW_RESIZE: + { + printf("resized, rect = {%f, %f, %f, %f}\n", + event.frame.rect.x, + event.frame.rect.y, + event.frame.rect.w, + event.frame.rect.h); + } break; + + case MP_EVENT_WINDOW_MOVE: + { + printf("moved, rect = {%f, %f, %f, %f}\n", + event.frame.rect.x, + event.frame.rect.y, + event.frame.rect.w, + event.frame.rect.h); + } break; + + case MP_EVENT_MOUSE_MOVE: + { + printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", + event.move.x, + event.move.y, + event.move.deltaX, + event.move.deltaY); + } break; + + case MP_EVENT_MOUSE_WHEEL: + { + printf("mouse wheel, delta = {%f, %f}\n", + event.move.deltaX, + event.move.deltaY); + } break; + + case MP_EVENT_MOUSE_ENTER: + { + printf("mouse enter\n"); + } break; + + case MP_EVENT_MOUSE_LEAVE: + { + printf("mouse leave\n"); + } break; + + case MP_EVENT_MOUSE_BUTTON: + { + printf("mouse button %i: %i\n", + event.key.code, + event.key.action == MP_KEY_PRESS ? 1 : 0); + } break; + + case MP_EVENT_KEYBOARD_KEY: + { + printf("key %i: %s\n", + event.key.code, + event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat")); + } break; + + case MP_EVENT_KEYBOARD_CHAR: + { + printf("entered char %s\n", event.character.sequence); + } break; + + default: + break; + } + } + + mg_surface_prepare(surface); + + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800/(f32)600; + + glViewport(0, 0, 800, 600); + + GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, + -sinf(alpha)/aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + + alpha += 2*M_PI/120; + + glUniformMatrix4fv(0, 1, false, matrix); + + + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + mg_surface_present(surface); + } + + mp_terminate(); + + return(0); +} diff --git a/examples/triangleGLES/build.bat b/examples/triangleGLES/build.bat index 3e918f6..704d78c 100644 --- a/examples/triangleGLES/build.bat +++ b/examples/triangleGLES/build.bat @@ -1,2 +1,2 @@ -set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext -cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib /out:test.exe +set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers +cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:./ libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib /out:test.exe diff --git a/ext/angle_install_notes.txt b/ext/angle_install_notes.txt new file mode 100644 index 0000000..8b52fc5 --- /dev/null +++ b/ext/angle_install_notes.txt @@ -0,0 +1,31 @@ +angle install on windows + +* need Python3 (can install through win app store) +* need Windows SDK +* clone depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git +or download and unzip bundle at https://storage.googleapis.com/chrome-infra/depot_tools.zip +* set depot_tools in path env variable through control panel>System and security>system>advanced system settings +* run gclient in a cmd shell + +* set DEPOT_TOOLS_WIN_TOOLCHAIN=0 +* mkdir angle +* cd angle +* fetch angle +* wait a million years + +* fails when running python3 third_party/depot_tools/download_from_google_storage.py ... + -> open DEPS and change third_party/depot_tools with ../depot/tools + +* run gclient sync to complete previous step + +* gn gen out/Debug +* gn args out/Debug and edit arguments: + angle_enable_vulkan = false + angle_build_tests = false + is_component_build = false + +* autoninja -C out/Debug +* wait a while + +* link with libEGL.dll.lib and libGLESv2.dll.lib +* put libEGL.dll and libGLESv2.dll in same directory as executable \ No newline at end of file diff --git a/ext/libEGL.dylib b/ext/libEGL.dylib deleted file mode 100755 index 8d5e3b4..0000000 Binary files a/ext/libEGL.dylib and /dev/null differ diff --git a/ext/libGLESv2.dylib b/ext/libGLESv2.dylib deleted file mode 100755 index 856ef5c..0000000 Binary files a/ext/libGLESv2.dylib and /dev/null differ diff --git a/src/milepost.c b/src/milepost.c index e5b5e15..c6de6bb 100644 --- a/src/milepost.c +++ b/src/milepost.c @@ -1,66 +1,67 @@ -/************************************************************//** -* -* @file: milepost.c -* @author: Martin Fouilleul -* @date: 13/02/2021 -* @revision: -* -*****************************************************************/ - -//--------------------------------------------------------------- -// utilities implementations -//--------------------------------------------------------------- -#include"util/debug_log.c" -#include"util/memory.c" -#include"util/strings.c" -#include"util/utf8.c" -#include"util/hash.c" -#include"util/ringbuffer.c" - -//--------------------------------------------------------------- -// platform implementations -//--------------------------------------------------------------- -#include"platform.h" - -#if defined(OS_WIN64) - #include"platform/win32_base_allocator.c" - //TODO -#elif defined(OS_MACOS) - #include"platform/unix_base_allocator.c" - #include"platform/osx_clock.c" - /* - #include"platform/unix_rng.c" - #include"platform/posix_thread.c" - #include"platform/posix_socket.c" - */ - -#elif defined(OS_LINUX) - #include"platform/unix_base_allocator.c" - #include"platform/linux_clock.c" - /* - #include"platform/unix_rng.c" - #include"platform/posix_thread.c" - #include"platform/posix_socket.c" - */ -#else - #error "Unsupported platform" -#endif - -//--------------------------------------------------------------- -// application layer -//--------------------------------------------------------------- - -#if defined(OS_WIN64) - #include"win32_app.c" - #include"win32_gl_surface.c" -#elif defined(OS_MACOS) - //NOTE: macos application layer is defined in milepost.m -#else - #error "Unsupported platform" -#endif - -//--------------------------------------------------------------- -// graphics/ui layer -//--------------------------------------------------------------- -#include"graphics.c" -//#include"ui.c" +/************************************************************//** +* +* @file: milepost.c +* @author: Martin Fouilleul +* @date: 13/02/2021 +* @revision: +* +*****************************************************************/ + +//--------------------------------------------------------------- +// utilities implementations +//--------------------------------------------------------------- +#include"util/debug_log.c" +#include"util/memory.c" +#include"util/strings.c" +#include"util/utf8.c" +#include"util/hash.c" +#include"util/ringbuffer.c" + +//--------------------------------------------------------------- +// platform implementations +//--------------------------------------------------------------- +#include"platform.h" + +#if defined(OS_WIN64) + #include"platform/win32_base_allocator.c" + //TODO +#elif defined(OS_MACOS) + #include"platform/unix_base_allocator.c" + #include"platform/osx_clock.c" + /* + #include"platform/unix_rng.c" + #include"platform/posix_thread.c" + #include"platform/posix_socket.c" + */ + +#elif defined(OS_LINUX) + #include"platform/unix_base_allocator.c" + #include"platform/linux_clock.c" + /* + #include"platform/unix_rng.c" + #include"platform/posix_thread.c" + #include"platform/posix_socket.c" + */ +#else + #error "Unsupported platform" +#endif + +//--------------------------------------------------------------- +// application layer +//--------------------------------------------------------------- + +#if defined(OS_WIN64) + #include"win32_app.c" +// #include"win32_gl_surface.c" + #include"win32_gles_surface.c" +#elif defined(OS_MACOS) + //NOTE: macos application layer is defined in milepost.m +#else + #error "Unsupported platform" +#endif + +//--------------------------------------------------------------- +// graphics/ui layer +//--------------------------------------------------------------- +#include"graphics.c" +//#include"ui.c" diff --git a/src/milepost.h b/src/milepost.h index 08433be..7243848 100644 --- a/src/milepost.h +++ b/src/milepost.h @@ -1,51 +1,51 @@ -/************************************************************//** -* -* @file: milepost.h -* @author: Martin Fouilleul -* @date: 13/02/2021 -* @revision: -* -*****************************************************************/ -#ifndef __MILEPOST_H_ -#define __MILEPOST_H_ - -//---------------------------------------------------------------- -// utility layer -//---------------------------------------------------------------- -#include"platform.h" -#include"typedefs.h" -#include"macro_helpers.h" -#include"debug_log.h" -#include"lists.h" -#include"memory.h" -#include"strings.h" -#include"utf8.h" -#include"hash.h" - -//---------------------------------------------------------------- -// platform layer -//---------------------------------------------------------------- -#include"platform_clock.h" -/* -#include"platform_rng.h" -#include"platform_socket.h" -#include"platform_thread.h" -*/ - -//---------------------------------------------------------------- -// application layer -//---------------------------------------------------------------- -#include"mp_app.h" - -#if defined(OS_WIN64) || defined(OS_WIN32) - #define WIN32_GL_LOADER_API - #include"win32_gl_loader.h" -#endif - -//---------------------------------------------------------------- -// graphics/ui layer -//---------------------------------------------------------------- -#include"graphics.h" -//#include"ui.h" - -#endif //__MILEPOST_H_ +/************************************************************//** +* +* @file: milepost.h +* @author: Martin Fouilleul +* @date: 13/02/2021 +* @revision: +* +*****************************************************************/ +#ifndef __MILEPOST_H_ +#define __MILEPOST_H_ + +//---------------------------------------------------------------- +// utility layer +//---------------------------------------------------------------- +#include"platform.h" +#include"typedefs.h" +#include"macro_helpers.h" +#include"debug_log.h" +#include"lists.h" +#include"memory.h" +#include"strings.h" +#include"utf8.h" +#include"hash.h" + +//---------------------------------------------------------------- +// platform layer +//---------------------------------------------------------------- +#include"platform_clock.h" +/* +#include"platform_rng.h" +#include"platform_socket.h" +#include"platform_thread.h" +*/ + +//---------------------------------------------------------------- +// application layer +//---------------------------------------------------------------- +#include"mp_app.h" + +#if defined(OS_WIN64) || defined(OS_WIN32) + #define WIN32_GL_LOADER_API +// #include"win32_gl_loader.h" +#endif + +//---------------------------------------------------------------- +// graphics/ui layer +//---------------------------------------------------------------- +#include"graphics.h" +//#include"ui.h" + +#endif //__MILEPOST_H_ diff --git a/src/win32_gl_surface.c b/src/win32_gl_surface.c index dff34c7..1b31e70 100644 --- a/src/win32_gl_surface.c +++ b/src/win32_gl_surface.c @@ -1,220 +1,220 @@ -/************************************************************//** -* -* @file: win32_gl_surface.c -* @author: Martin Fouilleul -* @date: 01/08/2022 -* @revision: -* -*****************************************************************/ - -#define WIN32_GL_LOADER_IMPL -#include"win32_gl_loader.h" - -#include"graphics_internal.h" -#include"win32_app.h" - -#define MG_IMPLEMENTS_BACKEND_GL - -typedef struct mg_gl_surface -{ - mg_surface_info interface; - - HDC hDC; - HGLRC glContext; - -} mg_gl_surface; - -void mg_gl_surface_destroy(mg_surface_info* interface) -{ - mg_gl_surface* surface = (mg_gl_surface*)interface; - //TODO -} - -void mg_gl_surface_prepare(mg_surface_info* interface) -{ - mg_gl_surface* surface = (mg_gl_surface*)interface; - - wglMakeCurrent(surface->hDC, surface->glContext); -} - -void mg_gl_surface_present(mg_surface_info* interface) -{ - mg_gl_surface* surface = (mg_gl_surface*)interface; - - SwapBuffers(surface->hDC); -} - -PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; -PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; -PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB; -PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; - -PFNGLCREATESHADERPROC glCreateShader; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; - -mg_surface mg_gl_surface_create_for_window(mp_window window) -{ - mg_surface surfaceHandle = mg_surface_nil(); - - mp_window_data* windowData = mp_window_ptr_from_handle(window); - if(windowData) - { - //NOTE: create a dummy window - WNDCLASS windowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, - .lpfnWndProc = WinProc, - .hInstance = GetModuleHandleW(NULL), - .lpszClassName = "HelperWindowClass", - .hCursor = LoadCursor(0, IDC_ARROW)}; - - if(!RegisterClass(&windowClass)) - { - //TODO: error - goto quit; - } - - HWND helperWindowHandle = CreateWindow("HelperWindowClass", "Test Window", - WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, - 800, 600, - 0, 0, windowClass.hInstance, 0); - - if(!helperWindowHandle) - { - //TODO: error - goto quit; - } - - //NOTE(martin): create a dummy OpenGL context, to be able to load extensions - HDC dummyDC = GetDC(helperWindowHandle); - - PIXELFORMATDESCRIPTOR pixelFormatDesc = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags - PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. - 32, // Colordepth of the framebuffer. - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 24, // Number of bits for the depthbuffer - 8, // Number of bits for the stencilbuffer - 0, // Number of Aux buffers in the framebuffer. - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - int pixelFormat = ChoosePixelFormat(dummyDC, &pixelFormatDesc); - SetPixelFormat(dummyDC, pixelFormat, &pixelFormatDesc); - - HGLRC dummyGLContext = wglCreateContext(dummyDC); - wglMakeCurrent(dummyDC, dummyGLContext); - - //NOTE(martin): now load extension functions - wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); - wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetProcAddress("wglMakeContextCurrentARB"); - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - - glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource"); - glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"); - glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog"); - glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog"); - glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"); - glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays"); - glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray"); - glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray"); - - //NOTE(martin): now create the true pixel format and gl context - int pixelFormatAttrs[] = { - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_COLOR_BITS_ARB, 32, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, - 0}; - - HDC hDC = GetDC(windowData->win32.hWnd); - u32 numFormats = 0; - - wglChoosePixelFormatARB(hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats); - - if(!pixelFormat) - { - //TODO: error - } - SetPixelFormat(hDC, pixelFormat, &pixelFormatDesc); - - int contextAttrs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, 3, - 0}; - - HGLRC glContext = wglCreateContextAttribsARB(hDC, dummyGLContext, contextAttrs); - - if(!glContext) - { - //TODO error - int error = GetLastError(); - printf("error: %i\n", error); - } - - //NOTE: destroy dummy context and dummy window - wglMakeCurrent(hDC, 0); - wglDeleteContext(dummyGLContext); - DestroyWindow(helperWindowHandle); - - //NOTE: make gl context current - wglMakeCurrent(hDC, glContext); - wglSwapIntervalEXT(1); - - //TODO save important info in surface_data and return a handle - mg_gl_surface* surface = malloc_type(mg_gl_surface); - surface->interface.backend = MG_BACKEND_GL; - surface->interface.destroy = mg_gl_surface_destroy; - surface->interface.prepare = mg_gl_surface_prepare; - surface->interface.present = mg_gl_surface_present; - - //TODO: get/set frame/hidden - - surface->hDC = hDC; - surface->glContext = glContext; - - surfaceHandle = mg_surface_alloc_handle((mg_surface_info*)surface); - } - - quit:; - return(surfaceHandle); -} +/************************************************************//** +* +* @file: win32_gl_surface.c +* @author: Martin Fouilleul +* @date: 01/08/2022 +* @revision: +* +*****************************************************************/ + +#define WIN32_GL_LOADER_IMPL +#include"win32_gl_loader.h" + +#include"graphics_internal.h" +#include"win32_app.h" + +#define MG_IMPLEMENTS_BACKEND_GL + +typedef struct mg_gl_surface +{ + mg_surface_data interface; + + HDC hDC; + HGLRC glContext; + +} mg_gl_surface; + +void mg_gl_surface_destroy(mg_surface_data* interface) +{ + mg_gl_surface* surface = (mg_gl_surface*)interface; + //TODO +} + +void mg_gl_surface_prepare(mg_surface_data* interface) +{ + mg_gl_surface* surface = (mg_gl_surface*)interface; + + wglMakeCurrent(surface->hDC, surface->glContext); +} + +void mg_gl_surface_present(mg_surface_data* interface) +{ + mg_gl_surface* surface = (mg_gl_surface*)interface; + + SwapBuffers(surface->hDC); +} + +PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; +PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; +PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB; +PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + +PFNGLCREATESHADERPROC glCreateShader; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +PFNGLBINDVERTEXARRAYPROC glBindVertexArray; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLBUFFERDATAPROC glBufferData; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; + +mg_surface mg_gl_surface_create_for_window(mp_window window) +{ + mg_surface surfaceHandle = mg_surface_nil(); + + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + //NOTE: create a dummy window + WNDCLASS windowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + .lpfnWndProc = WinProc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "HelperWindowClass", + .hCursor = LoadCursor(0, IDC_ARROW)}; + + if(!RegisterClass(&windowClass)) + { + //TODO: error + goto quit; + } + + HWND helperWindowHandle = CreateWindow("HelperWindowClass", "Test Window", + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, + 800, 600, + 0, 0, windowClass.hInstance, 0); + + if(!helperWindowHandle) + { + //TODO: error + goto quit; + } + + //NOTE(martin): create a dummy OpenGL context, to be able to load extensions + HDC dummyDC = GetDC(helperWindowHandle); + + PIXELFORMATDESCRIPTOR pixelFormatDesc = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags + PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. + 32, // Colordepth of the framebuffer. + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 24, // Number of bits for the depthbuffer + 8, // Number of bits for the stencilbuffer + 0, // Number of Aux buffers in the framebuffer. + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + int pixelFormat = ChoosePixelFormat(dummyDC, &pixelFormatDesc); + SetPixelFormat(dummyDC, pixelFormat, &pixelFormatDesc); + + HGLRC dummyGLContext = wglCreateContext(dummyDC); + wglMakeCurrent(dummyDC, dummyGLContext); + + //NOTE(martin): now load extension functions + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetProcAddress("wglMakeContextCurrentARB"); + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + + glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource"); + glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"); + glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog"); + glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog"); + glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"); + glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays"); + glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray"); + glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray"); + + //NOTE(martin): now create the true pixel format and gl context + int pixelFormatAttrs[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + WGL_COLOR_BITS_ARB, 32, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + 0}; + + HDC hDC = GetDC(windowData->win32.hWnd); + u32 numFormats = 0; + + wglChoosePixelFormatARB(hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats); + + if(!pixelFormat) + { + //TODO: error + } + SetPixelFormat(hDC, pixelFormat, &pixelFormatDesc); + + int contextAttrs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + 0}; + + HGLRC glContext = wglCreateContextAttribsARB(hDC, dummyGLContext, contextAttrs); + + if(!glContext) + { + //TODO error + int error = GetLastError(); + printf("error: %i\n", error); + } + + //NOTE: destroy dummy context and dummy window + wglMakeCurrent(hDC, 0); + wglDeleteContext(dummyGLContext); + DestroyWindow(helperWindowHandle); + + //NOTE: make gl context current + wglMakeCurrent(hDC, glContext); + wglSwapIntervalEXT(1); + + //TODO save important info in surface_data and return a handle + mg_gl_surface* surface = malloc_type(mg_gl_surface); + surface->interface.backend = MG_BACKEND_GL; + surface->interface.destroy = mg_gl_surface_destroy; + surface->interface.prepare = mg_gl_surface_prepare; + surface->interface.present = mg_gl_surface_present; + + //TODO: get/set frame/hidden + + surface->hDC = hDC; + surface->glContext = glContext; + + surfaceHandle = mg_surface_alloc_handle((mg_surface_data*)surface); + } + + quit:; + return(surfaceHandle); +} diff --git a/src/win32_gl_surface.h b/src/win32_gl_surface.h new file mode 100644 index 0000000..a212b03 --- /dev/null +++ b/src/win32_gl_surface.h @@ -0,0 +1,14 @@ +/************************************************************//** +* +* @file: win32_gl_surface.c +* @author: Martin Fouilleul +* @date: 28/01/2023 +* @revision: +* +*****************************************************************/ +#ifndef __WIN32_GL_SURFACE_H_ +#define __WIN32_GL_SURFACE_H_ + +mg_surface mg_gl_surface_create_for_window(mp_window window); + +#endif // __WIN32_GL_SURFACE_H_ diff --git a/src/win32_gles_surface.c b/src/win32_gles_surface.c new file mode 100644 index 0000000..9005aa7 --- /dev/null +++ b/src/win32_gles_surface.c @@ -0,0 +1,125 @@ +/************************************************************//** +* +* @file: osx_gles_surface.cpp +* @author: Martin Fouilleul +* @date: 18/08/2022 +* @revision: +* +*****************************************************************/ +#include +#define EGL_EGLEXT_PROTOTYPES +#include +#include + +#include"graphics_internal.h" + +typedef struct mg_gles_surface +{ + mg_surface_data interface; + + HWND hWnd; + + EGLDisplay eglDisplay; + EGLConfig eglConfig; + EGLContext eglContext; + EGLSurface eglSurface; + +} mg_gles_surface; + +void mg_gles_surface_destroy(mg_surface_data* interface) +{ + ////////////////////////////////////////////////// + //TODO + ////////////////////////////////////////////////// +} + +void mg_gles_surface_prepare(mg_surface_data* interface) +{ + mg_gles_surface* surface = (mg_gles_surface*)interface; + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); +} + +void mg_gles_surface_present(mg_surface_data* interface) +{ + + //TODO: eglSwapBuffers seem to never block in macOS (ie eglSwapInterval doesn't seem to have any effect) + // We need to use a CVDisplayLink to time this if we want surface present to block + + mg_gles_surface* surface = (mg_gles_surface*)interface; + eglSwapBuffers(surface->eglDisplay, surface->eglSurface); +} + +/* +void mg_gles_surface_set_frame(mg_surface_data* interface, mp_rect frame); +mp_rect mg_gles_surface_get_frame(mg_surface_data* interface); +void mg_gles_surface_set_hidden(mg_surface_data* interface, bool hidden); +bool mg_gles_surface_get_hidden(mg_surface_data* interface); +*/ + +mg_surface mg_gles_surface_create_for_window(mp_window window) +{ + mg_surface res = mg_surface_nil(); + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + mg_gles_surface* surface = malloc_type(mg_gles_surface); + memset(surface, 0, sizeof(mg_gles_surface)); + + surface->interface.backend = MG_BACKEND_GLES; + surface->interface.destroy = mg_gles_surface_destroy; + surface->interface.prepare = mg_gles_surface_prepare; + surface->interface.present = mg_gles_surface_present; + /*TODO + surface->interface.getFrame = mg_gles_surface_get_frame; + surface->interface.setFrame = mg_gles_surface_set_frame; + surface->interface.getHidden = mg_gles_surface_get_hidden; + surface->interface.setHidden = mg_gles_surface_set_hidden; + */ + + surface->hWnd = windowData->win32.hWnd; + + EGLAttrib displayAttribs[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_NONE}; + + surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); + eglInitialize(surface->eglDisplay, NULL, NULL); + + EGLint const configAttributes[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, + EGL_SAMPLES, EGL_DONT_CARE, + EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, + EGL_NONE }; + + int numConfigs = 0; + eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs); + + EGLint const surfaceAttributes[] = {EGL_NONE}; + surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay, surface->eglConfig, surface->hWnd, surfaceAttributes); + + eglBindAPI(EGL_OPENGL_ES_API); + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 0, //NOTE: Angle can't create a GLES 3.1 context on macOS + EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE, + EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE, + EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE, + EGL_NONE}; + + surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes); + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + + eglSwapInterval(surface->eglDisplay, 1); + + res = mg_surface_alloc_handle((mg_surface_data*)surface); + } + return(res); +} diff --git a/src/win32_gles_surface.h b/src/win32_gles_surface.h new file mode 100644 index 0000000..a89dff0 --- /dev/null +++ b/src/win32_gles_surface.h @@ -0,0 +1,14 @@ +/************************************************************//** +* +* @file: win32_gles_surface.h +* @author: Martin Fouilleul +* @date: 28/01/2023 +* @revision: +* +*****************************************************************/ +#ifndef __WIN32_GLES_SURFACE_H_ +#define __WIN32_GLES_SURFACE_H_ + +mg_surface mg_gles_surface_create_for_window(mg_window window); + +#endif // __WIN32_GLES_SURFACE_H_