diff --git a/deps/RFont.h b/deps/RFont.h index e6f6a1a..af9a375 100644 --- a/deps/RFont.h +++ b/deps/RFont.h @@ -33,8 +33,8 @@ is in at least one of your files or arguments #define RFONT_NO_STDIO - do not include stdio.h #define RFONT_EXTERNAL_STB - load stb_truetype from stb_truetype.h instead of using the internal version #define RFONT_NO_GRAPHICS - do not include any graphics functions at all -#define RFONT_RENDER_RLGL - use rlgl functions for rendering -#define RFONT_RENDER_LEGACY - use opengl legacy functions for rendering (if rlgl is not chosen) +#define RFONT_RENDER_RGL - use RGL functions for rendering +#define RFONT_RENDER_LEGACY - use opengl legacy functions for rendering (if RGL is not chosen) -- NOTE: By default, opengl 3.3 vbos are used for rendering -- */ @@ -307,6 +307,9 @@ inline u32 RFont_create_atlas(u32 atlasWidth, u32 atlasHeight); /* create a bitm inline void RFont_bitmap_to_atlas(u32 atlas, u8* bitmap, float x, float y, float w, float h); /* add the given bitmap to the texture based on the given coords and size data */ inline void RFont_render_text(u32 atlas, float* verts, float* tcoords, size_t nverts); /* render the text, using the vertices, atlas texture, and texture coords given. */ inline void RFont_render_free(u32 atlas); /* free any memory the renderer might need to free */ + +/* (if modern opengl is being used) switch to rendering using opengl legacy or not */ +inline void RFont_render_legacy(u8 legacy); #endif #endif /* RFONT_H */ @@ -724,7 +727,7 @@ size_t RFont_draw_text_len(RFont_font* font, const char* text, size_t len, float /* texture coords */ - //#if defined(RFONT_RENDER_LEGACY) || defined(RFONT_RENDER_RLGL) + //#if defined(RFONT_RENDER_LEGACY) || defined(RFONT_RENDER_RGL) tcoords[i] = RFONT_GET_TEXPOSX(glyph.x); tcoords[i + 1] = 0; //#endif @@ -758,18 +761,18 @@ size_t RFont_draw_text_len(RFont_font* font, const char* text, size_t len, float return x; } -#if !defined(RFONT_NO_OPENGL) && !defined(RFONT_NO_GRAPHICS) - -#if !defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RLGL) -#define GL_GLEXT_PROTOTYPES -#endif - #ifndef __APPLE__ #include #else #include #endif +#if !defined(RFONT_NO_OPENGL) && !defined(RFONT_NO_GRAPHICS) + +#if !defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RGL) +#define GL_GLEXT_PROTOTYPES +#endif + #ifndef GL_PERSPECTIVE_CORRECTION_HINT #define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 #endif @@ -780,7 +783,16 @@ size_t RFont_draw_text_len(RFont_font* font, const char* text, size_t len, float #ifdef RFONT_DEBUG -void RFont_debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { +#ifndef GL_DEBUG_TYPE_ERROR +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_INFO_LOG_LENGTH 0x8B84 +#endif + +void RFont_debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam) { if (type != GL_DEBUG_TYPE_ERROR) return; @@ -790,26 +802,27 @@ void RFont_debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, void RFont_opengl_getError() { GLenum err; while ((err = glGetError()) != GL_NO_ERROR) { - switch (err) { + switch (err) { case GL_INVALID_ENUM: - printf("OpenGL error: GL_INVALID_ENUM\n"); - break; + printf("OpenGL error: GL_INVALID_ENUM\n"); + break; case GL_INVALID_VALUE: - printf("OpenGL error: GL_INVALID_VALUE\n"); - break; + printf("OpenGL error: GL_INVALID_VALUE\n"); + break; case GL_INVALID_OPERATION: - printf("OpenGL error: GL_INVALID_OPERATION\n"); - break; + printf("OpenGL error: GL_INVALID_OPERATION\n"); + break; case GL_STACK_OVERFLOW: - printf("OpenGL error: GL_STACK_OVERFLOW\n"); - break; + printf("OpenGL error: GL_STACK_OVERFLOW\n"); + break; case GL_STACK_UNDERFLOW: - printf("OpenGL error: GL_STACK_UNDERFLOW\n"); - break; + printf("OpenGL error: GL_STACK_UNDERFLOW\n"); + break; default: - printf("OpenGL error: Unknown error code 0x%x\n", err); - break; - } + printf("OpenGL error: Unknown error code 0x%x\n", err); + break; + } + exit(1); } } @@ -875,73 +888,72 @@ void RFont_bitmap_to_atlas(u32 atlas, u8* bitmap, float x, float y, float w, flo RFont_push_pixel_values(alignment, rowLength, skipPixels, skipRows); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); } -#ifdef RFONT_RENDER_RLGL +#ifdef RFONT_RENDER_RGL void RFont_render_set_color(float r, float g, float b, float a) { - rlColor4f(r, g, b, a); + rglColor4f(r, g, b, a); } void RFont_render_text(u32 atlas, float* verts, float* tcoords, size_t nverts) { glEnable(GL_TEXTURE_2D); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - rlMatrixMode(RL_MODELVIEW); - rlLoadIdentity(); - glDisable(GL_DEPTH_TEST); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_CULL_FACE); - - rlSetTexture(atlas); + glShadeModel(GL_SMOOTH); - glEnable(GL_BLEND); + rglMatrixMode(GL_MODELVIEW); + rglLoadIdentity(); + rglPushMatrix(); - rlPushMatrix(); - - rlBegin(GL_QUADS); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); - i32 i, j = 0; - for (i = 0; (size_t)i < (nverts * 6); i += 2) { - rlTexCoord2f(tcoords[i], tcoords[i + 1]); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + rglSetTexture(atlas); - if (j++ && j == 2 && (j -= 3)) - rlVertex2f(verts[i], verts[i + 1]); + rglBegin(RGL_TRIANGLES_2D); - rlVertex2f(verts[i], verts[i + 1]); + size_t i; + for (i = 0; i < (nverts * 2); i += 2) { + rglTexCoord2f(tcoords[i], tcoords[i + 1]); + + rglVertex2f(verts[i], verts[i + 1]); } - rlEnd(); - rlPopMatrix(); + rglEnd(); + rglPopMatrix(); - rlSetTexture(0); + glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_DEPTH_TEST); } void RFont_render_free(u32 atlas) { glDeleteTextures(1, &atlas); } +void RFont_render_legacy(u8 legacy) { rglLegacy(legacy); } void RFont_render_init() {} -#endif /* RFONT_RENDER_RLGL */ +#endif /* RFONT_RENDER_RGL */ -#if defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RLGL) +#if defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RGL) void RFont_render_set_color(float r, float g, float b, float a) { glColor4f(r, g, b, a); } void RFont_render_text(u32 atlas, float* verts, float* tcoords, size_t nverts) { - glEnable(GL_TEXTURE_2D); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glShadeModel(GL_SMOOTH); + glEnable(GL_TEXTURE_2D); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glShadeModel(GL_SMOOTH); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glDisable(GL_DEPTH_TEST); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_CULL_FACE); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, atlas); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, atlas); glPushMatrix(); @@ -956,18 +968,21 @@ void RFont_render_text(u32 atlas, float* verts, float* tcoords, size_t nverts) { glEnd(); glPopMatrix(); - glBindTexture(GL_TEXTURE_2D, 0); - glEnable(GL_DEPTH_TEST); + glBindTexture(GL_TEXTURE_2D, 0); + glEnable(GL_DEPTH_TEST); } void RFont_render_free(u32 atlas) { glDeleteTextures(1, &atlas); } +void RFont_render_legacy(u8 legacy) { } void RFont_render_init() {} -#endif /* defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RLGL) */ +#endif /* defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RGL) */ -#if !defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RLGL) +#if !defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RGL) typedef struct { GLuint vao, vbo, tbo, cbo, ebo, program, vShader, fShader; + + u8 legacy; } RFont_gl_info; RFont_gl_info RFont_gl = { 0 }; @@ -1001,7 +1016,6 @@ void RFont_debug_shader(u32 src, const char* shader, const char* action) { } RFont_opengl_getError(); - exit(1); } } #endif @@ -1009,6 +1023,9 @@ void RFont_debug_shader(u32 src, const char* shader, const char* action) { #define RFONT_MULTILINE_STR(...) #__VA_ARGS__ void RFont_render_set_color(float r, float g, float b, float a) { + if (RFont_gl.legacy) + return glColor4f(r, g, b, a); + RFont_color[0] = r; RFont_color[1] = g; RFont_color[2] = b; @@ -1016,7 +1033,7 @@ void RFont_render_set_color(float r, float g, float b, float a) { } void RFont_render_init() { - if (RFont_gl.vao != 0) + if (RFont_gl.vao != 0 || RFont_gl.legacy) return; static const char* defaultVShaderCode = RFONT_MULTILINE_STR( @@ -1048,16 +1065,14 @@ void RFont_render_init() { FragColor = texture(texture0, fragTexCoord) * fragColor; } ); - + glGenVertexArrays(1, &RFont_gl.vao); - glBindVertexArray(RFont_gl.vao); glGenBuffers(1, &RFont_gl.vbo); glGenBuffers(1, &RFont_gl.tbo); glGenBuffers(1, &RFont_gl.cbo); glGenBuffers(1, &RFont_gl.ebo); - /* compile vertex shader */ RFont_gl.vShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(RFont_gl.vShader, 1, &defaultVShaderCode, NULL); @@ -1093,7 +1108,7 @@ void RFont_render_init() { RFont_debug_shader(RFont_gl.program, "Both", "link to the program"); #endif } - + void RFont_render_text(u32 atlas, float* verts, float* tcoords, size_t nverts) { glEnable(GL_TEXTURE_2D); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); @@ -1103,71 +1118,91 @@ void RFont_render_text(u32 atlas, float* verts, float* tcoords, size_t nverts) { glEnable(GL_CULL_FACE); glEnable(GL_BLEND); + glShadeModel(GL_SMOOTH); - glBindVertexArray(RFont_gl.vao); + if (RFont_gl.legacy) { + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glBindTexture(GL_TEXTURE_2D, atlas); + glPushMatrix(); - glUseProgram(RFont_gl.program); + glBegin(GL_TRIANGLES); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, RFont_gl.vbo); - glBufferData(GL_ARRAY_BUFFER, nverts * 2 * sizeof(float), verts, GL_DYNAMIC_DRAW); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); + size_t i; + for (i = 0; i < (nverts * 2); i += 2) { + glTexCoord2f(tcoords[i], tcoords[i + 1]); + + glVertex2f(verts[i], verts[i + 1]); + } + glEnd(); + glPopMatrix(); + } else { + glBindVertexArray(RFont_gl.vao); - glEnableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, RFont_gl.tbo); - glBufferData(GL_ARRAY_BUFFER, nverts * 2 * sizeof(float), tcoords, GL_DYNAMIC_DRAW); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glUseProgram(RFont_gl.program); - float* colors = malloc(sizeof(float) * nverts * 4); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, RFont_gl.vbo); + glBufferData(GL_ARRAY_BUFFER, nverts * 2 * sizeof(float), verts, GL_DYNAMIC_DRAW); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); - int i = 0; - for (i = 0; i < (nverts * 4); i += 4) { - colors[i] = RFont_color[0]; - colors[i + 1] = RFont_color[1]; - colors[i + 2] = RFont_color[2]; - colors[i + 3] = RFont_color[3]; - } + glEnableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, RFont_gl.tbo); + glBufferData(GL_ARRAY_BUFFER, nverts * 2 * sizeof(float), tcoords, GL_DYNAMIC_DRAW); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(2); - glBindBuffer(GL_ARRAY_BUFFER, RFont_gl.cbo); - glBufferData(GL_ARRAY_BUFFER, nverts * 4 * sizeof(float), colors, GL_DYNAMIC_DRAW); - glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, NULL); + float* colors = malloc(sizeof(float) * nverts * 4); - free(colors); + int i = 0; + for (i = 0; i < (nverts * 4); i += 4) { + colors[i] = RFont_color[0]; + colors[i + 1] = RFont_color[1]; + colors[i + 2] = RFont_color[2]; + colors[i + 3] = RFont_color[3]; + } - GLushort* indices = malloc(sizeof(GLushort) * 6 * nverts); - int k = 0; + glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, RFont_gl.cbo); + glBufferData(GL_ARRAY_BUFFER, nverts * 4 * sizeof(float), colors, GL_DYNAMIC_DRAW); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, NULL); - int j; - for (j = 0; j < (6 * nverts); j += 6) { - indices[j] = 4* k; - indices[j + 1] = 4*k + 1; - indices[j + 2] = 4*k + 2; - indices[j + 3] = 4*k; - indices[j + 4] = 4*k + 2; - indices[j + 5] = 4*k + 3; + free(colors); - k++; - } + GLushort* indices = malloc(sizeof(GLushort) * 6 * nverts); + int k = 0; + + int j; + for (j = 0; j < (6 * nverts); j += 6) { + indices[j] = 4* k; + indices[j + 1] = 4*k + 1; + indices[j + 2] = 4*k + 2; + indices[j + 3] = 4*k; + indices[j + 4] = 4*k + 2; + indices[j + 5] = 4*k + 3; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RFont_gl.ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 6 * nverts, indices, GL_STATIC_DRAW); + k++; + } - free(indices); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RFont_gl.ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 6 * nverts, indices, GL_STATIC_DRAW); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, atlas); + free(indices); - glDrawArrays(GL_TRIANGLES, 0, nverts); - glUseProgram(0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, atlas); + + glDrawArrays(GL_TRIANGLES, 0, nverts); + glUseProgram(0); + } glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); } void RFont_render_free(u32 atlas) { glDeleteTextures(1, &atlas); - if (RFont_gl.vao == 0) + if (RFont_gl.vao == 0 || RFont_gl.legacy) return; /* free vertex array */ @@ -1184,7 +1219,9 @@ void RFont_render_free(u32 atlas) { glDeleteProgram(RFont_gl.program); } -#endif /* !defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RLGL) */ +void RFont_render_legacy(u8 legacy) { RFont_gl.legacy = legacy; } + +#endif /* !defined(RFONT_RENDER_LEGACY) && !defined(RFONT_RENDER_RGL) */ #endif /* !defined(RFONT_NO_OPENGL) && !defined(RFONT_NO_GRAPHICS) */ /* diff --git a/deps/RGFW.h b/deps/RGFW.h index c9bab39..7311abd 100644 --- a/deps/RGFW.h +++ b/deps/RGFW.h @@ -60,7 +60,6 @@ Copyright (c) 2006-2019 Camilla Löwy */ -#define GL_SILENCE_DEPRECATION #ifndef RGFW_MALLOC #include #include @@ -393,6 +392,7 @@ RGFWDEF char RGFW_keystrToChar(const char*); RGFWDEF const char* RGFW_window_readClipboard(RGFW_window* win); /*!< read clipboard data */ RGFWDEF void RGFW_window_writeClipboard(RGFW_window* win, const char* text, u32 textLen); /*!< write text to the clipboard */ +#ifndef RGFW_NO_THREADS /*! threading functions*/ /*! NOTE! (for X11/linux) : if you define a window in a thread, it must be run after the original thread's window is created or else there will be a memory error */ @@ -405,6 +405,7 @@ RGFWDEF RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args); RGFWDEF void RGFW_cancelThread(RGFW_thread thread); /*!< cancels a thread*/ RGFWDEF void RGFW_joinThread(RGFW_thread thread); /*!< join thread to current thread */ RGFWDEF void RGFW_setThreadPriority(RGFW_thread thread, u8 priority); /*!< sets the priority priority */ +#endif /*! gamepad/joystick functions */ @@ -530,6 +531,12 @@ u8 RGFW_Error() { return RGFW_error; } attribs[index++] = v; \ } +#ifdef __APPLE__ +#define GL_SILENCE_DEPRECATION +#define SILICON_IMPLEMENTATION +#include "silicon.h" +#endif + #ifdef RGFW_OSMESA #ifndef __APPLE__ #include @@ -590,9 +597,6 @@ void RGFW_initVulkan(RGFW_window* win, void* inst) { #include #include -#ifdef RGFW_GL -void* RGFW_getProcAddress(const char* procname) { return (void*)wglGetProcAddress(procname); } -#endif #endif #if defined(__APPLE__) && !defined(RGFW_MACOS_X11) u8 RGFW_keyMap[128] = { 0 }; @@ -989,8 +993,8 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 } if (RGFW_CENTER & args) { - x = (screenR[0] - w) / 1.1; - y = (screenR[1] - h) / 4; + x = (screenR[0] - w) / 2; + y = (screenR[1] - h) / 2; } /* set and init the new window's data */ @@ -1215,8 +1219,8 @@ u32* RGFW_window_screenSize(RGFW_window* win) { Screen* scrn = DefaultScreenOfDisplay((Display*)win->display); - RGFWScreen[0] = scrn->height; - RGFWScreen[1] = scrn->width; + RGFWScreen[0] = scrn->width; + RGFWScreen[1] = scrn->height; return RGFWScreen; } @@ -2167,6 +2171,7 @@ u8 RGFW_isPressedI(RGFW_window* win, u32 key) { #ifdef RGFW_WINDOWS #include +#include char* createUTF8FromWideStringWin32(const WCHAR* source); @@ -2190,9 +2195,10 @@ PFN_OSMesaDestroyContext OSMesaDestroyContextSource; #define OSMesaDestroyContext OSMesaDestroyContextSource #endif -typedef BOOL (*PFN_wglSwapIntervalEXT)(int); -PFN_wglSwapIntervalEXT wglSwapIntervalEXTSrc = NULL; -#define wglSwapIntervalEXT wglSwapIntervalEXTSrc +typedef int (*PFN_wglGetSwapIntervalEXT)(void); +PFN_wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc = NULL; +#define wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc + void* RGFWjoystickApi = NULL; @@ -2201,39 +2207,74 @@ typedef HGLRC WINAPI (*wglCreateContextAttribsARB_type)(HDC hdc, HGLRC hShareCon const i32 *attribList); wglCreateContextAttribsARB_type wglCreateContextAttribsARB = NULL; -typedef BOOL WINAPI wglChoosePixelFormatARB_type(HDC hdc, const i32 *piAttribIList, - const FLOAT *pfAttribFList, UINT nMaxFormats, i32 *piFormats, UINT *nNumFormats); -wglChoosePixelFormatARB_type *wglChoosePixelFormatARB; - /* defines for creating ARB attributes */ #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_TRANSPARENT_ARB 0x200A #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_ACCELERATION_ARB 0x2003 #define WGL_SUPPORT_OPENGL_ARB 0x2010 #define WGL_DOUBLE_BUFFER_ARB 0x2011 #define WGL_PIXEL_TYPE_ARB 0x2013 #define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_ALPHA_BITS_ARB 0x201B #define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_STENCIL_BITS_ARB 0x2023 #define WGL_FULL_ACCELERATION_ARB 0x2027 #define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#ifdef RGFW_WGL_LOAD +static HMODULE wglinstance = NULL; +typedef HGLRC(WINAPI *PFN_wglCreateContext)(HDC); +typedef BOOL(WINAPI *PFN_wglDeleteContext)(HGLRC); +typedef PROC(WINAPI *PFN_wglGetProcAddress)(LPCSTR); +typedef BOOL(WINAPI *PFN_wglMakeCurrent)(HDC, HGLRC); +typedef HDC (WINAPI *PFN_wglGetCurrentDC)(); +typedef HGLRC (WINAPI *PFN_wglGetCurrentContext)(); + +PFN_wglCreateContext wglCreateContextSRC; +PFN_wglDeleteContext wglDeleteContextSRC; +PFN_wglGetProcAddress wglGetProcAddressSRC; +PFN_wglMakeCurrent wglMakeCurrentSRC; +PFN_wglGetCurrentDC wglGetCurrentDCSRC; +PFN_wglGetCurrentContext wglGetCurrentContextSRC; + +#define wglCreateContext wglCreateContextSRC +#define wglDeleteContext wglDeleteContextSRC +#define wglGetProcAddress wglGetProcAddressSRC +#define wglMakeCurrent wglMakeCurrentSRC + +#define wglGetCurrentDC wglGetCurrentDCSRC +#define wglGetCurrentContext wglGetCurrentContextSRC +#endif + +#ifdef RGFW_GL +void* RGFW_getProcAddress(const char* procname) { return (void*)wglGetProcAddress(procname); } +#endif + RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 args) { - #ifdef RGFW_WGL_LOAD + #ifdef RGFW_WGL_LOAD if (wglinstance == NULL) { wglinstance = LoadLibraryA("opengl32.dll"); - wglCreateContext = (PFN_wglCreateContext) GetProcAddress(wglinstance, "wglCreateContext"); - wglDeleteContext = (PFN_wglDeleteContext) GetProcAddress(wglinstance, "wglDeleteContext"); - wglGetProcAddress = (PFN_wglGetProcAddress) GetProcAddress(wglinstance, "wglGetProcAddress"); - wglMakeCurrent = (PFN_wglMakeCurrent) GetProcAddress(wglinstance, "wglMakeCurrent"); + wglCreateContextSRC = (PFN_wglCreateContext) GetProcAddress(wglinstance, "wglCreateContext"); + wglDeleteContextSRC = (PFN_wglDeleteContext) GetProcAddress(wglinstance, "wglDeleteContext"); + wglGetProcAddressSRC = (PFN_wglGetProcAddress) GetProcAddress(wglinstance, "wglGetProcAddress"); + wglMakeCurrentSRC = (PFN_wglMakeCurrent) GetProcAddress(wglinstance, "wglMakeCurrent"); + wglGetCurrentDCSRC = (PFN_wglGetCurrentDC) GetProcAddress(wglinstance, "wglGetCurrentDC"); + wglGetCurrentContextSRC = (PFN_wglGetCurrentContext) GetProcAddress(wglinstance, "wglGetCurrentContext"); } #endif + typedef BOOL (APIENTRY *PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); + static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; + if (name[0] == 0) name = (char*)" "; RGFW_window* win = (RGFW_window*)RGFW_MALLOC(sizeof(RGFW_window)); @@ -2256,8 +2297,8 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 } if (RGFW_CENTER & args) { - x = (r[0] - w) / 1.1; - y = (r[1] - h) / 4; + x = (r[0] - w) / 2; + y = (r[1] - h) / 2; } #ifndef RGFW_RECT @@ -2279,35 +2320,53 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 WNDCLASSA Class = {0}; /* Setup the Window class. */ Class.lpszClassName = name; Class.hInstance = inh; - Class.hCursor = LoadCursor(NULL, IDC_ARROW); + win->cursor = Class.hCursor = LoadCursor(NULL, IDC_ARROW); Class.lpfnWndProc = DefWindowProc; RegisterClassA(&Class); - DWORD window_style = 0; - window_style = WS_MAXIMIZEBOX | WS_MINIMIZEBOX | window_style; + DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - if (!(RGFW_NO_BORDER & args)) - window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER; - else - window_style |= WS_POPUP | WS_VISIBLE; + RECT windowRect, clientRect; - if (!(RGFW_NO_RESIZE & args)) - window_style |= WS_SIZEBOX; + if (!(RGFW_NO_BORDER & args)) { + window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_VISIBLE | WS_MINIMIZEBOX; + + if (!(RGFW_NO_RESIZE & args)) + window_style |= WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME; + } + else + window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX; win->display = CreateWindowA( Class.lpszClassName, name, window_style, x, y, w, h, 0, 0, inh, 0); - if (RGFW_TRANSPARENT_WINDOW & args) - SetWindowLong((HWND)win->display, GWL_EXSTYLE, GetWindowLong((HWND)win->display, GWL_EXSTYLE) | WS_EX_LAYERED); + GetWindowRect(win->display, &windowRect); + GetClientRect(win->display, &clientRect); + + win->h += (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top); + RGFW_window_resize(win, win->w, win->h); + + if (RGFW_TRANSPARENT_WINDOW & args) { + SetWindowLong((HWND)win->display, GWL_EXSTYLE, GetWindowLong((HWND)win->display, GWL_EXSTYLE) | WS_EX_LAYERED); + + DWM_BLURBEHIND bb = {0}; + bb.dwFlags = DWM_BB_ENABLE; + bb.fEnable = TRUE; + bb.hRgnBlur = NULL; + DwmEnableBlurBehindWindow(win->display, &bb); + + MARGINS margins = {-1}; + DwmExtendFrameIntoClientArea(win->display, &margins); + } if (RGFW_ALLOW_DND & args) DragAcceptFiles((HWND)win->display, TRUE); win->window = GetDC((HWND)win->display); - #ifdef RGFW_GL - HGLRC prc; + + HGLRC prc; HDC pdc; PIXELFORMATDESCRIPTOR pfd; @@ -2331,11 +2390,20 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 wglCreateContextAttribsARB = (wglCreateContextAttribsARB_type) wglGetProcAddress("wglCreateContextAttribsARB"); - wglSwapIntervalEXT = (PFN_wglSwapIntervalEXT) - wglGetProcAddress("wglSwapIntervalEXT"); + wglGetSwapIntervalEXTSrc = (PFN_wglGetSwapIntervalEXT) + wglGetProcAddress("wglGetSwapIntervalEXT"); + + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); } - wglMakeCurrent(pdc, prc); + if ((wglCreateContextAttribsARB != NULL && wglChoosePixelFormatARB == NULL) || wglChoosePixelFormatARB == NULL) { + #ifdef RGFW_DEBUG + printf("Failed to load wglCreateContextAttribsARB func\n"); + exit(0); + #endif + } + + wglMakeCurrent(pdc, prc); if (wglCreateContextAttribsARB != NULL) { wglDeleteContext(win->glWin); @@ -2358,20 +2426,36 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 i32 index = 0; SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); - SET_ATTRIB(WGL_STENCIL_BITS_ARB, 8); if (RGFW_majorVersion || RGFW_minorVersion) { SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion); SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion); + SET_ATTRIB(WGL_SUPPORT_OPENGL_ARB, GL_TRUE); + + SET_ATTRIB(WGL_DRAW_TO_WINDOW_ARB, TRUE); + SET_ATTRIB(WGL_DOUBLE_BUFFER_ARB, TRUE); + SET_ATTRIB(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); + SET_ATTRIB(WGL_TRANSPARENT_ARB, TRUE); + SET_ATTRIB(WGL_COLOR_BITS_ARB, 32); + SET_ATTRIB(WGL_RED_BITS_ARB, 8); + SET_ATTRIB(WGL_GREEN_BITS_ARB, 8); + SET_ATTRIB(WGL_BLUE_BITS_ARB, 8); + SET_ATTRIB(WGL_ALPHA_BITS_ARB, 8); + SET_ATTRIB(WGL_DEPTH_BITS_ARB, 24); + SET_ATTRIB(WGL_STENCIL_BITS_ARB, 8); } SET_ATTRIB(0, 0); win->glWin = wglCreateContextAttribsARB(win->window, NULL, attribs); } - else - win->glWin = wglCreateContext(win->window); - } + else { + printf("Failed to create an accelerated OpenGL Context\n"); + win->glWin = wglCreateContext(win->window); + } + } + else + printf("Failed to create an accelerated OpenGL Context\n"); #endif @@ -2496,8 +2580,10 @@ RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { case WM_MOUSEMOVE: #ifndef RGFW_RECT win->event.x = msg.pt.x - win->x; + win->event.y = msg.pt.y - win->y; #else win->event.x = msg.pt.x - win->r.x; + win->event.y = msg.pt.y - win->r.y; #endif win->event.type = RGFW_mousePosChanged; @@ -2607,6 +2693,7 @@ RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { mmi->ptMaxTrackSize.y = RGFW_WIN_MAX_SIZE[1]; return 0; } + default: win->event.type = 0; break; @@ -2888,16 +2975,15 @@ char* createUTF8FromWideStringWin32(const WCHAR* source) { } - +#ifndef RGFW_NO_THREADS RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args) { return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)*function_ptr, args, 0, NULL); } void RGFW_cancelThread(RGFW_thread thread) { CloseHandle((HANDLE)thread); } void RGFW_joinThread(RGFW_thread thread) { WaitForSingleObject((HANDLE)thread, INFINITE); } void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { SetThreadPriority((HANDLE)thread, priority); } #endif +#endif #if defined(__APPLE__) && !defined(RGFW_MACOS_X11) -#define SILICON_IMPLEMENTATION -#include "silicon.h" #include void* RGFWnsglFramework = NULL; @@ -3021,8 +3107,8 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 } if (RGFW_CENTER & args) { - x = (r[0] - w) / 4; - y = (r[1] - h) / 4; + x = (r[0] - w) / 2; + y = (r[1] - h) / 2; } #ifndef RGFW_RECT @@ -3035,7 +3121,7 @@ RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, u64 #endif win->fpsCap = 0; - win->event.inFocus = 0; + win->event.inFocus = 1; win->event.type = 0; win->event.droppedFilesCount = 0; @@ -3493,6 +3579,7 @@ void RGFW_window_close(RGFW_window* win){ #if defined(RGFW_X11) || defined(__APPLE__) +#ifndef RGFW_NO_THREADS #include RGFW_thread RGFW_createThread(void* (*function_ptr)(void*), void* args) { @@ -3506,6 +3593,7 @@ void RGFW_joinThread(RGFW_thread thread) { pthread_join((pthread_t)thread, NULL) void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { pthread_setschedprio(thread, priority); } #endif #endif +#endif void RGFW_window_makeCurrent_OpenGL(RGFW_window* win) { #ifdef RGFW_GL @@ -3541,7 +3629,25 @@ void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) { ((PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress((GLubyte*)"glXSwapIntervalEXT"))((Display*)win->display, (Window)win->window, swapInterval); #endif #ifdef RGFW_WINDOWS - wglSwapIntervalEXT(swapInterval); + + typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval); + static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; + static void* loadSwapFunc = (void*)1; + + if (loadSwapFunc == NULL) { + printf("wglSwapIntervalEXT not supported\n"); + win->fpsCap = (swapInterval == 1) ? 0 : swapInterval; + return; + } + + if (wglSwapIntervalEXT == NULL) { + loadSwapFunc = wglGetProcAddress("wglSwapIntervalEXT"); + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)loadSwapFunc; + } + + if (wglSwapIntervalEXT(swapInterval) == FALSE) + printf("Failed to set swap interval\n"); + #endif #if defined(__APPLE__) && !defined(RGFW_MACOS_X11) win->glWin = NSOpenGLView_openGLContext(win->view); @@ -3576,8 +3682,6 @@ void RGFW_window_swapBuffers(RGFW_window* win) { #endif #endif - - /* clear the window*/ diff --git a/deps/RGL.h b/deps/RGL.h index 3ac8c0f..fbbc240 100644 --- a/deps/RGL.h +++ b/deps/RGL.h @@ -116,7 +116,7 @@ typedef u8 b8; #endif #ifndef RGL_MAX_BATCHES -#define RGL_MAX_BATCHES 256 +#define RGL_MAX_BATCHES 1028 #endif #ifndef RGL_MAX_BUFFER_ELEMENTS @@ -132,6 +132,11 @@ typedef u8 b8; #define RGL_LINES 0x0001 /* GL_LINES */ #define RGL_TRIANGLES 0x0004 /* GL_TRIANGLES */ #define RGL_QUADS 0x0007 /* GL_QUADS */ + +/* these ensure GL_DEPTH_TEST is disabled when they're being rendered */ +#define RGL_LINES_2D 0x0011 /* GL_LINES */ +#define RGL_TRIANGLES_2D 0x0014 /* GL_TRIANGLES */ +#define RGL_QUADS_2D 0x0017 /* GL_QUADS */ #endif #ifndef GL_PERSPECTIVE_CORRECTION_HINT @@ -206,7 +211,7 @@ extern "C" { /* Prevents name mangling of functions */ RGLDEF void rglInit(int width, i32 height, void* loader); /* Initialize RGLinfo (buffers, shaders, textures, states) */ RGLDEF void rglClose(void); /* De-initialize RGLinfo (buffers, shaders, textures) */ -RGLDEF void rglSetFramebufferSize(int width, i32 height); /* Set current framebuffer size */ +RGLDEF void rglSetFramebufferSize(i32 width, i32 height); /* Set current framebuffer size */ RGLDEF void rglRenderBatch(void); /* Draw render batch data (Update->Draw->Reset) */ RGLDEF void rglRenderBatchWithShader(u32 program, u32 vertexLocation, u32 texCoordLocation, u32 colorLocation); @@ -219,8 +224,12 @@ RGLDEF void rglPerspective(double fovY, double aspect, double zNear, double zFar /* Scale */ RGLDEF RGL_MATRIX rglMatrixScale(float x, float y, float z); +/* render with legacy (or turn of legacy rendering if you turned it on) */ +RGLDEF void rglLegacy(u8 state); + +RGLDEF void rglBegin(int mode); + #if defined(RGL_OPENGL_LEGACY) -#define rglBegin glBegin #define rglColor3f glColor3f #define rglColor3ub glColor4ub #define rglColor4f glColor4f @@ -243,7 +252,6 @@ RGLDEF RGL_MATRIX rglMatrixScale(float x, float y, float z); #define rglLineWidth glLineWidth #else -RGLDEF void rglBegin(int mode); RGLDEF void rglEnd(void); RGLDEF void rglTexCoord2f(float x, float y); @@ -308,6 +316,8 @@ typedef GLint (*glGetUniformLocationPROC)(GLuint program, const GLchar *name); typedef void (*glUniformMatrix4fvPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (*glTexImage2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); typedef void (*glActiveTexturePROC) (GLenum texture); +typedef void (*glDebugMessageCallbackPROC)(void* callback, const void*); +typedef void (*glDebugMessageCallbackPROC)(void* callback, const void*); glShaderSourcePROC glShaderSourceSRC = NULL; glCreateShaderPROC glCreateShaderSRC = NULL; @@ -338,6 +348,7 @@ glBindVertexArrayPROC glBindVertexArraySRC = NULL; glGetUniformLocationPROC glGetUniformLocationSRC = NULL; glUniformMatrix4fvPROC glUniformMatrix4fvSRC = NULL; glActiveTexturePROC glActiveTextureSRC = NULL; +glDebugMessageCallbackPROC glDebugMessageCallbackSRC = NULL; #define glActiveTexture glActiveTextureSRC #define glShaderSource glShaderSourceSRC @@ -368,6 +379,7 @@ glActiveTexturePROC glActiveTextureSRC = NULL; #define glBindVertexArray glBindVertexArraySRC #define glGetUniformLocation glGetUniformLocationSRC #define glUniformMatrix4fv glUniformMatrix4fvSRC +#define glDebugMessageCallback glDebugMessageCallbackSRC extern int RGL_loadGL3(RGLloadfunc proc); @@ -435,23 +447,30 @@ typedef struct RGL_INFO { i32 currentBuffer; /* Current buffer tracking in case of multi-buffering */ i32 drawCounter; /* Draw calls counter */ - #ifdef RGL_ALLOC_BATCHES RGL_BATCH* batches; /* Draw calls array, depends on tex */ - #else - RGL_BATCH batches[RGL_MAX_BATCHES]; - #endif - + u32 vao, vbo, tbo, cbo, ebo; /* array object and array buffers */ + + u8 legacy; } RGL_INFO; RGL_INFO RGLinfo; #endif /* RGL_MODERN_OPENGL */ void rglSetTexture(u32 id) { -#if defined(RGL_OPENGL_LEGACY) - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, id); -#else + #if defined(RGL_MODERN_OPENGL) && !defined(RGL_OPENGL_LEGACY) + if (RGLinfo.legacy) + #endif + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, id); + + return; + } +#if defined(RGL_MODERN_OPENGL) + if (RGLinfo.tex == id) + return; + RGLinfo.tex = id; if (id == 0) @@ -523,8 +542,15 @@ void RGL_opengl_getError() { } #ifdef RGL_MODERN_OPENGL + +#ifndef GL_LINK_STATUS +#define GL_LINK_STATUS 0x8B82 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#endif + void RGL_debug_shader(u32 src, const char *shader, const char *action) { - GLint status; + GLint status; if (action[0] == 'l') glGetProgramiv(src, GL_LINK_STATUS, &status); else @@ -556,16 +582,29 @@ void RGL_debug_shader(u32 src, const char *shader, const char *action) { #define RGL_MULTILINE_STR(...) #__VA_ARGS__ +#ifdef RGL_OPENGL_LEGACY +void rglBegin(int mode) { + printf("%i\n", mode - 0x0010); + if (mode > 0x0010) + return glBegin(mode - 0x0010); + return glBegin(mode); +} +#endif + /* Initialize RGLinfo: OpenGL extensions, default buffers/shaders/textures, OpenGL states*/ void rglInit(int width, i32 height, void *loader) { #if defined(RGL_MODERN_OPENGL) if (RGL_loadGL3((RGLloadfunc)loader)) { #ifdef RGL_DEBUG - printf("Failed to load an OpenGL 3.3 Context\n"); + printf("Failed to load an OpenGL 3.3 Context, reverting to OpenGL Legacy\n"); #endif - exit(1); + + RGLinfo.legacy = 2; + return; } + RGLinfo.legacy = 0; + static const char *defaultVShaderCode = RGL_MULTILINE_STR( \x23version 330 \n in vec3 vertexPosition; @@ -639,7 +678,7 @@ void rglInit(int width, i32 height, void *loader) { RGLinfo.elementCount = RGL_MAX_BUFFER_ELEMENTS; RGLinfo.vertices = (float *)RGL_MALLOC(RGL_MAX_BUFFER_ELEMENTS * 3 * 4 * sizeof(float) * RGL_MAX_BATCHES); - RGLinfo.tcoords = (float *)RGL_MALLOC(RGL_MAX_BUFFER_ELEMENTS * 2 * 4 * sizeof(float) * RGL_MAX_BATCHES); + RGLinfo.tcoords = (float*)RGL_MALLOC(RGL_MAX_BUFFER_ELEMENTS * 2 * 4 * sizeof(float) * RGL_MAX_BATCHES); RGLinfo.colors = (float*)RGL_MALLOC(RGL_MAX_BUFFER_ELEMENTS * 4 * 4 * sizeof(float) * RGL_MAX_BATCHES); RGLinfo.indices = (u16*)RGL_MALLOC(RGL_MAX_BUFFER_ELEMENTS * 6 * sizeof(u16) * RGL_MAX_BATCHES); @@ -694,9 +733,7 @@ void rglInit(int width, i32 height, void *loader) { RGLinfo.defaultTex = rglCreateTexture(white, 1, 1, 4); RGLinfo.tex = RGLinfo.defaultTex; - #ifdef RGL_ALLOC_BATCHES RGLinfo.batches = (RGL_BATCH *)RGL_MALLOC(RGL_MAX_BATCHES * sizeof(RGL_BATCH)); - #endif #ifdef RGL_ALLOC_MATRIX_STACK RGLinfo.statck = (RGL_MATRIX*)RGL_MALLOC(RGL_MAX_MATRIX_STACK_SIZE * sizeof(RGL_MATRIX)); @@ -704,7 +741,7 @@ void rglInit(int width, i32 height, void *loader) { u32 i; for (i = 0; i < RGL_MAX_BATCHES; i++) { - RGLinfo.batches[i].mode = RGL_QUADS; + RGLinfo.batches[i].mode = 0; RGLinfo.batches[i].vertexCount = 0; RGLinfo.batches[i].vertexAlignment = 0; RGLinfo.batches[i].tex = RGLinfo.tex; @@ -731,6 +768,9 @@ void rglInit(int width, i32 height, void *loader) { /* Vertex Buffer Object deinitialization (memory free) */ void rglClose(void) { #if defined(RGL_MODERN_OPENGL) + if (RGLinfo.legacy) + return; + /* Unbind everything */ glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -790,12 +830,18 @@ void rglSetFramebufferSize(int width, i32 height) { void rglRenderBatch() { #if defined(RGL_MODERN_OPENGL) + if (RGLinfo.legacy) + return; + rglRenderBatchWithShader(RGLinfo.program, 0, 1, 2); #endif } void rglRenderBatchWithShader(u32 program, u32 vertexLocation, u32 texCoordLocation, u32 colorLocation) { #if defined(RGL_MODERN_OPENGL) + if (RGLinfo.legacy) + return; + if (RGLinfo.vertexCounter > 0) { glBindVertexArray(RGLinfo.vao); @@ -843,20 +889,29 @@ void rglRenderBatchWithShader(u32 program, u32 vertexLocation, u32 texCoordLocat u32 vertexOffset; u32 i; - for (i = 0, vertexOffset = 0; i < RGLinfo.drawCounter; i++) { + for (i = 1, vertexOffset = 0; i < RGLinfo.drawCounter; i++) { + GLenum mode = RGLinfo.batches[i].mode; + + if (mode > 0x0010) { + mode -= 0x0010; + glDisable(GL_DEPTH_TEST); + } + /* Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default */ glBindTexture(GL_TEXTURE_2D, RGLinfo.batches[i].tex); #ifdef RGL_EBO - if ((RGLinfo.batches[i].mode == RGL_LINES) || (RGLinfo.batches[i].mode == RGL_TRIANGLES)) + if ((modee == RGL_LINES) || (mode == RGL_TRIANGLES)) #endif - glDrawArrays(RGLinfo.batches[i].mode, vertexOffset, RGLinfo.batches[i].vertexCount); - + glDrawArrays(mode, vertexOffset, RGLinfo.batches[i].vertexCount); #ifdef RGL_EBO else glDrawElements(GL_TRIANGLES, RGLinfo.batches[i].vertexCount / 4 * 6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset / 4 * 6 * sizeof(GLushort))); #endif vertexOffset += (RGLinfo.batches[i].vertexCount + RGLinfo.batches[i].vertexAlignment); + + if (RGLinfo.batches[i].mode > 0x0010) + glEnable(GL_DEPTH_TEST); } if (!RGLinfo.vao) { @@ -916,30 +971,41 @@ RGL_MATRIX rglMatrixScale(float x, float y, float z) { return result; } +void rglLegacy(u8 state) { + #if defined(RGL_MODERN_OPENGL) + if (state != 2) + RGLinfo.legacy = state; + #endif +} + #if defined(RGL_MODERN_OPENGL) -/* Check internal buffer overflow for a given number of vertex */ -/* and force a void draw call if required */ int rglCheckRenderBatchLimit(int vCount) { - if ((RGLinfo.vertexCounter + vCount) < (RGLinfo.elementCount*4)) + if (RGLinfo.legacy || (RGLinfo.vertexCounter + vCount) < (RGLinfo.elementCount * 4)) return 0; /* Store current primitive drawing mode and texture id */ i32 currentMode = RGLinfo.batches[RGLinfo.drawCounter - 1].mode; - - rglRenderBatch(); /* NOTE: Stereo rendering is checked inside */ + + rglRenderBatch(); /* Restore state of last batch so we can continue adding vertices */ RGLinfo.batches[RGLinfo.drawCounter - 1].mode = currentMode; RGLinfo.batches[RGLinfo.drawCounter - 1].tex = RGLinfo.tex; - return 1; } /* Initialize drawing mode (how to organize vertex) */ void rglBegin(int mode) { - if (RGLinfo.batches[RGLinfo.drawCounter - 1].mode != mode && - RGLinfo.batches[RGLinfo.drawCounter - 1].tex != RGLinfo.tex && + if (RGLinfo.legacy) { + if (mode > 0x0010) + mode -= 0x0010; + + return glBegin(mode); + } + + if (RGLinfo.batches[RGLinfo.drawCounter - 1].mode != mode || + RGLinfo.batches[RGLinfo.drawCounter - 1].tex != RGLinfo.tex || RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount > 0) { if (RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_LINES) RGLinfo.batches[RGLinfo.drawCounter - 1].vertexAlignment = ((RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount < 4)? RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount : RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount%4); @@ -963,11 +1029,15 @@ void rglBegin(int mode) { } void rglEnd(void) { - + if (RGLinfo.legacy) + return glEnd(); } /* Define one vertex (texture coordinate) */ void rglTexCoord2f(float x, float y) { + if (RGLinfo.legacy) + return glTexCoord2f(x, y); + RGLinfo.tcoord[0] = x; RGLinfo.tcoord[1] = y; } @@ -986,6 +1056,9 @@ void rglColor3f(float r, float g, float b) { } void rglColor4f(float r, float g, float b, float a) { + if (RGLinfo.legacy) + return glColor4f(r, g, b, a); + RGLinfo.color[0] = r; RGLinfo.color[1] = g; RGLinfo.color[2] = b; @@ -998,6 +1071,9 @@ void rglVertex2f(float x, float y) { } void rglVertex3f(float x, float y, float z) { + if (RGLinfo.legacy) + return glVertex3f(x, y, z); + float tx = x; float ty = y; float tz = z; @@ -1009,13 +1085,13 @@ void rglVertex3f(float x, float y, float z) { } if (RGLinfo.vertexCounter > (RGLinfo.elementCount * 4 - 4)) { - if ((RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_LINES) && + if ((RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_LINES || RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_LINES_2D) && (RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount%2 == 0)) rglCheckRenderBatchLimit(2 + 1); - else if ((RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_TRIANGLES) && + else if ((RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_TRIANGLES || RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_TRIANGLES_2D) && (RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount%3 == 0)) rglCheckRenderBatchLimit(3 + 1); - else if ((RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_QUADS) && + else if ((RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_QUADS || RGLinfo.batches[RGLinfo.drawCounter - 1].mode == RGL_QUADS_2D) && (RGLinfo.batches[RGLinfo.drawCounter - 1].vertexCount%4 == 0)) rglCheckRenderBatchLimit(4 + 1); } @@ -1040,6 +1116,9 @@ void rglVertex3f(float x, float y, float z) { /* Multiply the current matrix by a translation matrix */ void rglTranslatef(float x, float y, float z) { + if (RGLinfo.legacy) + return glTranslatef(x, y, z); + RGL_MATRIX matTranslation = { { 1.0f, 0.0f, 0.0f, 0.0f, @@ -1055,6 +1134,10 @@ void rglTranslatef(float x, float y, float z) { /* Multiply the current matrix by a rotation matrix */ void rglRotatef(float angle, float x, float y, float z) { + if (RGLinfo.legacy) { + return glRotatef(angle, x, y, z); + } + /* Axis vector (x, y, z) normalization */ float lengthSquared = x * x + y * y + z * z; if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) { @@ -1082,6 +1165,10 @@ void rglRotatef(float angle, float x, float y, float z) { /* Multiply the current matrix by an orthographic matrix generated by parameters */ void rglOrtho(double left, double right, double bottom, double top, double znear, double zfar) { + if (RGLinfo.legacy) { + return glOrtho(left, right, bottom, top, znear, zfar); + } + float rl = (float)(right - left); float tb = (float)(top - bottom); float fn = (float)(zfar - znear); @@ -1103,6 +1190,10 @@ void rglOrtho(double left, double right, double bottom, double top, double znear /* Choose the current matrix to be transformed */ void rglMatrixMode(int mode) { + if (RGLinfo.legacy) { + return glMatrixMode(mode); + } + RGLinfo.matrixMode = mode; if (mode == RGL_MODELVIEW) @@ -1113,6 +1204,9 @@ void rglMatrixMode(int mode) { /* Push the current matrix into RGLinfo.stack */ void rglPushMatrix(void) { + if (RGLinfo.legacy) + return glPushMatrix(); + RGLinfo.stack[RGLinfo.stackCounter] = *RGLinfo.matrix; if (RGLinfo.matrixMode == RGL_MODELVIEW) { @@ -1125,6 +1219,9 @@ void rglPushMatrix(void) { /* Pop lattest inserted matrix from RGLinfo.stack */ void rglPopMatrix(void) { + if (RGLinfo.legacy) + return glPopMatrix(); + if (RGLinfo.stackCounter > 0) { RGL_MATRIX mat = RGLinfo.stack[RGLinfo.stackCounter - 1]; *RGLinfo.matrix = mat; @@ -1139,6 +1236,9 @@ void rglPopMatrix(void) { /* Reset current matrix to identity matrix */ void rglLoadIdentity(void) { + if (RGLinfo.legacy) + return glLoadIdentity(); + *RGLinfo.matrix = rglMatrixIdentity(); } @@ -1155,6 +1255,10 @@ RGL_MATRIX rglMatrixIdentity(void) { } void rglMultMatrixf(const float* m) { + if (RGLinfo.legacy) { + return glMultMatrixf(m); + } + *RGLinfo.matrix = rglMatrixMultiply(RGLinfo.matrix->m, (float*)m); } @@ -1211,6 +1315,7 @@ int RGL_loadGL3(RGLloadfunc proc) { RGL_PROC_DEF(proc, glGetUniformLocation); RGL_PROC_DEF(proc, glUniformMatrix4fv); RGL_PROC_DEF(proc, glActiveTexture); + RGL_PROC_DEF(proc, glDebugMessageCallback); if ( glShaderSourceSRC == NULL || @@ -1240,9 +1345,18 @@ int RGL_loadGL3(RGLloadfunc proc) { glGenBuffersSRC == NULL || glBindVertexArraySRC == NULL || glGetUniformLocationSRC == NULL || - glUniformMatrix4fvSRC == NULL + glUniformMatrix4fvSRC == NULL || + glDebugMessageCallbackSRC == NULL ) return 1; + + GLuint vao; + glGenVertexArraysSRC(1, &vao); + + if (vao == 0) + return 1; + + glDeleteVertexArraysSRC(1, &vao); return 0; } diff --git a/deps/miniaudio.h b/deps/miniaudio.h index 718a4ab..942a688 100644 --- a/deps/miniaudio.h +++ b/deps/miniaudio.h @@ -3628,6 +3628,13 @@ Some backends have some nuance details you may want to be aware of. is due to 64-bit file APIs not being available. */ +/* for cross compiling */ +#ifdef __linux__ +#define MA_NO_WFOPEN + +#pragma GCC diagnostic ignored "-Wformat" +#endif + #ifndef miniaudio_h #define miniaudio_h diff --git a/deps/silicon.h b/deps/silicon.h index 930e502..f939eba 100644 --- a/deps/silicon.h +++ b/deps/silicon.h @@ -76,6 +76,11 @@ #define NSUIntegerMax ULONG_MAX +#define si_SEL_exists(name) si_impl_SEL_exists(name, __FILE__, __LINE__) +#define selector(function) si_SEL_exists(#function":") + +SICDEF SEL si_impl_SEL_exists(const char* name, const char* filename, int line); + #ifndef siArray #define SILICON_ARRAY_IMPLEMENTATION @@ -595,8 +600,16 @@ SICDEF NSColor* NSColor_clearColor(void); SICDEF NSColor* NSColor_keyboardFocusIndicatorColor(void); /* ============ NSString ============ */ +/* converts a C String to an NSString object */ SICDEF NSString* NSString_stringWithUTF8String(const char* str); +/* converts an NString object to a C String */ SICDEF const char* NSString_to_char(NSString* str); +/* the name of a class in string form */ +SICDEF NSString* NSStringFromClass(id class); +/* compares an NSString object data with an C String */ +SICDEF bool NSString_isEqualChar(NSString* str, const char* str2); +/* compares two NSString objects */ +SICDEF bool NSString_isEqual(NSString* str, NSString* str2); /* ============ NSDictionary ============ */ SICDEF const char* NSDictionary_objectForKey(NSDictionary* d, const char* str); @@ -1162,7 +1175,8 @@ typedef NS_ENUM(NSUInteger, NSSearchPathDomainMask) { NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items }; -siArray(const char*) NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, bool expandTilde); +#define NSSearchPathForDirectoriesInDomains _NSSearchPathForDirectoriesInDomains +siArray(const char*) _NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, bool expandTilde); #endif /* ndef SILICON_H */ @@ -1219,6 +1233,37 @@ abi_objc_msgSend_stret - Sends a message with a data-structure return value to a const NSSize _NSZeroSize = {0, 0}; +#define si_SEL_exists(name) si_impl_SEL_exists(name, __FILE__, __LINE__) +#define selector(function) si_SEL_exists(#function":") + +SEL si_impl_SEL_exists(const char* name, const char* filename, int line) { + SEL selector = sel_getUid(name); + + Class original_class = nil; + unsigned int class_count = 0; + Class* class_list = objc_copyClassList(&class_count); + + for (unsigned int i = 0; i < class_count; i++) { + Class cls = class_list[i]; + + if (strcmp(class_getName((Class)cls), "UINSServiceViewController") == 0) // For whatever reason, this class ruins everything. + continue; + + if (class_getInstanceMethod(cls, selector)) { + original_class = cls; + break; + } + } + free(class_list); + + if (original_class == nil) { + printf("%s:%i: Method '%s' doesn't exist. If this is a C function, then make sure to convert it into a SEL method via 'func_to_SEL()' before this line.\n", filename, line, name); + return nil; + } + + return selector; +} + /* Key stuff. */ const char* NSKEYS[] = { "Up", "Down", "Left", "Right", @@ -1504,11 +1549,13 @@ enum { /* classes */ NS_WINDOW_IS_ZOOMED_CODE, NS_WINDOW_PERFORM_MINIATURIZE_CODE, NS_WINDOW_PERFORM_ZOOM_CODE, - NS_WINDOW_STYLE_MASK_CODE + NS_WINDOW_STYLE_MASK_CODE, + NS_STRING_FROM_CLASS_CODE, + NS_STRING_IS_EQUAL_CODE, }; void* SI_NS_CLASSES[36] = {NULL}; -void* SI_NS_FUNCTIONS[232]; +void* SI_NS_FUNCTIONS[233]; void si_initNS(void) { SI_NS_CLASSES[NS_APPLICATION_CODE] = objc_getClass("NSApplication"); @@ -1653,6 +1700,7 @@ void si_initNS(void) { SI_NS_FUNCTIONS[NS_BITMAPIMAGEREP_INIT_BITMAP_CODE] = sel_getUid("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:"); SI_NS_FUNCTIONS[NS_VIEW_SET_WANTSLAYER_CODE] = sel_getUid("setWantsLayer:"); SI_NS_FUNCTIONS[NS_STRING_WIDTH_UTF8_STRING_CODE] = sel_getUid("stringWithUTF8String:"); + SI_NS_FUNCTIONS[NS_STRING_IS_EQUAL_CODE] = sel_getUid("isEqual:"); SI_NS_FUNCTIONS[NS_ARRAY_SI_ARRAY_CODE] = sel_getUid("initWithObjects:count:"); SI_NS_FUNCTIONS[NS_WINDOW_SET_CONTENT_VIEW_CODE] = sel_getUid("setContentView:"); SI_NS_FUNCTIONS[NS_APPLICATION_NEXT_EVENT_MATCHING_MASK_CODE] = sel_getUid("nextEventMatchingMask:untilDate:inMode:dequeue:"); @@ -3062,6 +3110,19 @@ const char* NSString_to_char(NSString* str) { return ((const char* (*)(id, SEL)) objc_msgSend) (str, func); } +NSString* NSStringFromClass(id class) { + return NSString_stringWithUTF8String(class_getName((Class)class)); +} + +bool NSString_isEqualChar(NSString* str, const char* str2) { + return NSString_isEqual(str, NSString_stringWithUTF8String(str2)); +} + +bool NSString_isEqual(NSString* str, NSString* str2) { + void* func = SI_NS_FUNCTIONS[NS_STRING_IS_EQUAL_CODE]; + return ((bool (*)(id, SEL, id)) objc_msgSend) (str, func, str2); +} + const char* NSDictionary_objectForKey(NSDictionary* d, const char* str) { void* func = SI_NS_FUNCTIONS[NS_OBJECT_FOR_KEY_CODE]; @@ -3103,7 +3164,7 @@ NSUInteger NSArray_count(NSArray* array) { void* NSArray_objectAtIndex(NSArray* array, NSUInteger index) { void* func = SI_NS_FUNCTIONS[NS_OBJECT_AT_INDEX_CODE]; - return ((id (*)(id, SEL, NSUInteger))objc_msgSend)(SI_NS_CLASSES[NS_STRING_CODE], func, index); + return ((id (*)(id, SEL, NSUInteger))objc_msgSend)(array, func, index); } id NSAutoRelease(id obj) { return (id)objc_msgSend_id(obj, SI_NS_FUNCTIONS[NS_AUTORELEASE_CODE]); } @@ -3178,6 +3239,25 @@ void si_array_free(siArray(void) array) { free(SI_ARRAY_HEADER(array)); } + +#undef NSSearchPathForDirectoriesInDomains + +NSArray* NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde); + +siArray(const char*) _NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, bool expandTilde) { + NSArray* output = NSSearchPathForDirectoriesInDomains(directory, domainMask, expandTilde); + + NSUInteger count = NSArray_count(output); + siArray(const char*) res = si_array_init_reserve(si_sizeof(const char*), count); + + for (NSUInteger i = 0; i < count; i++) + res[i] = NSString_to_char(NSArray_objectAtIndex(output, i)); + + return res; +} + +#define NSSearchPathForDirectoriesInDomains _NSSearchPathForDirectoriesInDomains + #endif #endif /* SILICON_IMPLEMENTATION */ \ No newline at end of file