From 3ae40c35e685a19c2ddfe2e5ddcadc2571b8f322 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 16 Jun 2021 14:09:28 +0200 Subject: [PATCH 01/30] Update examples_template.c --- examples/examples_template.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/examples_template.c b/examples/examples_template.c index 8dc31706d..f17411045 100644 --- a/examples/examples_template.c +++ b/examples/examples_template.c @@ -41,16 +41,18 @@ * * raylib [core] example - Basic window * -* This example has been created using raylib 2.5 (www.raylib.com) +* This example has been created using raylib 3.8 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2019 Ramon Santamaria (@raysan5) +* Example contributed by (@) and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2021 (@) * ********************************************************************************************/ #include "raylib.h" -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- From f3d38018cdc306503b7533bfe3a9f1f70ed7edc4 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 00:03:24 +0200 Subject: [PATCH 02/30] Comment tweak --- src/raymath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raymath.h b/src/raymath.h index 6ab666e51..55ca14e80 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -138,7 +138,7 @@ typedef struct float3 { float v[3]; } float3; typedef struct float16 { float v[16]; } float16; -#include // Required for: sinf(), cosf(), sqrtf(), tan(), fabs() +#include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), fminf(), fmaxf(), fabs() //---------------------------------------------------------------------------------- // Module Functions Definition - Utils math From 4decbb258617f67c6b3122412fe1c698507b1331 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 00:04:24 +0200 Subject: [PATCH 03/30] RENAMED: MeshTangents() -> GenMeshTangents() RENAMED: MeshBinormals() -> GenMeshBinormals() --- src/models.c | 4 ++-- src/raylib.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/models.c b/src/models.c index 09cd431ce..f9dec64f2 100644 --- a/src/models.c +++ b/src/models.c @@ -2646,7 +2646,7 @@ BoundingBox GetMeshBoundingBox(Mesh mesh) // Compute mesh tangents // NOTE: To calculate mesh tangents and binormals we need mesh vertex positions and texture coordinates // Implementation base don: https://answers.unity.com/questions/7789/calculating-tangents-vector4.html -void MeshTangents(Mesh *mesh) +void GenMeshTangents(Mesh *mesh) { if (mesh->tangents == NULL) mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float)); else TRACELOG(LOG_WARNING, "MESH: Tangents data already available, re-writting"); @@ -2726,7 +2726,7 @@ void MeshTangents(Mesh *mesh) } // Compute mesh binormals (aka bitangent) -void MeshBinormals(Mesh *mesh) +void GenMeshBinormals(Mesh *mesh) { for (int i = 0; i < mesh->vertexCount; i++) { diff --git a/src/raylib.h b/src/raylib.h index cedf4f5dc..661c4c093 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1435,8 +1435,8 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Mesh manipulation functions RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits -RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents -RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals +RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents +RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals // Model drawing functions RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) From 942657fc7c8ea0cbabb15b3f1952c6364ce29c5e Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 00:28:51 +0200 Subject: [PATCH 04/30] Remove Color struct requirement --- src/rlgl.h | 74 +++++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index 4b88e09df..662ec8344 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -297,14 +297,6 @@ typedef struct RenderBatch { typedef enum { false, true } bool; #endif - // Color, 4 components, R8G8B8A8 (32bit) - typedef struct Color { - unsigned char r; // Color red value - unsigned char g; // Color green value - unsigned char b; // Color blue value - unsigned char a; // Color alpha value - } Color; - // Texture type // NOTE: Data stored in GPU memory typedef struct Texture2D { @@ -880,8 +872,8 @@ static char *rlGetCompressedFormatName(int format); // Get compressed format off #endif // SUPPORT_GL_DETAILS_INFO #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 #if defined(GRAPHICS_API_OPENGL_11) -static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side -static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side +static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side +static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side #endif static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) @@ -3957,22 +3949,20 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei width = baseWidth; height = baseHeight; - size = (width*height*4); + size = (width*height*4); // RGBA: 4 bytes // Generate mipmaps - // NOTE: Every mipmap data is stored after data - Color *image = (Color *)RL_MALLOC(width*height*sizeof(Color)); - Color *mipmap = NULL; + // NOTE: Every mipmap data is stored after data (RGBA - 4 bytes) + unsigned char *image = (unsigned char *)RL_MALLOC(width*height*4); + unsigned char *mipmap = NULL; int offset = 0; - int j = 0; for (int i = 0; i < size; i += 4) { - image[j].r = data[i]; - image[j].g = data[i + 1]; - image[j].b = data[i + 2]; - image[j].a = data[i + 3]; - j++; + image[i] = data[i]; + image[i + 1] = data[i + 1]; + image[i + 2] = data[i + 2]; + image[i + 3] = data[i + 3]; } TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height); @@ -3982,7 +3972,6 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei mipmap = rlGenNextMipmapData(image, width, height); offset += (width*height*4); // Size of last mipmap - j = 0; width /= 2; height /= 2; @@ -3991,11 +3980,10 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei // Add mipmap to data for (int i = 0; i < size; i += 4) { - data[offset + i] = mipmap[j].r; - data[offset + i + 1] = mipmap[j].g; - data[offset + i + 2] = mipmap[j].b; - data[offset + i + 3] = mipmap[j].a; - j++; + data[offset + i] = mipmap[i]; + data[offset + i + 1] = mipmap[i + 1]; + data[offset + i + 2] = mipmap[i + 2]; + data[offset + i + 3] = mipmap[i + 3]; } RL_FREE(image); @@ -4010,15 +3998,17 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei } // Manual mipmap generation (basic scaling algorithm) -static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight) +static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight) { - int x2, y2; - Color prow, pcol; + int x2 = 0; + int y2 = 0; + unsigned char prow[4]; + unsigned char pcol[4]; int width = srcWidth/2; int height = srcHeight/2; - Color *mipmap = (Color *)RL_MALLOC(width*height*sizeof(Color)); + unsigned char *mipmap = (unsigned char *)RL_MALLOC(width*height*4); // Scaling algorithm works perfectly (box-filter) for (int y = 0; y < height; y++) @@ -4029,20 +4019,20 @@ static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight) { x2 = 2*x; - prow.r = (srcData[y2*srcWidth + x2].r + srcData[y2*srcWidth + x2 + 1].r)/2; - prow.g = (srcData[y2*srcWidth + x2].g + srcData[y2*srcWidth + x2 + 1].g)/2; - prow.b = (srcData[y2*srcWidth + x2].b + srcData[y2*srcWidth + x2 + 1].b)/2; - prow.a = (srcData[y2*srcWidth + x2].a + srcData[y2*srcWidth + x2 + 1].a)/2; + prow[0] = (srcData[(y2*srcWidth + x2)*4 + 0] + srcData[(y2*srcWidth + x2 + 1)*4 + 0])/2; + prow[1] = (srcData[(y2*srcWidth + x2)*4 + 1] + srcData[(y2*srcWidth + x2 + 1)*4 + 1])/2; + prow[2] = (srcData[(y2*srcWidth + x2)*4 + 2] + srcData[(y2*srcWidth + x2 + 1)*4 + 2])/2; + prow[3] = (srcData[(y2*srcWidth + x2)*4 + 3] + srcData[(y2*srcWidth + x2 + 1)*4 + 3])/2; - pcol.r = (srcData[(y2+1)*srcWidth + x2].r + srcData[(y2+1)*srcWidth + x2 + 1].r)/2; - pcol.g = (srcData[(y2+1)*srcWidth + x2].g + srcData[(y2+1)*srcWidth + x2 + 1].g)/2; - pcol.b = (srcData[(y2+1)*srcWidth + x2].b + srcData[(y2+1)*srcWidth + x2 + 1].b)/2; - pcol.a = (srcData[(y2+1)*srcWidth + x2].a + srcData[(y2+1)*srcWidth + x2 + 1].a)/2; + pcol[0] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 0] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 0])/2; + pcol[1] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 1] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 1])/2; + pcol[2] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 2] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 2])/2; + pcol[3] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 3] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 3])/2; - mipmap[y*width + x].r = (prow.r + pcol.r)/2; - mipmap[y*width + x].g = (prow.g + pcol.g)/2; - mipmap[y*width + x].b = (prow.b + pcol.b)/2; - mipmap[y*width + x].a = (prow.a + pcol.a)/2; + mipmap[(y*width + x)*4 + 0] = (prow[0] + pcol[0])/2; + mipmap[(y*width + x)*4 + 1] = (prow[1] + pcol[1])/2; + mipmap[(y*width + x)*4 + 2] = (prow[2] + pcol[2])/2; + mipmap[(y*width + x)*4 + 3] = (prow[3] + pcol[3])/2; } } From 68e408474d3a2e469cd8ce88208fffdb3e81dc47 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 11:17:39 +0200 Subject: [PATCH 05/30] Renamed SUPPORT_MOUSE_CURSOR_NATIVE -> SUPPORT_MOUSE_CURSOR_POINT --- src/config.h | 2 +- src/core.c | 31 ++++++++++++++++--------------- src/models.c | 4 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/config.h b/src/config.h index 7c4777af6..c277e5ddf 100644 --- a/src/config.h +++ b/src/config.h @@ -37,7 +37,7 @@ // Reconfigure standard input to receive key inputs, works with SSH connection. #define SUPPORT_SSH_KEYBOARD_RPI 1 // Draw a mouse pointer on screen -#define SUPPORT_MOUSE_CURSOR_NATIVE 1 +#define SUPPORT_MOUSE_CURSOR_POINT 1 // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. #define SUPPORT_WINMM_HIGHRES_TIMER 1 diff --git a/src/core.c b/src/core.c index 77a8d47e7..a6d7a27e8 100644 --- a/src/core.c +++ b/src/core.c @@ -56,7 +56,7 @@ * WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other running processes or * blocking the device is not restored properly. Use with care. * -* #define SUPPORT_MOUSE_CURSOR_NATIVE (Raspberry Pi and DRM only) +* #define SUPPORT_MOUSE_CURSOR_POINT * Draw a mouse pointer on screen * * #define SUPPORT_BUSY_WAIT_LOOP @@ -387,7 +387,7 @@ typedef struct CoreData { Point position; // Window position on screen (required on fullscreen toggle) Size display; // Display width and height (monitor, device-screen, LCD, ...) Size screen; // Screen width and height (used render area) - Size currentFbo; // Current render width and height, it could change on BeginTextureMode() + Size currentFbo; // Current render width and height (depends on active fbo) Size render; // Framebuffer width and height (render area, including black bars if required) Point renderOffset; // Offset from render area (must be divided by 2) Matrix screenScale; // Matrix to scale screen (framebuffer rendering) @@ -1952,22 +1952,22 @@ void BeginDrawing(void) // End canvas drawing and swap buffers (double buffering) void EndDrawing(void) { -#if (defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) && defined(SUPPORT_MOUSE_CURSOR_NATIVE) - // On native mode we have no system mouse cursor, so, - // we draw a small rectangle for user reference + rlDrawRenderBatchActive(); // Update and draw internal render batch + +#if defined(SUPPORT_MOUSE_CURSOR_POINT) + // Draw a small rectangle on mouse position for user reference if (!CORE.Input.Mouse.cursorHidden) { DrawRectangle(CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y, 3, 3, MAROON); + rlDrawRenderBatchActive(); // Update and draw internal render batch } #endif - rlDrawRenderBatchActive(); // Update and draw internal render batch - #if defined(SUPPORT_GIF_RECORDING) - #define GIF_RECORD_FRAMERATE 10 - + // Draw record indicator if (gifRecording) { + #define GIF_RECORD_FRAMERATE 10 gifFramesCounter++; // NOTE: We record one gif frame every 10 game frames @@ -1992,6 +1992,7 @@ void EndDrawing(void) #endif #if defined(SUPPORT_EVENTS_AUTOMATION) + // Draw record/play indicator if (eventsRecording) { gifFramesCounter++; @@ -2018,8 +2019,8 @@ void EndDrawing(void) } #endif - SwapBuffers(); // Copy back buffer to front buffer - + SwapBuffers(); // Copy back buffer to front buffer (screen) + // Frame time control system CORE.Time.current = GetTime(); CORE.Time.draw = CORE.Time.current - CORE.Time.previous; @@ -2040,13 +2041,13 @@ void EndDrawing(void) } PollInputEvents(); // Poll user events - + #if defined(SUPPORT_EVENTS_AUTOMATION) + // Events recording and playing logic if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter); - - // TODO: When should we play? After/before/replace PollInputEvents()? - if (eventsPlaying) + else if (eventsPlaying) { + // TODO: When should we play? After/before/replace PollInputEvents()? if (CORE.Time.frameCounter >= eventCount) eventsPlaying = false; PlayAutomationEvent(CORE.Time.frameCounter); } diff --git a/src/models.c b/src/models.c index f9dec64f2..f566780ac 100644 --- a/src/models.c +++ b/src/models.c @@ -4800,7 +4800,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo // output->framerate = // TODO: Use framerate instead of const timestep // Name and parent bones - for (unsigned int j = 0; j < output->boneCount; j++) + for (int j = 0; j < output->boneCount; j++) { strcpy(output->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name); output->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1; @@ -4812,7 +4812,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo { output->framePoses[frame] = RL_MALLOC(output->boneCount*sizeof(Transform)); - for (unsigned int i = 0; i < output->boneCount; i++) + for (int i = 0; i < output->boneCount; i++) { output->framePoses[frame][i].translation = Vector3Zero(); output->framePoses[frame][i].rotation = QuaternionIdentity(); From ab032919df7fbc2c6f9e61dbd5a1b6765690dde2 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 11:47:05 +0200 Subject: [PATCH 06/30] RENAMED: Wait() -> WaitTime() --- src/core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core.c b/src/core.c index a6d7a27e8..5441ba506 100644 --- a/src/core.c +++ b/src/core.c @@ -605,7 +605,7 @@ static void SetupViewport(int width, int height); // Set viewport for a pr static void SwapBuffers(void); // Copy back buffer to front buffer static void InitTimer(void); // Initialize timer -static void Wait(float ms); // Wait for some milliseconds (stop program execution) +static void WaitTime(float ms); // Wait for some milliseconds (stop program execution) static void PollInputEvents(void); // Register user events @@ -673,7 +673,7 @@ static void PlayAutomationEvent(unsigned int frame); #if defined(_WIN32) // NOTE: We include Sleep() function signature here to avoid windows.h inclusion (kernel32 lib) - void __stdcall Sleep(unsigned long msTimeout); // Required for Wait() + void __stdcall Sleep(unsigned long msTimeout); // Required for WaitTime() #endif //---------------------------------------------------------------------------------- @@ -2031,7 +2031,7 @@ void EndDrawing(void) // Wait for some milliseconds... if (CORE.Time.frame < CORE.Time.target) { - Wait((float)(CORE.Time.target - CORE.Time.frame)*1000.0f); + WaitTime((float)(CORE.Time.target - CORE.Time.frame)*1000.0f); CORE.Time.current = GetTime(); double waitTime = CORE.Time.current - CORE.Time.previous; @@ -4690,7 +4690,7 @@ static void InitTimer(void) // take longer than expected... for that reason we use the busy wait loop // Ref: http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected // Ref: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timming on Win32! -static void Wait(float ms) +static void WaitTime(float ms) { #if defined(PLATFORM_UWP) UWPGetSleepFunc()(ms/1000); @@ -6328,7 +6328,8 @@ static void *EventThread(void *arg) #endif } } - Wait(5); // Sleep for 5ms to avoid hogging CPU time + + WaitTime(5); // Sleep for 5ms to avoid hogging CPU time } close(worker->fd); @@ -6416,7 +6417,7 @@ static void *GamepadThread(void *arg) } } } - else Wait(1); // Sleep for 1 ms to avoid hogging CPU time + else WaitTime(1); // Sleep for 1 ms to avoid hogging CPU time } } From 19b71f5f13ee6e343836732a80f56d241e6f1659 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 12:17:50 +0200 Subject: [PATCH 07/30] WARNING: Exposed `SUPPORT_CUSTOM_FRAME_CONTROL` #1729 --- src/config.h | 4 ++ src/core.c | 140 +++++++++++++++++++++++++-------------------------- src/raylib.h | 9 ++++ 3 files changed, 81 insertions(+), 72 deletions(-) diff --git a/src/config.h b/src/config.h index c277e5ddf..df34f8095 100644 --- a/src/config.h +++ b/src/config.h @@ -57,6 +57,10 @@ #define SUPPORT_DATA_STORAGE 1 // Support automatic generated events, loading and recording of those events when required #define SUPPORT_EVENTS_AUTOMATION 1 +// Support custom frame control, only for advance users +// By default EndDrawing() does this job: draws everything + SwapBuffers() + manage frame timming + PollInputEvents() +// Enabling this flag allows manual control of the frame processes, use at your own risk +//#define SUPPORT_CUSTOM_FRAME_CONTROL 1 // core: Configuration values //------------------------------------------------------------------------------------ diff --git a/src/core.c b/src/core.c index 5441ba506..a31120aa1 100644 --- a/src/core.c +++ b/src/core.c @@ -602,12 +602,6 @@ extern void UnloadFontDefault(void); // [Module: text] Unloads default fo static bool InitGraphicsDevice(int width, int height); // Initialize graphics device static void SetupFramebuffer(int width, int height); // Setup main framebuffer static void SetupViewport(int width, int height); // Set viewport for a provided width and height -static void SwapBuffers(void); // Copy back buffer to front buffer - -static void InitTimer(void); // Initialize timer -static void WaitTime(float ms); // Wait for some milliseconds (stop program execution) - -static void PollInputEvents(void); // Register user events #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error @@ -2019,6 +2013,7 @@ void EndDrawing(void) } #endif +#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) SwapBuffers(); // Copy back buffer to front buffer (screen) // Frame time control system @@ -2041,6 +2036,7 @@ void EndDrawing(void) } PollInputEvents(); // Poll user events +#endif #if defined(SUPPORT_EVENTS_AUTOMATION) // Events recording and playing logic @@ -4660,7 +4656,7 @@ static void SetupFramebuffer(int width, int height) } // Initialize hi-resolution timer -static void InitTimer(void) +void InitTimer(void) { srand((unsigned int)time(NULL)); // Initialize random seed @@ -4690,7 +4686,7 @@ static void InitTimer(void) // take longer than expected... for that reason we use the busy wait loop // Ref: http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected // Ref: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timming on Win32! -static void WaitTime(float ms) +void WaitTime(float ms) { #if defined(PLATFORM_UWP) UWPGetSleepFunc()(ms/1000); @@ -4738,8 +4734,70 @@ static void WaitTime(float ms) #endif } -// Poll (store) all input events -static void PollInputEvents(void) +// Swap back buffer with front buffer (screen drawing) +void SwapBuffers(void) +{ +#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) + glfwSwapBuffers(CORE.Window.handle); +#endif + +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) || defined(PLATFORM_UWP) + eglSwapBuffers(CORE.Window.device, CORE.Window.surface); + +#if defined(PLATFORM_DRM) + if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc) + { + TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap"); + abort(); + } + + struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface); + if (!bo) + { + TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer"); + abort(); + } + + uint32_t fb = 0; + int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, + CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb); + if (0 != result) + { + TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result); + abort(); + } + + result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0, + &CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]); + if (0 != result) + { + TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result); + abort(); + } + + if (CORE.Window.prevFB) + { + result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB); + if (0 != result) + { + TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result); + abort(); + } + } + CORE.Window.prevFB = fb; + + if (CORE.Window.prevBO) + { + gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO); + } + + CORE.Window.prevBO = bo; +#endif // PLATFORM_DRM +#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP +} + +// Register all input events +void PollInputEvents(void) { #if defined(SUPPORT_GESTURES_SYSTEM) // NOTE: Gestures update must be called every frame to reset gestures correctly @@ -5015,68 +5073,6 @@ static void PollInputEvents(void) #endif } -// Copy back buffer to front buffers -static void SwapBuffers(void) -{ -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) - glfwSwapBuffers(CORE.Window.handle); -#endif - -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) || defined(PLATFORM_UWP) - eglSwapBuffers(CORE.Window.device, CORE.Window.surface); - -#if defined(PLATFORM_DRM) - if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc) - { - TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap"); - abort(); - } - - struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface); - if (!bo) - { - TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer"); - abort(); - } - - uint32_t fb = 0; - int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, - CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb); - if (0 != result) - { - TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result); - abort(); - } - - result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0, - &CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]); - if (0 != result) - { - TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result); - abort(); - } - - if (CORE.Window.prevFB) - { - result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB); - if (0 != result) - { - TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result); - abort(); - } - } - CORE.Window.prevFB = fb; - - if (CORE.Window.prevBO) - { - gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO); - } - - CORE.Window.prevBO = bo; -#endif // PLATFORM_DRM -#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP -} - #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) // GLFW3 Error Callback, runs on GLFW3 error static void ErrorCallback(int error, const char *description) diff --git a/src/raylib.h b/src/raylib.h index 661c4c093..2559a9c01 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -960,6 +960,15 @@ RLAPI const char *GetMonitorName(int monitor); // Get the hum RLAPI void SetClipboardText(const char *text); // Set clipboard text content RLAPI const char *GetClipboardText(void); // Get clipboard text content +// Custom frame control functions +// NOTE: Those functions are intended for advance users that want full control over the frame processing +// By default EndDrawing() does this job: draws everything + SwapBuffers() + manage frame timming + PollInputEvents() +// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL +RLAPI void InitTimer(void); // Initialize timer (hi-resolution if available) +RLAPI void WaitTime(float ms); // Wait for some milliseconds (halt program execution) +RLAPI void SwapBuffers(void); // Swap back buffer with front buffer (screen drawing) +RLAPI void PollInputEvents(void); // Register all input events + // Cursor-related functions RLAPI void ShowCursor(void); // Shows cursor RLAPI void HideCursor(void); // Hides cursor From b733e76c869afcaee1e2f716bfd99b8b10ef507c Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 12:26:33 +0200 Subject: [PATCH 08/30] Update physac.h --- src/extras/physac.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/extras/physac.h b/src/extras/physac.h index 676a96953..834290bc4 100644 --- a/src/extras/physac.h +++ b/src/extras/physac.h @@ -318,7 +318,7 @@ static unsigned int usedMemory = 0; // Total allocated d //---------------------------------------------------------------------------------- #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM) // Timming measure functions -static void InitTimer(void); // Initializes hi-resolution MONOTONIC timer +static void InitTimerHiRes(void); // Initializes hi-resolution MONOTONIC timer static unsigned long long int GetClockTicks(void); // Get hi-res MONOTONIC time measure in mseconds static double GetCurrentTime(void); // Get current time measure in milliseconds #endif @@ -370,7 +370,7 @@ PHYSACDEF void InitPhysics(void) { #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM) // Initialize high resolution timer - InitTimer(); + InitTimerHiRes(); #endif TRACELOG("[PHYSAC] Physics module initialized successfully\n"); @@ -1848,7 +1848,7 @@ static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3) #if !defined(PHYSAC_AVOID_TIMMING_SYSTEM) // Initializes hi-resolution MONOTONIC timer -static void InitTimer(void) +static void InitTimerHiRes(void) { #if defined(_WIN32) QueryPerformanceFrequency((unsigned long long int *) &frequency); From e07054d0d48161b31375ad83c6e505553bf8f204 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 12:47:03 +0200 Subject: [PATCH 09/30] RENAMED: `SwapBuffers()` -> `SwapScreenBuffer()` Avoid possible symbol collisions --- src/config.h | 2 +- src/core.c | 4 ++-- src/raylib.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config.h b/src/config.h index df34f8095..7edac306b 100644 --- a/src/config.h +++ b/src/config.h @@ -58,7 +58,7 @@ // Support automatic generated events, loading and recording of those events when required #define SUPPORT_EVENTS_AUTOMATION 1 // Support custom frame control, only for advance users -// By default EndDrawing() does this job: draws everything + SwapBuffers() + manage frame timming + PollInputEvents() +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents() // Enabling this flag allows manual control of the frame processes, use at your own risk //#define SUPPORT_CUSTOM_FRAME_CONTROL 1 diff --git a/src/core.c b/src/core.c index a31120aa1..887b57b16 100644 --- a/src/core.c +++ b/src/core.c @@ -2014,7 +2014,7 @@ void EndDrawing(void) #endif #if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) - SwapBuffers(); // Copy back buffer to front buffer (screen) + SwapScreenBuffer(); // Copy back buffer to front buffer (screen) // Frame time control system CORE.Time.current = GetTime(); @@ -4735,7 +4735,7 @@ void WaitTime(float ms) } // Swap back buffer with front buffer (screen drawing) -void SwapBuffers(void) +void SwapScreenBuffer(void) { #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) glfwSwapBuffers(CORE.Window.handle); diff --git a/src/raylib.h b/src/raylib.h index 2559a9c01..ce589bda2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -962,11 +962,11 @@ RLAPI const char *GetClipboardText(void); // Get clipboa // Custom frame control functions // NOTE: Those functions are intended for advance users that want full control over the frame processing -// By default EndDrawing() does this job: draws everything + SwapBuffers() + manage frame timming + PollInputEvents() +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents() // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL RLAPI void InitTimer(void); // Initialize timer (hi-resolution if available) RLAPI void WaitTime(float ms); // Wait for some milliseconds (halt program execution) -RLAPI void SwapBuffers(void); // Swap back buffer with front buffer (screen drawing) +RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) RLAPI void PollInputEvents(void); // Register all input events // Cursor-related functions From 0e65e5877fc0fc5a9246ee14a7341be462b7a761 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 12:54:05 +0200 Subject: [PATCH 10/30] Update rlgl_standalone.c --- examples/others/rlgl_standalone.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/others/rlgl_standalone.c b/examples/others/rlgl_standalone.c index 47233afd8..f30889039 100644 --- a/examples/others/rlgl_standalone.c +++ b/examples/others/rlgl_standalone.c @@ -65,6 +65,14 @@ #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray +// Color, 4 components, R8G8B8A8 (32bit) +typedef struct Color { + unsigned char r; // Color red value + unsigned char g; // Color green value + unsigned char b; // Color blue value + unsigned char a; // Color alpha value +} Color; + // Camera type, defines a camera position/orientation in 3d space typedef struct Camera { Vector3 position; // Camera position From 1a420b77e30a444e66dded47fcd1988b90fb2185 Mon Sep 17 00:00:00 2001 From: Sirvoid Date: Thu, 17 Jun 2021 09:42:37 -0400 Subject: [PATCH 11/30] Fixed: Binding vertex position twice (#1835) --- src/models.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/models.c b/src/models.c index f566780ac..b243a45e7 100644 --- a/src/models.c +++ b/src/models.c @@ -1099,10 +1099,6 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0); rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]); - rlEnableVertexBuffer(mesh.vboId[0]); - rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0); - rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]); - // Bind mesh VBO data: vertex texcoords (shader-location = 1) rlEnableVertexBuffer(mesh.vboId[1]); rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0); From 8be5ec2288a71c80c703a48fcc4f75a9efd917e0 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 17 Jun 2021 18:18:16 +0200 Subject: [PATCH 12/30] Avoid SUPPORT_MOUSE_CURSOR_POINT --- src/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.h b/src/config.h index 7edac306b..b90b81b3a 100644 --- a/src/config.h +++ b/src/config.h @@ -37,7 +37,7 @@ // Reconfigure standard input to receive key inputs, works with SSH connection. #define SUPPORT_SSH_KEYBOARD_RPI 1 // Draw a mouse pointer on screen -#define SUPPORT_MOUSE_CURSOR_POINT 1 +//#define SUPPORT_MOUSE_CURSOR_POINT 1 // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. #define SUPPORT_WINMM_HIGHRES_TIMER 1 From c37f776e87ff948ec81011a7707ad0fd59b3a0f0 Mon Sep 17 00:00:00 2001 From: PtitLuca <61348595+PtitLuca@users.noreply.github.com> Date: Fri, 18 Jun 2021 13:11:10 +0200 Subject: [PATCH 13/30] fix: change relevant occurences of MeshBoundingBox to GetMeshBoundingBox (#1836) --- projects/Geany/raylib.c.tags | 2 +- projects/Notepad++/c_raylib.xml | 2 +- projects/Notepad++/raylib_npp_parser/raylib_npp.xml | 2 +- projects/Notepad++/raylib_npp_parser/raylib_to_parse.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/Geany/raylib.c.tags b/projects/Geany/raylib.c.tags index 1b47efdd7..78e6e7241 100644 --- a/projects/Geany/raylib.c.tags +++ b/projects/Geany/raylib.c.tags @@ -298,7 +298,7 @@ GenMeshTorus|Mesh|(float radius, float size, int radSeg, int sides);| GenMeshKnot|Mesh|(float radius, float size, int radSeg, int sides);| GenMeshHeightmap|Mesh|(Image heightmap, Vector3 size);| GenMeshCubicmap|Mesh|(Image cubicmap, Vector3 cubeSize);| -MeshBoundingBox|BoundingBox|(Mesh mesh);| +GetMeshBoundingBox|BoundingBox|(Mesh mesh);| MeshTangents|void|(Mesh *mesh);| MeshBinormals|void|(Mesh *mesh);| DrawModel|void|(Model model, Vector3 position, float scale, Color tint);| diff --git a/projects/Notepad++/c_raylib.xml b/projects/Notepad++/c_raylib.xml index 8deab87ef..497fb7b82 100644 --- a/projects/Notepad++/c_raylib.xml +++ b/projects/Notepad++/c_raylib.xml @@ -1549,7 +1549,7 @@ - + diff --git a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml index 2c8bafb5e..b59fed57f 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_npp.xml +++ b/projects/Notepad++/raylib_npp_parser/raylib_npp.xml @@ -2495,7 +2495,7 @@ - + diff --git a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h index 8079f5c78..f7f252975 100644 --- a/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h +++ b/projects/Notepad++/raylib_npp_parser/raylib_to_parse.h @@ -515,7 +515,7 @@ RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data // Mesh manipulation functions -RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits +RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals From 28093c46a8d264206936d2eb534c56173346020b Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 19 Jun 2021 19:54:36 +0200 Subject: [PATCH 14/30] Disable `SUPPORT_EVENTS_AUTOMATION` by default --- src/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.h b/src/config.h index b90b81b3a..3ca160320 100644 --- a/src/config.h +++ b/src/config.h @@ -56,7 +56,7 @@ // Support saving binary data automatically to a generated storage.data file. This file is managed internally. #define SUPPORT_DATA_STORAGE 1 // Support automatic generated events, loading and recording of those events when required -#define SUPPORT_EVENTS_AUTOMATION 1 +//#define SUPPORT_EVENTS_AUTOMATION 1 // Support custom frame control, only for advance users // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents() // Enabling this flag allows manual control of the frame processes, use at your own risk From 96d5dd24aa8054c0daebb495bea25a2da0a7340e Mon Sep 17 00:00:00 2001 From: Adrian Guerrero Vera Date: Mon, 21 Jun 2021 00:11:27 +0200 Subject: [PATCH 15/30] core: added `GetMouseDelta()` (#1832) * core: added `GetMouseDelta()` Thanks to previousPosition added by raysan it is now possible to create the GetMouseDelta() function. Returns a Vector2 with the difference between the current and previous position of the mouse in a frame. Useful for creating camera scrolling, among others. * Added changes noted by raysan --- src/core.c | 11 +++++++++++ src/raylib.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/core.c b/src/core.c index 887b57b16..149dad048 100644 --- a/src/core.c +++ b/src/core.c @@ -3537,6 +3537,17 @@ Vector2 GetMousePosition(void) return position; } +// Get mouse delta between frames +Vector2 GetMouseDelta(void) +{ + Vector2 delta = {0}; + + delta.x = CORE.Input.Mouse.currentPosition.x - CORE.Input.Mouse.previousPosition.x; + delta.y = CORE.Input.Mouse.currentPosition.y - CORE.Input.Mouse.previousPosition.y; + + return delta; +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/raylib.h b/src/raylib.h index ce589bda2..515654210 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1113,6 +1113,7 @@ RLAPI bool IsMouseButtonUp(int button); // Check if a mous RLAPI int GetMouseX(void); // Get mouse position X RLAPI int GetMouseY(void); // Get mouse position Y RLAPI Vector2 GetMousePosition(void); // Get mouse position XY +RLAPI Vector2 GetMouseDelta(void); // Get mouse delta between frames RLAPI void SetMousePosition(int x, int y); // Set mouse position XY RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling From 115cc7dede289f3af0dd2b1b4f47dd8fe26014b9 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 21 Jun 2021 00:46:30 +0200 Subject: [PATCH 16/30] Review GetFPS() --- src/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core.c b/src/core.c index 149dad048..e88ee08ac 100644 --- a/src/core.c +++ b/src/core.c @@ -2635,6 +2635,9 @@ void SetTargetFPS(int fps) // NOTE: We calculate an average framerate int GetFPS(void) { + int fps = 0; + +#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) #define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures #define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes #define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT) @@ -2654,8 +2657,11 @@ int GetFPS(void) history[index] = fpsFrame/FPS_CAPTURE_FRAMES_COUNT; average += history[index]; } + + fps = (int)roundf(1.0f/average); +#endif - return (int)roundf(1.0f/average); + return fps; } // Get time in seconds for last frame drawn (delta time) From 906c7f591e3313a97479caa35c2006501b888fde Mon Sep 17 00:00:00 2001 From: FSasquatch <74960320+ForeignSasquatch@users.noreply.github.com> Date: Tue, 22 Jun 2021 21:37:47 +0530 Subject: [PATCH 17/30] Added hxRaylib (#1846) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index 886b8e67c..1c66f495c 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -64,6 +64,7 @@ Here it is a list with the ones I'm aware of: | raylib-factor | 3.5 | [Factor](https://factorcode.org/) | https://github.com/ArnautDaniel/raylib-factor | | gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | https://github.com/ArnautDaniel/gforth-raylib | | raylib-haxe | 2.4 | [Haxe](https://haxe.org/) | https://github.com/ibilon/raylib-haxe | +| hxRaylib | 3.7 | [Haxe](https://haxe.org/) | https://github.com/ForeignSasquatch/hxRaylib | | ringraylib | 2.6 | [Ring](http://ring-lang.sourceforge.net/) | https://github.com/ringpackages/ringraylib | | cl-raylib | 3.0 | [Common Lisp](https://common-lisp.net/) | https://github.com/longlene/cl-raylib | | raylib-scm | 2.5 | [Chicken Scheme](https://www.call-cc.org/) | https://github.com/yashrk/raylib-scm | From 52f1c7df6d6743a9078b9d56f68770b40c02b2db Mon Sep 17 00:00:00 2001 From: Guillaume DEVOILLE Date: Tue, 22 Jun 2021 18:12:42 +0200 Subject: [PATCH 18/30] Fix missing fclose in tinyobj loader (#1842) Missing fclose in tinyobj loader. --- src/external/tinyobj_loader_c.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/external/tinyobj_loader_c.h b/src/external/tinyobj_loader_c.h index 6bd63fceb..6d34d25f7 100644 --- a/src/external/tinyobj_loader_c.h +++ b/src/external/tinyobj_loader_c.h @@ -948,6 +948,8 @@ static int tinyobj_parse_and_index_mtl_file(tinyobj_material_t **materials_out, /* @todo { unknown parameter } */ } + fclose(fp); + if (material.name) { /* Flush last material element */ materials = tinyobj_material_add(materials, num_materials, &material); From 30a0f6f2925fa287719e9825437230361bb26125 Mon Sep 17 00:00:00 2001 From: Diesirae <15613425+n67094@users.noreply.github.com> Date: Tue, 22 Jun 2021 18:16:04 +0200 Subject: [PATCH 19/30] Fix DrawTextRec (#1843) * fix text wrapping * fix indent * fix indent * fix indent * fix DrawTextRec --- src/text.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/text.c b/src/text.c index e18afe41e..a5e871213 100644 --- a/src/text.c +++ b/src/text.c @@ -901,10 +901,10 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f { int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop - int textOffsetY = 0; // Offset between lines (on line break '\n') + float textOffsetY = 0; // Offset between lines (on line break '\n') float textOffsetX = 0.0f; // Offset X to next character to draw - float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor + float scaleFactor = fontSize/(float)font.baseSize; // Character quad scaling factor // Word/character wrapping mechanism variables enum { MEASURE_STATE = 0, DRAW_STATE = 1 }; @@ -926,12 +926,13 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f if (codepoint == 0x3f) codepointByteCount = 1; i += (codepointByteCount - 1); - int glyphWidth = 0; + float glyphWidth = 0; if (codepoint != '\n') { - glyphWidth = (font.chars[index].advanceX == 0)? - (int)(font.recs[index].width*scaleFactor + spacing): - (int)(font.chars[index].advanceX*scaleFactor + spacing); + glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width * scaleFactor : font.chars[index].advanceX * scaleFactor; + + if (i + 1 < length) + glyphWidth = glyphWidth + spacing; } // NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container @@ -945,7 +946,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f // Ref: http://jkorpela.fi/chars/spaces.html if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i; - if ((textOffsetX + glyphWidth + 1) >= rec.width) + if ((textOffsetX + glyphWidth) > rec.width) { endLine = (endLine < 1)? i : endLine; if (i == endLine) endLine -= codepointByteCount; @@ -956,7 +957,6 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f else if ((i + 1) == length) { endLine = i; - state = !state; } else if (codepoint == '\n') state = !state; @@ -979,26 +979,26 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f { if (!wordWrap) { - textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor); + textOffsetY += (font.baseSize + font.baseSize / 2) * scaleFactor; textOffsetX = 0; } } else { - if (!wordWrap && ((textOffsetX + glyphWidth + 1) >= rec.width)) + if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) { - textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor); + textOffsetY += (font.baseSize + font.baseSize / 2) * scaleFactor; textOffsetX = 0; } // When text overflows rectangle height limit, just stop drawing - if ((textOffsetY + (int)(font.baseSize*scaleFactor)) > rec.height) break; + if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break; // Draw selection background bool isGlyphSelected = false; if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength))) { - DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, (float)glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint); + DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize * scaleFactor }, selectBackTint); isGlyphSelected = true; } @@ -1011,7 +1011,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f if (wordWrap && (i == endLine)) { - textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor); + textOffsetY += (font.baseSize + font.baseSize / 2) * scaleFactor; textOffsetX = 0; startLine = endLine; endLine = -1; From 9095dd9e82b6be2b4ab477deaea6fe4634d1583c Mon Sep 17 00:00:00 2001 From: Sky Date: Tue, 22 Jun 2021 09:25:52 -0700 Subject: [PATCH 20/30] Add support for resizing Emscripten canvas (#1840) --- src/core.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/core.c b/src/core.c index e88ee08ac..9bf9837b3 100644 --- a/src/core.c +++ b/src/core.c @@ -630,6 +630,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #if defined(PLATFORM_WEB) static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); +static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData); + #endif #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) @@ -869,10 +871,14 @@ void InitWindow(int width, int height, const char *title) #endif #if defined(PLATFORM_WEB) - // Check fullscreen change events - //emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback); - //emscripten_set_resize_callback("#canvas", NULL, 1, EmscriptenResizeCallback); - + // Check fullscreen change events(note this is done on the window since most + // browsers don't support this on #canvas) + emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); + // Check Resize event (note this is done on the window since most browsers + // don't support this on #canvas) + emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); + // Trigger this once to get initial window sizing + EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); // Support keyboard events //emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); //emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); @@ -5096,8 +5102,33 @@ static void ErrorCallback(int error, const char *description) { TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description); } +#if defined(PLATFORM_WEB) +EM_JS(int, CanvasGetWidth, (), { return canvas.clientWidth; }); +EM_JS(int, CanvasGetHeight, (), { return canvas.clientHeight; }); +static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData) +{ + // Don't resize non-resizeable windows + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) return true; + // This event is called whenever the window changes sizes, so the size of + // the canvas object is explicitly retrieved below + int width = CanvasGetWidth(); + int height = CanvasGetHeight(); + emscripten_set_canvas_element_size("#canvas",width,height); + + SetupViewport(width, height); // Reset viewport and projection matrix for new size + CORE.Window.currentFbo.width = width; + CORE.Window.currentFbo.height = height; + CORE.Window.resizedLastFrame = true; + if (IsWindowFullscreen()) return true; + + // Set current screen size + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + // NOTE: Postprocessing texture is not scaled to new size +} +#endif // GLFW3 WindowSize Callback, runs when window is resizedLastFrame // NOTE: Window resizing not allowed by default static void WindowSizeCallback(GLFWwindow *window, int width, int height) From 2efb50cc63155af0e2ce8fbaf58aecc77b1b9485 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Jun 2021 20:01:57 +0200 Subject: [PATCH 21/30] Update .gitignore --- .gitignore | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.gitignore b/.gitignore index 49e296e73..a1ca6c009 100644 --- a/.gitignore +++ b/.gitignore @@ -53,17 +53,6 @@ packages/ *.bc *.so -# Ignore all examples files -examples/* -# Unignore all examples files with extension -!examples/*.c -!examples/*.png -# Unignore examples Makefile -!examples/Makefile -!examples/Makefile.Android -!examples/raylib_compile_execute.bat -!examples/raylib_makefile_example.bat - # Ignore files build by xcode *.mode*v* *.pbxuser @@ -93,9 +82,6 @@ compile_commands.json CTestTestfile.cmake build -# Unignore These makefiles... -!examples/CMakeLists.txt - # Ignore GNU global tags GPATH GRTAGS From 7f2a071c5168daf0bf8c7ebbf73d75ba1833bb38 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Jun 2021 20:14:44 +0200 Subject: [PATCH 22/30] Formatting review --- src/core.c | 35 ++++++++++++++++++++--------------- src/raylib.h | 2 +- src/shapes.c | 2 +- src/text.c | 15 +++++++-------- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/core.c b/src/core.c index 9bf9837b3..41ef4b4fa 100644 --- a/src/core.c +++ b/src/core.c @@ -1953,7 +1953,7 @@ void BeginDrawing(void) void EndDrawing(void) { rlDrawRenderBatchActive(); // Update and draw internal render batch - + #if defined(SUPPORT_MOUSE_CURSOR_POINT) // Draw a small rectangle on mouse position for user reference if (!CORE.Input.Mouse.cursorHidden) @@ -2021,7 +2021,7 @@ void EndDrawing(void) #if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) SwapScreenBuffer(); // Copy back buffer to front buffer (screen) - + // Frame time control system CORE.Time.current = GetTime(); CORE.Time.draw = CORE.Time.current - CORE.Time.previous; @@ -2043,7 +2043,7 @@ void EndDrawing(void) PollInputEvents(); // Poll user events #endif - + #if defined(SUPPORT_EVENTS_AUTOMATION) // Events recording and playing logic if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter); @@ -2642,8 +2642,8 @@ void SetTargetFPS(int fps) int GetFPS(void) { int fps = 0; - -#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) + +#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL) #define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures #define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes #define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT) @@ -2663,7 +2663,7 @@ int GetFPS(void) history[index] = fpsFrame/FPS_CAPTURE_FRAMES_COUNT; average += history[index]; } - + fps = (int)roundf(1.0f/average); #endif @@ -5102,19 +5102,22 @@ static void ErrorCallback(int error, const char *description) { TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description); } + #if defined(PLATFORM_WEB) -EM_JS(int, CanvasGetWidth, (), { return canvas.clientWidth; }); -EM_JS(int, CanvasGetHeight, (), { return canvas.clientHeight; }); +EM_JS(int, GetCanvasWidth, (), { return canvas.clientWidth; }); +EM_JS(int, GetCanvasHeight, (), { return canvas.clientHeight; }); + static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData) { // Don't resize non-resizeable windows if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) return true; - // This event is called whenever the window changes sizes, so the size of - // the canvas object is explicitly retrieved below - int width = CanvasGetWidth(); - int height = CanvasGetHeight(); + + // This event is called whenever the window changes sizes, + // so the size of the canvas object is explicitly retrieved below + int width = GetCanvasWidth(); + int height = GetCanvasHeight(); emscripten_set_canvas_element_size("#canvas",width,height); - + SetupViewport(width, height); // Reset viewport and projection matrix for new size CORE.Window.currentFbo.width = width; @@ -5126,9 +5129,11 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * // Set current screen size CORE.Window.screen.width = width; CORE.Window.screen.height = height; + // NOTE: Postprocessing texture is not scaled to new size } -#endif +#endif + // GLFW3 WindowSize Callback, runs when window is resizedLastFrame // NOTE: Window resizing not allowed by default static void WindowSizeCallback(GLFWwindow *window, int width, int height) @@ -6875,7 +6880,7 @@ static void LoadAutomationEvents(const char *fileName) { sscanf(buffer, "e %d %d %d %d %d", &events[count].frame, &events[count].type, &events[count].params[0], &events[count].params[1], &events[count].params[2]); - + count++; } diff --git a/src/raylib.h b/src/raylib.h index 515654210..020af5274 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -222,7 +222,7 @@ typedef struct Color { // Rectangle, 4 components typedef struct Rectangle { - float x; // Rectangle top-left corner position x + float x; // Rectangle top-left corner position x float y; // Rectangle top-left corner position y float width; // Rectangle width float height; // Rectangle height diff --git a/src/shapes.c b/src/shapes.c index 788c3c830..98852bc8c 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -1645,7 +1645,7 @@ bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshol if (fabsf(dxl) >= fabsf(dyl)) collision = (dxl > 0)? ((p1.x <= point.x) && (point.x <= p2.x)) : ((p2.x <= point.x) && (point.x <= p1.x)); else collision = (dyl > 0)? ((p1.y <= point.y) && (point.y <= p2.y)) : ((p2.y <= point.y) && (point.y <= p1.y)); } - + return collision; } diff --git a/src/text.c b/src/text.c index a5e871213..65460d808 100644 --- a/src/text.c +++ b/src/text.c @@ -929,10 +929,9 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f float glyphWidth = 0; if (codepoint != '\n') { - glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width * scaleFactor : font.chars[index].advanceX * scaleFactor; - - if (i + 1 < length) - glyphWidth = glyphWidth + spacing; + glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor; + + if (i + 1 < length) glyphWidth = glyphWidth + spacing; } // NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container @@ -979,7 +978,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f { if (!wordWrap) { - textOffsetY += (font.baseSize + font.baseSize / 2) * scaleFactor; + textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetX = 0; } } @@ -987,7 +986,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f { if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) { - textOffsetY += (font.baseSize + font.baseSize / 2) * scaleFactor; + textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetX = 0; } @@ -998,7 +997,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f bool isGlyphSelected = false; if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength))) { - DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize * scaleFactor }, selectBackTint); + DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint); isGlyphSelected = true; } @@ -1011,7 +1010,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f if (wordWrap && (i == endLine)) { - textOffsetY += (font.baseSize + font.baseSize / 2) * scaleFactor; + textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; textOffsetX = 0; startLine = endLine; endLine = -1; From 429c5a9a9add32b470115e8cd9e38aa811546e69 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Jun 2021 20:26:59 +0200 Subject: [PATCH 23/30] Review and un-expose InitTimer() Actually it's not required for SUPPORT_CUSTOM_FRAME_CONTROL --- src/core.c | 11 ++++++++--- src/raylib.h | 3 +-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core.c b/src/core.c index 41ef4b4fa..38e6a5e7b 100644 --- a/src/core.c +++ b/src/core.c @@ -599,6 +599,7 @@ extern void UnloadFontDefault(void); // [Module: text] Unloads default fo //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- +static void InitTimer(void); // Initialize timer (hi-resolution if available) static bool InitGraphicsDevice(int width, int height); // Initialize graphics device static void SetupFramebuffer(int width, int height); // Setup main framebuffer static void SetupViewport(int width, int height); // Set viewport for a provided width and height @@ -839,6 +840,9 @@ void InitWindow(int width, int height, const char *title) // Init hi-res timer InitTimer(); + + // Initialize random seed + srand((unsigned int)time(NULL)); #if defined(SUPPORT_DEFAULT_FONT) // Load default font @@ -4679,10 +4683,8 @@ static void SetupFramebuffer(int width, int height) } // Initialize hi-resolution timer -void InitTimer(void) +static void InitTimer(void) { - srand((unsigned int)time(NULL)); // Initialize random seed - // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. // High resolutions can also prevent the CPU power management system from entering power-saving modes. @@ -5424,6 +5426,9 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Init hi-res timer InitTimer(); + + // Initialize random seed + srand((unsigned int)time(NULL)); #if defined(SUPPORT_DEFAULT_FONT) // Load default font diff --git a/src/raylib.h b/src/raylib.h index 020af5274..ea3dc6938 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -964,10 +964,9 @@ RLAPI const char *GetClipboardText(void); // Get clipboa // NOTE: Those functions are intended for advance users that want full control over the frame processing // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents() // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL -RLAPI void InitTimer(void); // Initialize timer (hi-resolution if available) -RLAPI void WaitTime(float ms); // Wait for some milliseconds (halt program execution) RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) RLAPI void PollInputEvents(void); // Register all input events +RLAPI void WaitTime(float ms); // Wait for some milliseconds (halt program execution) // Cursor-related functions RLAPI void ShowCursor(void); // Shows cursor From 6f60622619ed3b2606cc186d9d87cfe15e665e75 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Jun 2021 21:20:14 +0200 Subject: [PATCH 24/30] ADDED: Example: core_custom_frame_control --- examples/core/core_custom_frame_control.c | 126 ++++++++++++++++++++ examples/core/core_custom_frame_control.png | Bin 0 -> 16952 bytes 2 files changed, 126 insertions(+) create mode 100644 examples/core/core_custom_frame_control.c create mode 100644 examples/core/core_custom_frame_control.png diff --git a/examples/core/core_custom_frame_control.c b/examples/core/core_custom_frame_control.c new file mode 100644 index 000000000..c1290abff --- /dev/null +++ b/examples/core/core_custom_frame_control.c @@ -0,0 +1,126 @@ +/******************************************************************************************* +* +* raylib [core] example - custom frame control +* +* WARNING: This is an example for advance users willing to have full control over +* the frame processes. By default, EndDrawing() calls the following processes: +* 1. Draw remaining batch data: rlDrawRenderBatchActive() +* 2. SwapScreenBuffer() +* 3. Frame time control: WaitTime() +* 4. PollInputEvents() +* +* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in +* config.h (it requires recompiling raylib). This way those steps are up to the user. +* +* Note that enabling this flag invalidates some functions: +* - GetFrameTime() +* - SetTargetFPS() +* - GetFPS() +* +* This example has been created using raylib 3.8 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2021 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - custom frame control"); + + // Custom timming variables + double previousTime = GetTime(); // Previous time measure + double currentTime = 0.0; // Current time measure + double updateDrawTime = 0.0; // Update + Draw time + double waitTime = 0.0; // Wait time (if target fps required) + float deltaTime = 0.0f; // Frame time (Update + Draw + Wait time) + + float timeCounter = 0.0f; // Accumulative time counter (seconds) + float position = 0.0f; // Circle position + bool pause = false; // Pause control flag + + int targetFPS = 60; // Our initial target fps + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL) + + if (IsKeyPressed(KEY_SPACE)) pause = !pause; + + if (IsKeyPressed(KEY_UP)) targetFPS += 20; + else if (IsKeyPressed(KEY_DOWN)) targetFPS -= 20; + + if (targetFPS < 0) targetFPS = 0; + + if (!pause) + { + position += 200*deltaTime; // We move at 200 pixels per second + + if (position >= GetScreenWidth()) position = 0; + + timeCounter += deltaTime; // We count time (seconds) + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + for (int i = 0; i < GetScreenWidth()/200; i++) DrawRectangle(200*i, 0, 1, GetScreenHeight(), SKYBLUE); + + DrawCircle((int)position, GetScreenHeight()/2 - 25, 50, RED); + + DrawText(FormatText("%03.0f ms", timeCounter*1000.0f), position - 40, GetScreenHeight()/2 - 100, 20, MAROON); + DrawText(FormatText("PosX: %03.0f", position), position - 50, GetScreenHeight()/2 + 40, 20, BLACK); + + DrawText("Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate.", 10, 10, 20, DARKGRAY); + DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 30, 20, GRAY); + DrawText(FormatText("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME); + DrawText(FormatText("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN); + + EndDrawing(); + + // NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL, + // Events polling, screen buffer swap and frame time control must be managed by the user + + SwapScreenBuffer(); // Flip the back buffer to screen (front buffer) + + currentTime = GetTime(); + updateDrawTime = currentTime - previousTime; + + if (targetFPS > 0) // We want a fixed frame rate + { + waitTime = (1.0f/(float)targetFPS) - updateDrawTime; + if (waitTime > 0.0) + { + WaitTime((float)waitTime*1000.0f); + currentTime = GetTime(); + deltaTime = (float)(currentTime - previousTime); + } + } + else deltaTime = updateDrawTime; // Framerate could be variable + + previousTime = currentTime; + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/core/core_custom_frame_control.png b/examples/core/core_custom_frame_control.png new file mode 100644 index 0000000000000000000000000000000000000000..7d615efe29c0e9561453344a33650c269810373d GIT binary patch literal 16952 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 literal 0 HcmV?d00001 From 49d2897b2480fa7f66405b326c1b8d01ff6ee2d8 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 22 Jun 2021 21:24:15 +0200 Subject: [PATCH 25/30] Update core_custom_frame_control.c --- examples/core/core_custom_frame_control.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/core/core_custom_frame_control.c b/examples/core/core_custom_frame_control.c index c1290abff..a3306d13b 100644 --- a/examples/core/core_custom_frame_control.c +++ b/examples/core/core_custom_frame_control.c @@ -66,9 +66,7 @@ int main(void) if (!pause) { position += 200*deltaTime; // We move at 200 pixels per second - if (position >= GetScreenWidth()) position = 0; - timeCounter += deltaTime; // We count time (seconds) } //---------------------------------------------------------------------------------- @@ -87,7 +85,8 @@ int main(void) DrawText(FormatText("PosX: %03.0f", position), position - 50, GetScreenHeight()/2 + 40, 20, BLACK); DrawText("Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate.", 10, 10, 20, DARKGRAY); - DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 30, 20, GRAY); + DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 60, 20, GRAY); + DrawText("PRESS UP | DOWN to CHANGE TARGET FPS", 10, GetScreenHeight() - 30, 20, GRAY); DrawText(FormatText("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME); DrawText(FormatText("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN); @@ -123,4 +122,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} From f989048bda60aeb74111ec687cd44ec92deacfe3 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 23 Jun 2021 01:16:21 +0200 Subject: [PATCH 26/30] Reviewed example --- .../core/core_2d_camera_smooth_pixelperfect.c | 90 ++++++++---------- .../core_2d_camera_smooth_pixelperfect.png | Bin 6365 -> 15832 bytes 2 files changed, 39 insertions(+), 51 deletions(-) diff --git a/examples/core/core_2d_camera_smooth_pixelperfect.c b/examples/core/core_2d_camera_smooth_pixelperfect.c index ae40cdfc1..75ffe262a 100644 --- a/examples/core/core_2d_camera_smooth_pixelperfect.c +++ b/examples/core/core_2d_camera_smooth_pixelperfect.c @@ -5,15 +5,16 @@ * This example has been created using raylib 3.7 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Example contributed by Giancamillo Alessandroni ([discord]NotManyIdeas#9972 - [github]NotManyIdeasDev) and +* Example contributed by Giancamillo Alessandroni (@NotManyIdeasDev) and * reviewed by Ramon Santamaria (@raysan5) * -* Copyright (c) 2021 Giancamillo Alessandroni (NotManyIdeas#9972) and Ramon Santamaria (@raysan5) +* Copyright (c) 2021 Giancamillo Alessandroni (@NotManyIdeasDev) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" -#include + +#include // Required for: sinf(), cosf() int main(void) { @@ -22,33 +23,32 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - const int virualScreenWidth = 160; + const int virtualScreenWidth = 160; const int virtualScreenHeight = 90; - const float virtualRatio = (float)screenWidth/(float)virualScreenWidth; + const float virtualRatio = (float)screenWidth/(float)virtualScreenWidth; InitWindow(screenWidth, screenHeight, "raylib [core] example - smooth pixel-perfect camera"); - Camera2D worldSpaceCamera = { 0 }; // Game world camera + Camera2D worldSpaceCamera = { 0 }; // Game world camera worldSpaceCamera.zoom = 1.0f; - Camera2D screenSpaceCamera = { 0 }; //Smoothing camera + Camera2D screenSpaceCamera = { 0 }; // Smoothing camera screenSpaceCamera.zoom = 1.0f; - RenderTexture2D renderTexture = LoadRenderTexture(virualScreenWidth, virtualScreenHeight); //This is where we'll draw all our objects. + RenderTexture2D target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight); // This is where we'll draw all our objects. - Rectangle firstRectangle = { 70.0f, 35.0f, 20.0f, 20.0f }; - Rectangle secondRectangle = { 90.0f, 55.0f, 30.0f, 10.0f }; - Rectangle thirdRectangle = { 80.0f, 65.0f, 15.0f, 25.0f }; + Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f }; + Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f }; + Rectangle rec03 = { 80.0f, 65.0f, 15.0f, 25.0f }; - //The renderTexture's height is flipped (in the source Rectangle), due to OpenGL reasons. - Rectangle renderTextureSource = { 0.0f, 0.0f, (float)renderTexture.texture.width, (float)-renderTexture.texture.height }; - Rectangle renderTextureDest = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) }; + // The target's height is flipped (in the source Rectangle), due to OpenGL reasons + Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height }; + Rectangle destRec = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) }; Vector2 origin = { 0.0f, 0.0f }; float rotation = 0.0f; - float degreesPerSecond = 60.0f; float cameraX = 0.0f; float cameraY = 0.0f; @@ -61,16 +61,16 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - rotation += degreesPerSecond*GetFrameTime(); // Rotate the rectangles. + rotation += 60.0f*GetFrameTime(); // Rotate the rectangles, 60 degrees per second - // Make the camera move to demonstrate the effect. + // Make the camera move to demonstrate the effect cameraX = (sinf(GetTime())*50.0f) - 10.0f; cameraY = cosf(GetTime())*30.0f; - // Set the camera's target to the values computed above. + // Set the camera's target to the values computed above screenSpaceCamera.target = (Vector2){ cameraX, cameraY }; - //Round worldSpace coordinates, keep decimals into screenSpace coordinates. + // Round worldSpace coordinates, keep decimals into screenSpace coordinates worldSpaceCamera.target.x = (int)screenSpaceCamera.target.x; screenSpaceCamera.target.x -= worldSpaceCamera.target.x; screenSpaceCamera.target.x *= virtualRatio; @@ -83,47 +83,35 @@ int main(void) // Draw //---------------------------------------------------------------------------------- - BeginDrawing(); - ClearBackground(RED); // This is for debug purposes. If you see red, then you've probably done something wrong. - - BeginTextureMode(renderTexture); - BeginMode2D(worldSpaceCamera); - ClearBackground(RAYWHITE); // This is the color you should see as background color. - - // Draw the rectangles - DrawRectanglePro(firstRectangle, origin, rotation, BLACK); - DrawRectanglePro(secondRectangle, origin, -rotation, RED); - DrawRectanglePro(thirdRectangle, origin, rotation + 45.0f, BLUE); - - EndMode2D(); + BeginTextureMode(target); + ClearBackground(RAYWHITE); + + BeginMode2D(worldSpaceCamera); + DrawRectanglePro(rec01, origin, rotation, BLACK); + DrawRectanglePro(rec02, origin, -rotation, RED); + DrawRectanglePro(rec03, origin, rotation + 45.0f, BLUE); + EndMode2D(); EndTextureMode(); + + BeginDrawing(); + ClearBackground(RED); - BeginMode2D(screenSpaceCamera); + BeginMode2D(screenSpaceCamera); + DrawTexturePro(target.texture, sourceRec, destRec, origin, 0.0f, WHITE); + EndMode2D(); - // Draw the render texture with an offset of 1 worldSpace unit/pixel, so that the content behind the renderTexture is not shown. - DrawTexturePro( - renderTexture.texture, - renderTextureSource, - renderTextureDest, - origin, - 0.0f, - WHITE - ); - - EndMode2D(); - - //Debug info - DrawText("Screen resolution: 800x450", 5, 0, 20, DARKBLUE); - DrawText("World resolution: 160x90", 5, 20, 20, DARKGREEN); - DrawFPS(screenWidth - 75, 0); + DrawText(TextFormat("Screen resolution: %ix%i", screenWidth, screenHeight), 10, 10, 20, DARKBLUE); + DrawText(TextFormat("World resolution: %ix%i", virtualScreenWidth, virtualScreenHeight), 10, 40, 20, DARKGREEN); + DrawFPS(GetScreenWidth() - 95, 10); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - UnloadRenderTexture(renderTexture); // RenderTexture unloading - CloseWindow(); // Close window and OpenGL context + UnloadRenderTexture(target); // Unload render texture + + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/core/core_2d_camera_smooth_pixelperfect.png b/examples/core/core_2d_camera_smooth_pixelperfect.png index aeac7944688c34c2a38b299721cf90915fb22084..ba8d89b7c1e7d68f069a4c25488a2e0a8a698d22 100644 GIT binary patch literal 15832 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 Date: Wed, 23 Jun 2021 01:25:09 +0200 Subject: [PATCH 27/30] Review BeginTextureMode() usage Moved outside BeginDrawing()/EndDrawing() to illustrate drawing is happening to an external texture (not screen) --- examples/core/core_split_screen.c | 22 +++++----- examples/core/core_vr_simulator.c | 28 ++++++------- examples/core/core_window_letterbox.c | 38 ++++++++--------- examples/shaders/shaders_custom_uniform.c | 51 ++++++++++------------- examples/shaders/shaders_eratosthenes.c | 34 +++++++-------- examples/shaders/shaders_julia_set.c | 42 +++++++++---------- examples/shaders/shaders_postprocessing.c | 34 +++++---------- src/core.c | 7 +++- 8 files changed, 113 insertions(+), 143 deletions(-) diff --git a/examples/core/core_split_screen.c b/examples/core/core_split_screen.c index 0bfdb84ac..31c3fb4bf 100644 --- a/examples/core/core_split_screen.c +++ b/examples/core/core_split_screen.c @@ -89,7 +89,7 @@ int main(void) // this moves thigns at 10 world units per second, regardless of the actual FPS float offsetThisFrame = 10.0f*GetFrameTime(); - // Move player 1 forward and backwards (no turning) + // Move Player1 forward and backwards (no turning) if (IsKeyDown(KEY_W)) { cameraPlayer1.position.z += offsetThisFrame; @@ -101,7 +101,7 @@ int main(void) cameraPlayer1.target.z -= offsetThisFrame; } - // Move player 2 forward and backwards (no turning) + // Move Player2 forward and backwards (no turning) if (IsKeyDown(KEY_UP)) { cameraPlayer2.position.x += offsetThisFrame; @@ -116,7 +116,7 @@ int main(void) // Draw //---------------------------------------------------------------------------------- - // Draw player 1's view to the render texture + // Draw Player1 view to the render texture BeginTextureMode(screenPlayer1); ClearBackground(SKYBLUE); BeginMode3D(cameraPlayer1); @@ -125,7 +125,7 @@ int main(void) DrawText("PLAYER1 W/S to move", 0, 0, 20, RED); EndTextureMode(); - // Draw player 2's view to the render texture + // Draw Player2 view to the render texture BeginTextureMode(screenPlayer2); ClearBackground(SKYBLUE); BeginMode3D(cameraPlayer2); @@ -134,21 +134,21 @@ int main(void) DrawText("PLAYER2 UP/DOWN to move", 0, 0, 20, BLUE); EndTextureMode(); - // Draw both view render textures to the screen side by side + // Draw both views render textures to the screen side by side BeginDrawing(); ClearBackground(BLACK); - DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2) { 0, 0 }, WHITE); - DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2) { screenWidth/2.0f, 0 }, WHITE); + DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE); + DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE); EndDrawing(); } // De-Initialization //-------------------------------------------------------------------------------------- - UnloadRenderTexture(screenPlayer1); - UnloadRenderTexture(screenPlayer2); - UnloadTexture(textureGrid); + UnloadRenderTexture(screenPlayer1); // Unload render texture + UnloadRenderTexture(screenPlayer2); // Unload render texture + UnloadTexture(textureGrid); // Unload texture - CloseWindow(); // Close window and OpenGL context + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/core/core_vr_simulator.c b/examples/core/core_vr_simulator.c index bba90b823..65f0dec65 100644 --- a/examples/core/core_vr_simulator.c +++ b/examples/core/core_vr_simulator.c @@ -105,30 +105,26 @@ int main(void) // Draw //---------------------------------------------------------------------------------- - BeginDrawing(); - + BeginTextureMode(target); ClearBackground(RAYWHITE); + BeginVrStereoMode(config); + BeginMode3D(camera); - BeginTextureMode(target); - ClearBackground(RAYWHITE); - BeginVrStereoMode(config); - BeginMode3D(camera); - - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); - DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - DrawGrid(40, 1.0f); - - EndMode3D(); - EndVrStereoMode(); - EndTextureMode(); + DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); + DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); + DrawGrid(40, 1.0f); + EndMode3D(); + EndVrStereoMode(); + EndTextureMode(); + + BeginDrawing(); + ClearBackground(RAYWHITE); BeginShaderMode(distortion); DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE); EndShaderMode(); - DrawFPS(10, 10); - EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/examples/core/core_window_letterbox.c b/examples/core/core_window_letterbox.c index 2c3af6df6..2933ca422 100644 --- a/examples/core/core_window_letterbox.c +++ b/examples/core/core_window_letterbox.c @@ -48,11 +48,11 @@ int main(void) Color colors[10] = { 0 }; for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 }; - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- @@ -79,37 +79,33 @@ int main(void) // Draw //---------------------------------------------------------------------------------- + // Draw everything in the render texture, note this will not be rendered on screen, yet + BeginTextureMode(target); + ClearBackground(RAYWHITE); // Clear render texture background color + + for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]); + + DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE); + DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN); + DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW); + EndTextureMode(); + BeginDrawing(); - ClearBackground(BLACK); + ClearBackground(BLACK); // Clear screen background - // Draw everything in the render texture, note this will not be rendered on screen, yet - BeginTextureMode(target); - - ClearBackground(RAYWHITE); // Clear render texture background color - - for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]); - - DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE); - - DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN); - DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW); - - EndTextureMode(); - - // Draw RenderTexture2D to window, properly scaled + // Draw render texture to screen, properly scaled DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height }, (Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5f, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5f, (float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE); - EndDrawing(); //-------------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - UnloadRenderTexture(target); // Unload render texture + UnloadRenderTexture(target); // Unload render texture - CloseWindow(); // Close window and OpenGL context + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/shaders/shaders_custom_uniform.c b/examples/shaders/shaders_custom_uniform.c index 6efda727b..60516c110 100644 --- a/examples/shaders/shaders_custom_uniform.c +++ b/examples/shaders/shaders_custom_uniform.c @@ -65,11 +65,11 @@ int main(void) // Setup orbital camera SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- @@ -81,55 +81,46 @@ int main(void) // Send new value to the shader to be used on drawing SetShaderValue(shader, swirlCenterLoc, swirlCenter, SHADER_UNIFORM_VEC2); - UpdateCamera(&camera); // Update camera + UpdateCamera(&camera); // Update camera //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- + BeginTextureMode(target); // Enable drawing to texture + ClearBackground(RAYWHITE); // Clear texture background + + BeginMode3D(camera); // Begin 3d mode drawing + DrawModel(model, position, 0.5f, WHITE); // Draw 3d model with texture + DrawGrid(10, 1.0f); // Draw a grid + EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode + + DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED); + EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) + BeginDrawing(); + ClearBackground(RAYWHITE); // Clear screen background - ClearBackground(RAYWHITE); - - BeginTextureMode(target); // Enable drawing to texture - - ClearBackground(RAYWHITE); // Clear texture background - - BeginMode3D(camera); // Begin 3d mode drawing - - DrawModel(model, position, 0.5f, WHITE); // Draw 3d model with texture - - DrawGrid(10, 1.0f); // Draw a grid - - EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode - - DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED); - - EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) - + // Enable shader using the custom uniform BeginShaderMode(shader); - // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE); - EndShaderMode(); // Draw some 2d text over drawn texture DrawText("(c) Barracks 3D model by Alberto Cano", screenWidth - 220, screenHeight - 20, 10, GRAY); - DrawFPS(10, 10); - EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - UnloadShader(shader); // Unload shader - UnloadTexture(texture); // Unload texture - UnloadModel(model); // Unload model - UnloadRenderTexture(target); // Unload render texture + UnloadShader(shader); // Unload shader + UnloadTexture(texture); // Unload texture + UnloadModel(model); // Unload model + UnloadRenderTexture(target); // Unload render texture - CloseWindow(); // Close window and OpenGL context + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/shaders/shaders_eratosthenes.c b/examples/shaders/shaders_eratosthenes.c index d5163a7f6..65fd9f980 100644 --- a/examples/shaders/shaders_eratosthenes.c +++ b/examples/shaders/shaders_eratosthenes.c @@ -46,11 +46,11 @@ int main(void) // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/eratosthenes.fs", GLSL_VERSION)); - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- @@ -59,35 +59,33 @@ int main(void) // Draw //---------------------------------------------------------------------------------- + BeginTextureMode(target); // Enable drawing to texture + ClearBackground(BLACK); // Clear the render texture + + // Draw a rectangle in shader mode to be used as shader canvas + // NOTE: Rectangle uses font white character texture coordinates, + // so shader can not be applied here directly because input vertexTexCoord + // do not represent full screen coordinates (space where want to apply shader) + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK); + EndTextureMode(); // End drawing to texture (now we have a blank texture available for the shader) + BeginDrawing(); - - ClearBackground(RAYWHITE); - - BeginTextureMode(target); // Enable drawing to texture - ClearBackground(BLACK); // Clear the render texture - - // Draw a rectangle in shader mode to be used as shader canvas - // NOTE: Rectangle uses font white character texture coordinates, - // so shader can not be applied here directly because input vertexTexCoord - // do not represent full screen coordinates (space where want to apply shader) - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK); - EndTextureMode(); // End drawing to texture (now we have a blank texture available for the shader) + ClearBackground(RAYWHITE); // Clear screen background BeginShaderMode(shader); // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE); EndShaderMode(); - EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - UnloadShader(shader); // Unload shader - UnloadRenderTexture(target); // Unload texture + UnloadShader(shader); // Unload shader + UnloadRenderTexture(target); // Unload render texture - CloseWindow(); // Close window and OpenGL context + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/shaders/shaders_julia_set.c b/examples/shaders/shaders_julia_set.c index 4a12ba02e..90c44cf58 100644 --- a/examples/shaders/shaders_julia_set.c +++ b/examples/shaders/shaders_julia_set.c @@ -75,15 +75,15 @@ int main(void) SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT); SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2); - int incrementSpeed = 0; // Multiplier of speed to change c value - bool showControls = true; // Show controls - bool pause = false; // Pause animation + int incrementSpeed = 0; // Multiplier of speed to change c value + bool showControls = true; // Show controls + bool pause = false; // Pause animation - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- @@ -145,20 +145,19 @@ int main(void) // Draw //---------------------------------------------------------------------------------- + // Using a render texture to draw Julia set + BeginTextureMode(target); // Enable drawing to texture + ClearBackground(BLACK); // Clear the render texture + + // Draw a rectangle in shader mode to be used as shader canvas + // NOTE: Rectangle uses font white character texture coordinates, + // so shader can not be applied here directly because input vertexTexCoord + // do not represent full screen coordinates (space where want to apply shader) + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK); + EndTextureMode(); + BeginDrawing(); - - ClearBackground(BLACK); // Clear the screen of the previous frame. - - // Using a render texture to draw Julia set - BeginTextureMode(target); // Enable drawing to texture - ClearBackground(BLACK); // Clear the render texture - - // Draw a rectangle in shader mode to be used as shader canvas - // NOTE: Rectangle uses font white character texture coordinates, - // so shader can not be applied here directly because input vertexTexCoord - // do not represent full screen coordinates (space where want to apply shader) - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK); - EndTextureMode(); + ClearBackground(BLACK); // Clear screen background // Draw the saved texture and rendered julia set with shader // NOTE: We do not invert texture on Y, already considered inside shader @@ -176,17 +175,16 @@ int main(void) DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE); DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE); } - EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - UnloadShader(shader); // Unload shader - UnloadRenderTexture(target); // Unload render texture + UnloadShader(shader); // Unload shader + UnloadRenderTexture(target); // Unload render texture - CloseWindow(); // Close window and OpenGL context + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; diff --git a/examples/shaders/shaders_postprocessing.c b/examples/shaders/shaders_postprocessing.c index ef815391b..ebe5fcdb4 100644 --- a/examples/shaders/shaders_postprocessing.c +++ b/examples/shaders/shaders_postprocessing.c @@ -124,50 +124,38 @@ int main(void) // Draw //---------------------------------------------------------------------------------- + BeginTextureMode(target); // Enable drawing to texture + ClearBackground(RAYWHITE); // Clear texture background + + BeginMode3D(camera); // Begin 3d mode drawing + DrawModel(model, position, 0.1f, WHITE); // Draw 3d model with texture + DrawGrid(10, 1.0f); // Draw a grid + EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode + EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) + BeginDrawing(); + ClearBackground(RAYWHITE); // Clear screen background - ClearBackground(RAYWHITE); - - BeginTextureMode(target); // Enable drawing to texture - - ClearBackground(RAYWHITE); // Clear texture background - - BeginMode3D(camera); // Begin 3d mode drawing - - DrawModel(model, position, 0.1f, WHITE); // Draw 3d model with texture - - DrawGrid(10, 1.0f); // Draw a grid - - EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode - - EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) - - // Render previously generated texture using selected postpro shader + // Render generated texture using selected postprocessing shader BeginShaderMode(shaders[currentShader]); - // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE); - EndShaderMode(); // Draw 2d shapes and text over drawn texture DrawRectangle(0, 9, 580, 30, Fade(LIGHTGRAY, 0.7f)); DrawText("(c) Church 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY); - DrawText("CURRENT POSTPRO SHADER:", 10, 15, 20, BLACK); DrawText(postproShaderText[currentShader], 330, 15, 20, RED); DrawText("< >", 540, 10, 30, DARKBLUE); - DrawFPS(700, 15); - EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - // Unload all postpro shaders for (int i = 0; i < MAX_POSTPRO_SHADERS; i++) UnloadShader(shaders[i]); diff --git a/src/core.c b/src/core.c index 38e6a5e7b..e70b9474c 100644 --- a/src/core.c +++ b/src/core.c @@ -1942,7 +1942,10 @@ void ClearBackground(Color color) // Setup canvas (framebuffer) to start drawing void BeginDrawing(void) { - CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer() + // WARNING: Previously to BeginDrawing() other render textures drawing could happen, + // consequently the measure for update vs draw is not accurate (only the total frame time is accurate) + + CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer() CORE.Time.update = CORE.Time.current - CORE.Time.previous; CORE.Time.previous = CORE.Time.current; @@ -2045,7 +2048,7 @@ void EndDrawing(void) CORE.Time.frame += waitTime; // Total frame time: update + draw + wait } - PollInputEvents(); // Poll user events + PollInputEvents(); // Poll user events (before next frame update) #endif #if defined(SUPPORT_EVENTS_AUTOMATION) From 3db26f82eae53677c2e4ee6a4a5901fa8eb5f190 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 23 Jun 2021 09:58:49 +0200 Subject: [PATCH 28/30] WARNING: BREAKING: Functions renamed! RENAMED: GetCodepoints() -> LoadCodepoints(), now codepoint array data is loaded dynamically instead of reusing a limited static buffer. ADDED: UnloadCodepoints() to safely free loaded codepoints RENAMED: GetNextCodepoint() -> GetCodepoint() --- examples/text/text_draw_3d.c | 18 +++++++++--------- src/config.h | 1 - src/raylib.h | 5 +++-- src/text.c | 36 +++++++++++++++++++++++------------- src/textures.c | 2 +- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/examples/text/text_draw_3d.c b/examples/text/text_draw_3d.c index a579a528b..8ce576b6b 100644 --- a/examples/text/text_draw_3d.c +++ b/examples/text/text_draw_3d.c @@ -291,7 +291,7 @@ int main(void) for (int i = 0; i < layers; ++i) { Color clr = light; - if(multicolor) clr = multi[i]; + if (multicolor) clr = multi[i]; DrawTextWave3D(font, text, (Vector3){ -tbox.x/2.0f, layerDistance*i, -4.5f }, fontSize, fontSpacing, lineSpacing, true, &wcfg, time, clr); } @@ -465,7 +465,7 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS float width = (float)(font.recs[index].width + 2.0f*font.charsPadding)/(float)font.baseSize*scale; float height = (float)(font.recs[index].height + 2.0f*font.charsPadding)/(float)font.baseSize*scale; - if(font.texture.id > 0) + if (font.texture.id > 0) { const float x = 0.0f; const float y = 0.0f; @@ -477,7 +477,7 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS const float tw = (srcRec.x+srcRec.width)/font.texture.width; const float th = (srcRec.y+srcRec.height)/font.texture.height; - if(SHOW_LETTER_BOUNDRY) + if (SHOW_LETTER_BOUNDRY) DrawCubeWiresV((Vector3){ position.x + width/2, position.y, position.z + height/2}, (Vector3){ width, LETTER_BOUNDRY_SIZE, height }, LETTER_BOUNDRY_COLOR); #if defined(RAYLIB_NEW_RLGL) @@ -533,7 +533,7 @@ void DrawText3D(Font font, const char *text, Vector3 position, float fontSize, f { // Get next codepoint from byte string and glyph index in font int codepointByteCount = 0; - int codepoint = GetNextCodepoint(&text[i], &codepointByteCount); + int codepoint = GetCodepoint(&text[i], &codepointByteCount); int index = GetGlyphIndex(font, codepoint); // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -582,7 +582,7 @@ Vector3 MeasureText3D(Font font, const char* text, float fontSize, float fontSpa lenCounter++; int next = 0; - letter = GetNextCodepoint(&text[i], &next); + letter = GetCodepoint(&text[i], &next); index = GetGlyphIndex(font, letter); // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -632,7 +632,7 @@ void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSiz { // Get next codepoint from byte string and glyph index in font int codepointByteCount = 0; - int codepoint = GetNextCodepoint(&text[i], &codepointByteCount); + int codepoint = GetCodepoint(&text[i], &codepointByteCount); int index = GetGlyphIndex(font, codepoint); // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -649,7 +649,7 @@ void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSiz } else if (codepoint == '~') { - if (GetNextCodepoint(&text[i+1], &codepointByteCount) == '~') + if (GetCodepoint(&text[i+1], &codepointByteCount) == '~') { codepointByteCount += 1; wave = !wave; @@ -698,7 +698,7 @@ Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, float fon lenCounter++; int next = 0; - letter = GetNextCodepoint(&text[i], &next); + letter = GetCodepoint(&text[i], &next); index = GetGlyphIndex(font, letter); // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -708,7 +708,7 @@ Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, float fon if (letter != '\n') { - if(letter == '~' && GetNextCodepoint(&text[i+1], &next) == '~') + if (letter == '~' && GetCodepoint(&text[i+1], &next) == '~') { i++; } diff --git a/src/config.h b/src/config.h index 3ca160320..6479d409a 100644 --- a/src/config.h +++ b/src/config.h @@ -165,7 +165,6 @@ //------------------------------------------------------------------------------------ #define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions: // TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit() -#define MAX_TEXT_UNICODE_CHARS 512 // Maximum number of unicode codepoints: GetCodepoints() #define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit() diff --git a/src/raylib.h b/src/raylib.h index ea3dc6938..6c4ab45e6 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1369,9 +1369,10 @@ RLAPI int TextToInteger(const char *text); // Get int RLAPI char *TextToUtf8(int *codepoints, int length); // Encode text codepoint into utf8 text (memory must be freed!) // UTF8 text strings management functions -RLAPI int *GetCodepoints(const char *text, int *count); // Get all codepoints in a string, codepoints count returned by parameters +RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF8 text string, codepoints count returned by parameter +RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory RLAPI int GetCodepointsCount(const char *text); // Get total number of characters (codepoints) in a UTF8 encoded string -RLAPI int GetNextCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF8 encoded string; 0x3f('?') is returned on failure +RLAPI int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF8 encoded string, 0x3f('?') is returned on failure RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength); // Encode codepoint into utf8 text (char array length returned as parameter) //------------------------------------------------------------------------------------ diff --git a/src/text.c b/src/text.c index 65460d808..5b5b85648 100644 --- a/src/text.c +++ b/src/text.c @@ -861,7 +861,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f { // Get next codepoint from byte string and glyph index in font int codepointByteCount = 0; - int codepoint = GetNextCodepoint(&text[i], &codepointByteCount); + int codepoint = GetCodepoint(&text[i], &codepointByteCount); int index = GetGlyphIndex(font, codepoint); // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -918,7 +918,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f { // Get next codepoint from byte string and glyph index in font int codepointByteCount = 0; - int codepoint = GetNextCodepoint(&text[i], &codepointByteCount); + int codepoint = GetCodepoint(&text[i], &codepointByteCount); int index = GetGlyphIndex(font, codepoint); // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -1089,7 +1089,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing lenCounter++; int next = 0; - letter = GetNextCodepoint(&text[i], &next); + letter = GetCodepoint(&text[i], &next); index = GetGlyphIndex(font, letter); // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) @@ -1563,28 +1563,38 @@ RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength) return utf8; } -// Get all codepoints in a string, codepoints count returned by parameters -// REQUIRES: memset() -int *GetCodepoints(const char *text, int *count) +// Load all codepoints from a UTF8 text string, codepoints count returned by parameter +int *LoadCodepoints(const char *text, int *count) { - static int codepoints[MAX_TEXT_UNICODE_CHARS] = { 0 }; - memset(codepoints, 0, MAX_TEXT_UNICODE_CHARS*sizeof(int)); - - int bytesProcessed = 0; int textLength = TextLength(text); + + int bytesProcessed = 0; int codepointsCount = 0; + + // Allocate a big enough buffer to store as many codepoints as text bytes + int *codepoints = RL_CALLOC(textLength, sizeof(int)); for (int i = 0; i < textLength; codepointsCount++) { - codepoints[codepointsCount] = GetNextCodepoint(text + i, &bytesProcessed); + codepoints[codepointsCount] = GetCodepoint(text + i, &bytesProcessed); i += bytesProcessed; } + // Re-allocate buffer to the actual number of codepoints loaded + void *temp = RL_REALLOC(codepoints, codepointsCount*sizeof(int)); + if (temp != NULL) codepoints = temp; + *count = codepointsCount; return codepoints; } +// Unload codepoints data from memory +void UnloadCodepoints(int *codepoints) +{ + RL_FREE(codepoints); +} + // Get total number of characters(codepoints) in a UTF8 encoded text, until '\0' is found // NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead int GetCodepointsCount(const char *text) @@ -1595,7 +1605,7 @@ int GetCodepointsCount(const char *text) while (*ptr != '\0') { int next = 0; - int letter = GetNextCodepoint(ptr, &next); + int letter = GetCodepoint(ptr, &next); if (letter == 0x3f) ptr += 1; else ptr += next; @@ -1613,7 +1623,7 @@ int GetCodepointsCount(const char *text) // NOTE: the standard says U+FFFD should be returned in case of errors // but that character is not supported by the default font in raylib // TODO: Optimize this code for speed!! -int GetNextCodepoint(const char *text, int *bytesProcessed) +int GetCodepoint(const char *text, int *bytesProcessed) { /* UTF8 specs from https://www.ietf.org/rfc/rfc3629.txt diff --git a/src/textures.c b/src/textures.c index 7017660ba..a9c40d50e 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1114,7 +1114,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co { // Get next codepoint from byte string and glyph index in font int codepointByteCount = 0; - int codepoint = GetNextCodepoint(&text[i], &codepointByteCount); + int codepoint = GetCodepoint(&text[i], &codepointByteCount); int index = GetGlyphIndex(font, codepoint); // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) From 7203acdef974014fde0629b49ea8d6a70e7de4d6 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 23 Jun 2021 09:59:11 +0200 Subject: [PATCH 29/30] Minor format tweaks --- examples/models/models_gltf_model.c | 2 +- examples/others/rlgl_standalone.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/models/models_gltf_model.c b/examples/models/models_gltf_model.c index 3475b3f0c..9889ad25a 100644 --- a/examples/models/models_gltf_model.c +++ b/examples/models/models_gltf_model.c @@ -98,7 +98,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - for(int i = 0; i < MAX_MODELS; i++) UnloadModel(model[i]); // Unload models + for (int i = 0; i < MAX_MODELS; i++) UnloadModel(model[i]); // Unload models CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/others/rlgl_standalone.c b/examples/others/rlgl_standalone.c index f30889039..0a5cb5096 100644 --- a/examples/others/rlgl_standalone.c +++ b/examples/others/rlgl_standalone.c @@ -279,7 +279,7 @@ static void DrawGrid(int slices, float spacing) int halfSlices = slices / 2; rlBegin(RL_LINES); - for(int i = -halfSlices; i <= halfSlices; i++) + for (int i = -halfSlices; i <= halfSlices; i++) { if (i == 0) { From f7a6b94f46b296394791a8104663bcc94a877b1a Mon Sep 17 00:00:00 2001 From: Nikhilesh S Date: Wed, 23 Jun 2021 01:02:18 -0700 Subject: [PATCH 30/30] Allow SetWindowSize() on web (#1847) --- src/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core.c b/src/core.c index e70b9474c..e711e4ec8 100644 --- a/src/core.c +++ b/src/core.c @@ -1560,7 +1560,7 @@ void SetWindowMinSize(int width, int height) // TODO: Issues on HighDPI scaling void SetWindowSize(int width, int height) { -#if defined(PLATFORM_DESKTOP) +#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) glfwSetWindowSize(CORE.Window.handle, width, height); #endif #if defined(PLATFORM_WEB)