mirror of
https://github.com/raysan5/raylib.git
synced 2026-10-11 04:01:54 -04:00
Compare commits
24 Commits
e18de07224
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 453cc35f27 | |||
| bc77441de0 | |||
| 89650b5b9e | |||
| 0b5fab1123 | |||
| e453e80bed | |||
| c5958f5832 | |||
| fd0f4c185b | |||
| 84e4a2a257 | |||
| 9056ea3299 | |||
| 806d68a9bc | |||
| 3825bbf2d4 | |||
| c8b19b297b | |||
| a043255aa7 | |||
| 8c23ce44a0 | |||
| 48aaf6e2df | |||
| 0ed3570469 | |||
| 2dee47282a | |||
| 607a659363 | |||
| 040a4bafa9 | |||
| 8571d445e9 | |||
| 4722c9fa58 | |||
| 91d50e2938 | |||
| 92f1f3d5d5 | |||
| f0736f6fb5 |
88
CHANGELOG
88
CHANGELOG
@ -4,20 +4,20 @@ changelog
|
|||||||
Current Release: raylib 6.0 (23 April 2026)
|
Current Release: raylib 6.0 (23 April 2026)
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
Release: raylib 6.2 (xx Sep 2026)
|
Release: raylib 6.2 (xx Oct 2026)
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
KEY CHANGES:
|
KEY CHANGES:
|
||||||
- REDESIGNED: Image API for more alignment with Texture API
|
- REDESIGNED: Image API for more alignment with Texture API
|
||||||
- REDESIGNED: File API for more standard return result values
|
- REDESIGNED: File API for more standard return result values
|
||||||
- REVIEWED: Shapes lines drawing functions, added new ones and unify behaviour
|
- REVIEWED: Shapes lines drawing functions, added new ones and unify behaviour
|
||||||
|
|
||||||
Detailed changes (until 12-Sept-2026):
|
Detailed changes (until 08-Oct-2026):
|
||||||
|
|
||||||
[rcore] ADDED: `IsPathDirectory()`, for convenience and more readability at user code by @raysan5
|
[rcore] ADDED: `IsPathDirectory()`, for convenience and more readability at user code by @raysan5
|
||||||
[rcore] ADDED: `IsPathAbsolute()`, check absolute paths by @raysan5
|
[rcore] ADDED: `IsPathAbsolute()`, check absolute paths by @raysan5
|
||||||
[rcore] ADDED: `IsFileHidden()`, check file hidden (OS-dependant) by @raysan5
|
[rcore] ADDED: `IsFileHidden()`, check file hidden (OS-dependant) by @raysan5
|
||||||
[rcore] REVIEWED: `File*()` functions for consistent return result value by @raysan5 -WARNING-
|
[rcore] REVIEWED: `File*()` functions for consistent return result value by @raysan5 -WARNING-
|
||||||
[rcore] REVIEWED: Not updating mouse.previousPosition when `SeMousePosition()` #5962 by @raysan5 -WARNING-
|
[rcore] REVIEWED: Not updating mouse.previousPosition when `SetMousePosition()` #5962 by @raysan5 -WARNING-
|
||||||
[rcore] REVIEWED: Use `rlgl` provided interface instead of `rlsw` direct access by @raysan5
|
[rcore] REVIEWED: Use `rlgl` provided interface instead of `rlsw` direct access by @raysan5
|
||||||
[rcore] REVIEWED: Set mouse position to (0,0) when mouse leaves window area #5945 by @raysan5
|
[rcore] REVIEWED: Set mouse position to (0,0) when mouse leaves window area #5945 by @raysan5
|
||||||
[rcore] REVIEWED: Multiple string boundary handling (#5812) by @zhaob1n
|
[rcore] REVIEWED: Multiple string boundary handling (#5812) by @zhaob1n
|
||||||
@ -26,7 +26,7 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rcore] REVIEWED: Fix initial macOS window size (#5967) by @loukamb
|
[rcore] REVIEWED: Fix initial macOS window size (#5967) by @loukamb
|
||||||
[rcore] REVIEWED: Fix clipboard image memory leak (#5968) by @LuisR385
|
[rcore] REVIEWED: Fix clipboard image memory leak (#5968) by @LuisR385
|
||||||
[rcore] REVIEWED: `TakeScreenshot()`, support absolute paths by @raysan5
|
[rcore] REVIEWED: `TakeScreenshot()`, support absolute paths by @raysan5
|
||||||
[rcore] REVIEWED: `OpenURL()`, added some safety checks to mitigate malicious url inputs - ROS: `CLN-002 by @raysan5 -WARNING-
|
[rcore] REVIEWED: `OpenURL()`, added some safety checks to mitigate malicious url inputs - ROS: `CLN-002` by @raysan5 -WARNING-
|
||||||
[rcore] REVIEWED: `LoadAutomationEventList()` - ROS: `CLN-005`, `CLN-006` by @raysan5
|
[rcore] REVIEWED: `LoadAutomationEventList()` - ROS: `CLN-005`, `CLN-006` by @raysan5
|
||||||
[rcore] REVIEWED: `GetWindowHandle()`, to be consistent between backends, fix #5885 by @raysan5
|
[rcore] REVIEWED: `GetWindowHandle()`, to be consistent between backends, fix #5885 by @raysan5
|
||||||
[rcore] REVIEWED: `GetWindowPosition()` #5932 by @raysan5
|
[rcore] REVIEWED: `GetWindowPosition()` #5932 by @raysan5
|
||||||
@ -40,6 +40,8 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rcore] REVIEWED: `ComputeSHA256()`, wrong hash when message length mod 64 is 56..59 (#6144) by @killerdevildog -WARNING-
|
[rcore] REVIEWED: `ComputeSHA256()`, wrong hash when message length mod 64 is 56..59 (#6144) by @killerdevildog -WARNING-
|
||||||
[rcore] REVIEWED: `GetPrevDirectoryPath()` behavior to better support side cases (#6073) by @luphi
|
[rcore] REVIEWED: `GetPrevDirectoryPath()` behavior to better support side cases (#6073) by @luphi
|
||||||
[rcore] REVIEWED: `GetGamepadAxisCount()`, `GetGamepadName()`, bounds-check gamepad index (#5937) by @szarta
|
[rcore] REVIEWED: `GetGamepadAxisCount()`, `GetGamepadName()`, bounds-check gamepad index (#5937) by @szarta
|
||||||
|
[rcore] REVIEWED: `FileText*()`, make error handling consistent with `Text*()` helpers (#6210) by @Ne0nWinds
|
||||||
|
[rcore] REVIEWED: `MAX_FILEPATH_LENGTH` to match `MAX_PATH` (#6164) by @randomnumbersandletters
|
||||||
[rcore][GLFW] REVIEWED: `GetClipboardImage()`, fix creating new connection under X11 (#5871) by @steampuker
|
[rcore][GLFW] REVIEWED: `GetClipboardImage()`, fix creating new connection under X11 (#5871) by @steampuker
|
||||||
[rcore][GLFW] REVIEWED: Borderless-windowed mode being always on top (#5868) by @auwsmit
|
[rcore][GLFW] REVIEWED: Borderless-windowed mode being always on top (#5868) by @auwsmit
|
||||||
[rcore][GLFW] REVIEWED: Clipboard image memory leak (GLFW, RGFW) (#6103) by @omaribrahimsaad
|
[rcore][GLFW] REVIEWED: Clipboard image memory leak (GLFW, RGFW) (#6103) by @omaribrahimsaad
|
||||||
@ -47,19 +49,35 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rcore][GLFW] REVIEWED: `Font` symbol conflict (#6094) by @M374LX
|
[rcore][GLFW] REVIEWED: `Font` symbol conflict (#6094) by @M374LX
|
||||||
[rcore][RGFW] REVIEWED: Add fullscreen behaviour on size 0 window creation (#5859) by @keks137
|
[rcore][RGFW] REVIEWED: Add fullscreen behaviour on size 0 window creation (#5859) by @keks137
|
||||||
[rcore][RGFW] REVIEWED: Fix window Y position reading X in RGFW move callback (#6044) by @latent-9
|
[rcore][RGFW] REVIEWED: Fix window Y position reading X in RGFW move callback (#6044) by @latent-9
|
||||||
|
[rcore][GLFW] REVIEWED: Window centering overflow with unsigned screen size (#6119) by @nfvelten
|
||||||
|
[rcore][GLFW] REVIEWED: Allow non-fullscreen window being able to be larger than a workable area (#6137) by @JamesMillsDev
|
||||||
[rcore][SDL] REVIEWED: Use precise mouse wheel values (#5830) by @Menduist
|
[rcore][SDL] REVIEWED: Use precise mouse wheel values (#5830) by @Menduist
|
||||||
[rcore][SDL] REVIEWED: Fix SDL3 wrong joystick functions usage (#5948) by @0xFishbyte
|
[rcore][SDL] REVIEWED: Fix SDL3 wrong joystick functions usage (#5948) by @0xFishbyte
|
||||||
|
[rcore][SDL] REVIEWED: Accumulate relative mouse motion per frame (#6215) by @snowyukitty
|
||||||
|
[rcore][SDL] REVIEWED: Fix only the first dropped file being registered (#6190) by @SulimanAbdulrazzaq
|
||||||
|
[rcore][SDL] REVIEWED: `DROP_EVENT_DATA` definition (#6185) by @Yonokid
|
||||||
|
[rcore][SDL] REVIEWED: Grow dropFilePaths dynamically when file is dragged ontop of window (#6178) by @jestarray
|
||||||
|
[rcore][SDL] REVIEWED: Refactor dragdrop file onto window handling and grow dropFilepaths dynamically like glfw (#6178) by @jestarray
|
||||||
[rcore][DRM] REVIEWED: Silence warnings when using GRAPHICS_API_OPENGL_SOFTWARE (#5839) by @NighthowlerStudios
|
[rcore][DRM] REVIEWED: Silence warnings when using GRAPHICS_API_OPENGL_SOFTWARE (#5839) by @NighthowlerStudios
|
||||||
[rcore][DRM] REVIEWED: Segfault on some NVIDIA proprietary drivers (#5960) by @girvel
|
[rcore][DRM] REVIEWED: Segfault on some NVIDIA proprietary drivers (#5960) by @girvel
|
||||||
[rcore][DRM] REVIEWED: Raise MAX_DRM_CACHED_BUFFERS to 4 and warn when the cache fills (#6107) by @jtakakura
|
[rcore][DRM] REVIEWED: Raise MAX_DRM_CACHED_BUFFERS to 4 and warn when the cache fills (#6107) by @jtakakura
|
||||||
[rcore][Web] REVIEWED: Fix for stale mouse position (#5981) by @largenumberhere
|
[rcore][Web] REVIEWED: Fix for stale mouse position (#5981) by @largenumberhere
|
||||||
[rcore][Win32] ADDED: GetClipboardImage() (#6091) by @omaribrahimsaad
|
[rcore][Web] REVIEWED: Avoid `glfwGetProcAddress()` to reduce code size (#6220) by @vdemcak -WARNING-
|
||||||
|
[rcore][Win32] ADDED: Support MSAA (#6227) by @Ne0nWinds
|
||||||
|
[rcore][Win32] ADDED: `IsKeyPressedRepeat()` implementation (#6218) by @Ne0nWinds
|
||||||
|
[rcore][Win32] ADDED: `GetClipboardImage()` (#6091) by @omaribrahimsaad
|
||||||
[rcore][Win32] REVIEWED: Use `CORE.Input.Keyboard.exitKey` when handling window closing (#5911) by @aceinetx
|
[rcore][Win32] REVIEWED: Use `CORE.Input.Keyboard.exitKey` when handling window closing (#5911) by @aceinetx
|
||||||
[rcore][Win32] REVIEWED: Security fixes (#5899) by @M374LX
|
[rcore][Win32] REVIEWED: Security fixes (#5899) by @M374LX
|
||||||
[rcore][Win32] REVIEWED: Handle conflict with `PlaySoundW()` for wide string builds (#6140) by @JeffM2501
|
[rcore][Win32] REVIEWED: Handle conflict with `PlaySoundW()` for wide string builds (#6140) by @JeffM2501
|
||||||
|
[rcore][Win32] REVIEWED: `SetWindowState()`, prevent infinite loop (#6194) by @Ne0nWinds
|
||||||
|
[rcore][Win32] REVIEWED: Missing break in WndProc switch statement (#6209) by @Ne0nWinds
|
||||||
|
[rcore][Win32] REVIEWED: `SetWindowSize()`, allow to change only the width or height (#6232) by @Ne0nWinds
|
||||||
|
[rcore][Win32] REVIEWED: `CloseWindow()`, clean up window state (#6233) by @Ne0nWinds
|
||||||
|
[rcore][Win32] REVIEWED: `IsWindowResized()`, return true only when needed (#6186) by @Ne0nWinds
|
||||||
|
[rcore][Win32] REVIEWED: WGL pixel format not being applied (#6219) by @Ne0nWinds
|
||||||
[rcore][Android] REVIEWED: Restore face-button input on Android gamepads (#5824) by @Tubbles
|
[rcore][Android] REVIEWED: Restore face-button input on Android gamepads (#5824) by @Tubbles
|
||||||
[rcore][Android] REVIEWED: Relaunch hang after destroy while paused (#6040) by @get-charlie
|
[rcore][Android] REVIEWED: Relaunch hang after destroy while paused (#6040) by @get-charlie
|
||||||
[rcore][Emscripten] REVIEWED: GetTime(), fix time calculation (#6061) by @andzdroid
|
[rcore][Emscripten] REVIEWED: `GetTime()`, fix time calculation (#6061) by @andzdroid
|
||||||
[rcore][Emscripten] REVIEWED: Handle emscripten keyboard events (#6067) by @andzdroid
|
[rcore][Emscripten] REVIEWED: Handle emscripten keyboard events (#6067) by @andzdroid
|
||||||
[rcore][Emscripten] REVIEWED: Invert emscripten scroll wheel direction (#6104) by @andzdroid
|
[rcore][Emscripten] REVIEWED: Invert emscripten scroll wheel direction (#6104) by @andzdroid
|
||||||
[rcore][Emscripten] REVIEWED: Update emscripten mouse handling (#6070) by @andzdroid
|
[rcore][Emscripten] REVIEWED: Update emscripten mouse handling (#6070) by @andzdroid
|
||||||
@ -97,12 +115,16 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rshapes] REVIEWED: `DrawPolyLinesEx()` line thickness (#6014) by @MatthewRoush
|
[rshapes] REVIEWED: `DrawPolyLinesEx()` line thickness (#6014) by @MatthewRoush
|
||||||
[rshapes] REVIEWED: `DrawRectangleLinesEx()` (#6027) by @MatthewRoush
|
[rshapes] REVIEWED: `DrawRectangleLinesEx()` (#6027) by @MatthewRoush
|
||||||
[rshapes] REVIEWED: `DrawRectangleRoundedLines()` (#5992) by @MatthewRoush
|
[rshapes] REVIEWED: `DrawRectangleRoundedLines()` (#5992) by @MatthewRoush
|
||||||
|
[rshapes] REVIEWED: `DrawRectangleRounded*()`, segment auto-calculation threshold (#6159) by @MatthewRoush
|
||||||
|
[rtextures] ADDED: Support for .pep image fileformat, useful for pixel-art by @raysan5
|
||||||
[rtextures] ADDED: `LoadRenderTextureEx()` with user defined pixel format (#6114) by @JeffM2501
|
[rtextures] ADDED: `LoadRenderTextureEx()` with user defined pixel format (#6114) by @JeffM2501
|
||||||
[rtextures] ADDED: `ImageDrawLineStrip()` by @raysan5
|
[rtextures] ADDED: `ImageDrawLineStrip()` by @raysan5
|
||||||
[rtextures] ADDED: `DrawTriangleGradient()` by @raysan5
|
[rtextures] ADDED: `DrawTriangleGradient()` by @raysan5
|
||||||
[rtextures] ADDED: `DrawCircleLinesEx()`, simpler naming than `DrawRing()` by @raysan5
|
[rtextures] ADDED: `DrawCircleLinesEx()`, simpler naming than `DrawRing()` by @raysan5
|
||||||
[rtextures] ADDED: `ImageDrawCircleGradient()` by @raysan5
|
[rtextures] ADDED: `ImageDrawCircleGradient()` by @raysan5
|
||||||
[rtextures] ADDED: Support for .pep image fileformat, useful for pixel-art by @raysan5
|
[rtextures] ADDED: `ImageDrawImageEx()` by @raysan5
|
||||||
|
[rtextures] ADDED: `ImageDrawRectanglePro()` by @raysan5
|
||||||
|
[rtextures] ADDED: `ImageDrawRectangleGradientEx()` by @raysan5
|
||||||
[rtextures] RENAMED: `ImageDrawTriangleEx()` to `ImageDrawTriangleGradient()` by @raysan5 -WARNING-
|
[rtextures] RENAMED: `ImageDrawTriangleEx()` to `ImageDrawTriangleGradient()` by @raysan5 -WARNING-
|
||||||
[rtextures] REDESIGNED: `ImageDraw()`, align with `DrawTexture()` by @raysan5 -WARNING-
|
[rtextures] REDESIGNED: `ImageDraw()`, align with `DrawTexture()` by @raysan5 -WARNING-
|
||||||
[rtextures] REDESIGNED: `ImageDrawRectangleLines()`, consistency with `DrawRectangleLines()` by @raysan5 -WARNING-
|
[rtextures] REDESIGNED: `ImageDrawRectangleLines()`, consistency with `DrawRectangleLines()` by @raysan5 -WARNING-
|
||||||
@ -118,6 +140,9 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rtextures] REVIEWED: `ImageColorContrast()` parameter type, consistent with other `Image*()` functions by @raysan5 -WARNING-
|
[rtextures] REVIEWED: `ImageColorContrast()` parameter type, consistent with other `Image*()` functions by @raysan5 -WARNING-
|
||||||
[rtextures] REVIEWED: `GetPixelDataSize()`, avoid allocations >2GB - ROS: `CLN-013` by @raysan5
|
[rtextures] REVIEWED: `GetPixelDataSize()`, avoid allocations >2GB - ROS: `CLN-013` by @raysan5
|
||||||
[rtextures] REVIEWED: `GetPixelColor()` const by @raysan5
|
[rtextures] REVIEWED: `GetPixelColor()` const by @raysan5
|
||||||
|
[rtextures] REVIEWED: `ImageDrawImageEx()`, blending on transparent destinations (#6224) by @Kartikey-cs
|
||||||
|
[rtextures] REVIEWED: `ImageKernelConvolution()`, sampling across rows at image edges and unclamped alpha (#6192) by @4RH1T3CT0R7
|
||||||
|
[rtext] REVIEWED: BDF loading writing glyphs through a NULL-based pointer (#6198) by @antonsoo
|
||||||
[rtext] REVIEWED: `LoadFontEx()`, `LoadFontFromMemory()`, additional warnings (#5864) by @CrackedPixel
|
[rtext] REVIEWED: `LoadFontEx()`, `LoadFontFromMemory()`, additional warnings (#5864) by @CrackedPixel
|
||||||
[rtext] REVIEWED: `TextToSnake()`, not considering spaces properly by @raysan5
|
[rtext] REVIEWED: `TextToSnake()`, not considering spaces properly by @raysan5
|
||||||
[rtext] REVIEWED: `TextSubtext()`, fix returning empty string when position is 0 (#5975) by @thiagomucci
|
[rtext] REVIEWED: `TextSubtext()`, fix returning empty string when position is 0 (#5975) by @thiagomucci
|
||||||
@ -127,10 +152,14 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rtext] REVIEWED: `LoadFontFromImage()`, memory leak (#6100) by @ApexNadir
|
[rtext] REVIEWED: `LoadFontFromImage()`, memory leak (#6100) by @ApexNadir
|
||||||
[rtext] REVIEWED: `TextInsert()`/`TextInsertAlloc()` (#6021) by @SewerynKaminski
|
[rtext] REVIEWED: `TextInsert()`/`TextInsertAlloc()` (#6021) by @SewerynKaminski
|
||||||
[rtext] REVIEWED: `TextSplit()` reading past its buffer on text of 1024 bytes (#6136) by @MaxFreedomPollard
|
[rtext] REVIEWED: `TextSplit()` reading past its buffer on text of 1024 bytes (#6136) by @MaxFreedomPollard
|
||||||
[rtext] REVIEWED: `TextToPascal()`/`TextToCamel()` truncating text after a separator (#6132) by @MaxFreedomPollard
|
[rtext] REVIEWED: `TextToPascal()`/`TextToCamel()`, truncating text after a separator (#6132) by @MaxFreedomPollard
|
||||||
|
[rtext] REVIEWED: `TextToPascal()`/`TextToCamel()`, empty strings checks (#6213) by @Ne0nWinds
|
||||||
[rmodels] REDESIGNED: `DrawCapsule()`, `DrawCapsuleWires()`, parameter order by @raysan5 -WARNING-
|
[rmodels] REDESIGNED: `DrawCapsule()`, `DrawCapsuleWires()`, parameter order by @raysan5 -WARNING-
|
||||||
[rmodels] REVIEWED: Fix glTF skinning when joints have non-joint parent nodes (#5876) by @cseelhoff
|
[rmodels] REVIEWED: Fix glTF skinning when joints have non-joint parent nodes (#5876) by @cseelhoff
|
||||||
[rmodels] REVIEWED: Change `boneCount` field type to `unsigned int` (#5955) by @lauchimoon
|
[rmodels] REVIEWED: Change `boneCount` field type to `unsigned int` (#5955) by @lauchimoon
|
||||||
|
[rmodels] REVIEWED: GLTF animation interpolation (#6007) by @lassade
|
||||||
|
[rmodels] REVIEWED: glTF pose sampled at the end of an animation returning a pose from the start (#6048) by @LeFede
|
||||||
|
[rmodels] REVIEWED: `LoadOBJ()`, avoid reading past vertex data on out-of-range face indices (#6199) by @antonsoo
|
||||||
[rmodels] REVIEWED: `LoadGLTF()`, use inverse bind matrices for bind pose (#5832) by @fyl2xp1
|
[rmodels] REVIEWED: `LoadGLTF()`, use inverse bind matrices for bind pose (#5832) by @fyl2xp1
|
||||||
[rmodels] REVIEWED: `IsModelValid()` #5780 by @raysan5
|
[rmodels] REVIEWED: `IsModelValid()` #5780 by @raysan5
|
||||||
[rmodels] REVIEWED: `GenMeshTorus()`, improved comments (#5934) by @EugenioBarbieriViale
|
[rmodels] REVIEWED: `GenMeshTorus()`, improved comments (#5934) by @EugenioBarbieriViale
|
||||||
@ -138,8 +167,7 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[rmodels] REVIEWED: `DrawSphereWires()`, code optimization (#6000) by @oscujic
|
[rmodels] REVIEWED: `DrawSphereWires()`, code optimization (#6000) by @oscujic
|
||||||
[rmodels] REVIEWED: `DrawCapsule()`, `DrawCapsuleWires()`, validate minimum rings (#5909) by @LuisR385
|
[rmodels] REVIEWED: `DrawCapsule()`, `DrawCapsuleWires()`, validate minimum rings (#5909) by @LuisR385
|
||||||
[rmodels] REVIEWED: `UnloadModel()`, fix memory leak (#5907) by @LuisR385
|
[rmodels] REVIEWED: `UnloadModel()`, fix memory leak (#5907) by @LuisR385
|
||||||
[rmodels] REVIEWED: GLTF animation interpolation (#6007) by @lassade
|
[rmodels] REVIEWED: `UpdateModelAnimation()`, compute bone normal matrices once per bone instead of per vertex (#6191) by @4RH1T3CT0R7 -WARNING-
|
||||||
[rmodels] REVIEWED: glTF pose sampled at the end of an animation returning a pose from the start (#6048) by @LeFede
|
|
||||||
[raudio] REVIEWED: `UpdateSound()`, missleading parameter name by @raysan5
|
[raudio] REVIEWED: `UpdateSound()`, missleading parameter name by @raysan5
|
||||||
[raudio] REVIEWED: `UnloadSoundAlias()`, prevent leak (#5857) by @Peter0x44
|
[raudio] REVIEWED: `UnloadSoundAlias()`, prevent leak (#5857) by @Peter0x44
|
||||||
[raudio] REVIEWED: Remove extra `drflac_free()` call (#5916) by @CrackedPixel
|
[raudio] REVIEWED: Remove extra `drflac_free()` call (#5916) by @CrackedPixel
|
||||||
@ -149,6 +177,9 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[raudio] REVIEWED: `CloseAudioDevice()`, crash when uninit device before mutex (#6039) by @get-charlie
|
[raudio] REVIEWED: `CloseAudioDevice()`, crash when uninit device before mutex (#6039) by @get-charlie
|
||||||
[raymath] ADDED: Operator overload for (float * Vector) (#5815) by @alphahex99
|
[raymath] ADDED: Operator overload for (float * Vector) (#5815) by @alphahex99
|
||||||
[raymath] REVIEWED: `MatrixCompose()` to follow raymath conventions (#6133) by @carlost0
|
[raymath] REVIEWED: `MatrixCompose()` to follow raymath conventions (#6133) by @carlost0
|
||||||
|
[raymath] REVIEWED: `MatrixCompose()`, rotating vectors with already overwritten components (#6187) by @ethanstoner
|
||||||
|
[raymath] REVIEWED: `MatrixDecompose()`, reading rows instead of columns (#6225) by @ewraj
|
||||||
|
[raymath] REVIEWED: `QuaternionFromVector3ToVector3()`, returning a zero quaternion for opposite vectors (#6230) by @ewraj
|
||||||
|
|
||||||
[build] REMOVED: Unmaintained project: 4coder by @raysan5
|
[build] REMOVED: Unmaintained project: 4coder by @raysan5
|
||||||
[build] REMOVED: Unmaintained project: VS2019-Android by @raysan5
|
[build] REMOVED: Unmaintained project: VS2019-Android by @raysan5
|
||||||
@ -156,6 +187,7 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[build][Make] REVIEWED: Re-enable `GLFW_LINUX_ENABLE_WAYLAND` flag by default #5816 by @raysan5
|
[build][Make] REVIEWED: Re-enable `GLFW_LINUX_ENABLE_WAYLAND` flag by default #5816 by @raysan5
|
||||||
[build][Make] REVIEWED: examples/Makefile after testing on OSX (#6077) by @WilliamIsMe1
|
[build][Make] REVIEWED: examples/Makefile after testing on OSX (#6077) by @WilliamIsMe1
|
||||||
[build][Make] REVIEWED: Detect the recipe shell for proper clean (#6146) by @Peter0x44
|
[build][Make] REVIEWED: Detect the recipe shell for proper clean (#6146) by @Peter0x44
|
||||||
|
[build][Make] REVIEWED: Avoid _GNU_SOURCE on Linux to keep the library linkable with older glibc (#6214) by @Peter0x44 -WARNING-
|
||||||
[build][VS2022] REVIEWED: x64 build compatibility support (#6052) (#6053) by @yoobezxc
|
[build][VS2022] REVIEWED: x64 build compatibility support (#6052) (#6053) by @yoobezxc
|
||||||
[build][CMake] ADDED: Support for Win32 platform + examples (#5855) by @CrackedPixel
|
[build][CMake] ADDED: Support for Win32 platform + examples (#5855) by @CrackedPixel
|
||||||
[build][CMake] REVIEWED: Fix config.h parsing into cmake options (#5844) by @Peter0x44
|
[build][CMake] REVIEWED: Fix config.h parsing into cmake options (#5844) by @Peter0x44
|
||||||
@ -166,16 +198,20 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[build][CMake] REVIEWED: Fix static link dependencies (#5990) by @meta-legend
|
[build][CMake] REVIEWED: Fix static link dependencies (#5990) by @meta-legend
|
||||||
[build][CMake] REVIEWED: Fix standalone configuration of examples project (#6079) by @zaveshaa
|
[build][CMake] REVIEWED: Fix standalone configuration of examples project (#6079) by @zaveshaa
|
||||||
[build][CMake] REVIEWED: Propagate Cocoa backend frameworks to consumers of static raylib on macOS (#6086) by @zaveshaa
|
[build][CMake] REVIEWED: Propagate Cocoa backend frameworks to consumers of static raylib on macOS (#6086) by @zaveshaa
|
||||||
|
[build][CMake] REVIEWED: Fix install export with vendored SDL (#6173) by @RobLoach
|
||||||
[build][Zig] REVIEWED: Support wasm examples building (#5811) by @shadeops
|
[build][Zig] REVIEWED: Support wasm examples building (#5811) by @shadeops
|
||||||
[build][Zig] REVIEWED: Avoid building examples all the time (#5869) by @jn-jairo
|
[build][Zig] REVIEWED: Avoid building examples all the time (#5869) by @jn-jairo
|
||||||
[build][Zig] REVIEWED: Avoid building web examples all the time (#6006) by @jn-jairo
|
[build][Zig] REVIEWED: Avoid building web examples all the time (#6006) by @jn-jairo
|
||||||
[build][Zig] REVIEWED: Update to raygui 5.0 (#6005) by @jn-jairo
|
[build][Zig] REVIEWED: Update to raygui 5.0 (#6005) by @jn-jairo
|
||||||
|
[build][Zig] REVIEWED: Migration to latest 0.17 release (#5951) by @miker2049 -WARNING-
|
||||||
|
[build][CI] ADDED: Clang tidy linting (disabled by default) (#6163) by @jestarray -WARNING-
|
||||||
[build][CI] REVIEWED: GitHub Actions update to latest actions versions by @raysan5
|
[build][CI] REVIEWED: GitHub Actions update to latest actions versions by @raysan5
|
||||||
[build][CI] REVIEWED: `build_examples_windows.yml`, use latest actions versions by @raysan5
|
[build][CI] REVIEWED: `build_examples_windows.yml`, use latest actions versions by @raysan5
|
||||||
[build][CI] REVIEWED: `analyze_codeql.yml`, use latest actions versions by @raysan5
|
[build][CI] REVIEWED: `analyze_codeql.yml`, use latest actions versions by @raysan5
|
||||||
[build][CI] REVIEWED: `setup-emsdk`, use latest actions version by @raysan5
|
[build][CI] REVIEWED: `setup-emsdk`, use latest actions version by @raysan5
|
||||||
|
|
||||||
[bindings] ADDED: Recomendations for binding authors (#6141) by @JeffM2501
|
[bindings] ADDED: Recomendations for binding authors (#6141) by @JeffM2501
|
||||||
|
[bindings] ADDED: gcl native raylib module (#6152) by @gnuchanos
|
||||||
[bindings] ADDED: sola-raylib (6.0) (#5790, #5795) by @brettchalupa
|
[bindings] ADDED: sola-raylib (6.0) (#5790, #5795) by @brettchalupa
|
||||||
[bindings] ADDED: gclang-raylib (6.0) (#5850) by @gnuchanos
|
[bindings] ADDED: gclang-raylib (6.0) (#5850) by @gnuchanos
|
||||||
[bindings] ADDED: mach-raylib (#6059) by @Angluca
|
[bindings] ADDED: mach-raylib (#6059) by @Angluca
|
||||||
@ -208,26 +244,39 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[bindings] UPDATED: fortran-raylib to raylib 6.0 (#6060) by @interkosmos
|
[bindings] UPDATED: fortran-raylib to raylib 6.0 (#6060) by @interkosmos
|
||||||
[bindings] UPDATED: raylib-py to raylib 6.0 (#6095) by @overdev
|
[bindings] UPDATED: raylib-py to raylib 6.0 (#6095) by @overdev
|
||||||
[bindings] UPDATED: h-raylib to raylib 6.0 (#6142) by @Anut-py
|
[bindings] UPDATED: h-raylib to raylib 6.0 (#6142) by @Anut-py
|
||||||
|
[bindings] UPDATED: Raylib.nelua (#6183) by @AuzFox
|
||||||
|
[bindings] UPDATED: mach-raylib to raylib 6.x-dev (#6153) by @Angluca
|
||||||
|
|
||||||
[examples] ADDED: `core_scissor_shape` (#6032) by @davidbuzatto
|
[examples] ADDED: `core_scissor_shape` (#6032) by @davidbuzatto
|
||||||
[examples] ADDED: `models_mesh_uv_painting` (#6084) by @PanicTitan
|
|
||||||
[examples] ADDED: `models_procedural_decals` (#6083) by @PanicTitan
|
|
||||||
[examples] ADDED: `shaders_lights_bloom` (#6081) by @PanicTitan
|
|
||||||
[examples] ADDED: `shapes_outlines_testbed` (#6072) by @MatthewRoush
|
[examples] ADDED: `shapes_outlines_testbed` (#6072) by @MatthewRoush
|
||||||
[examples] ADDED: `shapes_outlines_thickness` (#6037) by @MatthewRoush
|
[examples] ADDED: `shapes_outlines_thickness` (#6037) by @MatthewRoush
|
||||||
[examples] ADDED: `shapes_polygon_lines` (#6023) by @MatthewRoush
|
[examples] ADDED: `shapes_polygon_lines` (#6023) by @MatthewRoush
|
||||||
|
[examples] ADDED: `shapes_drag_puzzle` (#6165) by @gabriel-piangers
|
||||||
[examples] ADDED: `textures_portal_window` (#6082) by @PanicTitan
|
[examples] ADDED: `textures_portal_window` (#6082) by @PanicTitan
|
||||||
[examples] REVIEWED: `shaders_shadowmap_rendering` by @raysan5
|
[examples] ADDED: `models_mesh_uv_painting` (#6084) by @PanicTitan
|
||||||
[examples] REVIEWED: `models_mesh_uv_painting` by @raysan5
|
[examples] ADDED: `models_procedural_decals` (#6083) by @PanicTitan
|
||||||
[examples] REVIEWED: `shaders_lights_bloom` by @raysan5
|
[examples] ADDED: `shaders_lights_bloom` (#6081) by @PanicTitan
|
||||||
[examples] REVIEWED: `textures_portal_window` by @raysan5
|
[examples] REVIEWED: Clarify Camera2d.offset and how it works with High DPI scale mode (#6203) by @JeffM2501
|
||||||
|
[examples] REVIEWED: Inconsistent version metadata (#6171) by @Ne0nWinds
|
||||||
|
[examples] REVIEWED: Multiple examples, adding missing `Unload*()` (#6151) by @emecdelam
|
||||||
[examples] REVIEWED: `core_smooth_pixelperfect` (#5803) by @rose-mtz
|
[examples] REVIEWED: `core_smooth_pixelperfect` (#5803) by @rose-mtz
|
||||||
[examples] REVIEWED: `core_directory_files` (#5823) by @MAXDVVV
|
[examples] REVIEWED: `core_directory_files` (#5823) by @MAXDVVV
|
||||||
|
[examples] REVIEWED: `core_delta_time`, convert frametime to milliseconds before printing (#6201) by @Ne0nWinds
|
||||||
[examples] REVIEWED: `shapes_ball_physics`, move window for ball shake (#5791) by @Sebbl0508
|
[examples] REVIEWED: `shapes_ball_physics`, move window for ball shake (#5791) by @Sebbl0508
|
||||||
[examples] REVIEWED: `textures_image_drawing` by @raysan5
|
[examples] REVIEWED: `textures_image_drawing` by @raysan5
|
||||||
|
[examples] REVIEWED: `textures_portal_window` by @raysan5
|
||||||
|
[examples] REVIEWED: `textures_image_rotate`, unload source image (#6145) by @Hugohong258
|
||||||
|
[examples] REVIEWED: `textures_image_processing`, fix up arrow wraparound logic (#6217) by @Ne0nWinds
|
||||||
|
[examples] REVIEWED: `text_codepoints_loading`, out of bounds error in `CodepointRemoveDuplicates()` (#6206) by @Ne0nWinds
|
||||||
[examples] REVIEWED: `models_basic_voxel` by @raysan5
|
[examples] REVIEWED: `models_basic_voxel` by @raysan5
|
||||||
[examples] REVIEWED: `models_animation_blending` by @raysan5
|
[examples] REVIEWED: `models_animation_blending` by @raysan5
|
||||||
|
[examples] REVIEWED: `models_mesh_uv_painting` by @raysan5
|
||||||
|
[examples] REVIEWED: `models_animation_blending`, avoid crash when animations fail to load (#6234) by @akashdeshmukh-git
|
||||||
[examples] REVIEWED: `shaders_*`, `pbr.fs`, using wrong uniform value (#5965) by @raysan5
|
[examples] REVIEWED: `shaders_*`, `pbr.fs`, using wrong uniform value (#5965) by @raysan5
|
||||||
|
[examples] REVIEWED: `shaders_lights_bloom` by @raysan5
|
||||||
|
[examples] REVIEWED: `shaders_shadowmap_rendering` by @raysan5
|
||||||
|
[examples] REVIEWED: `shaders_mesh_instancing`, release mesh instancing resources on exit (#6207) by @Hugohong258
|
||||||
|
[examples] REVIEWED: `shaders_lightmap_rendering`, unload lightmap render texture (#6188) by @Hugohong258
|
||||||
|
|
||||||
[rlparser] ADDED: S-Expression output type (#5943) by @VisenDev
|
[rlparser] ADDED: S-Expression output type (#5943) by @VisenDev
|
||||||
[rlparser] REVIEWED: Path fixes (#5794) by @gigamonster256
|
[rlparser] REVIEWED: Path fixes (#5794) by @gigamonster256
|
||||||
@ -249,11 +298,12 @@ Detailed changes (until 12-Sept-2026):
|
|||||||
[external] UPDATED: GLFW to 3.5.1 (#6051) by @M374LX
|
[external] UPDATED: GLFW to 3.5.1 (#6051) by @M374LX
|
||||||
[external] UPDATED: miniaudio to 0.11.25 (#6050) by @M374LX
|
[external] UPDATED: miniaudio to 0.11.25 (#6050) by @M374LX
|
||||||
[external] UPDATED: `raygui` to latest master (raygui 5.0) by @raysan5
|
[external] UPDATED: `raygui` to latest master (raygui 5.0) by @raysan5
|
||||||
|
[external] UPDATED: `qoa` with upstream out-of-bounds fixes (#6162) by @thaidn
|
||||||
[external] REVIEWED: `jar_mod_load_file()`, check fread return value (#5840) by @fffaraz
|
[external] REVIEWED: `jar_mod_load_file()`, check fread return value (#5840) by @fffaraz
|
||||||
[external] REVIEWED: `tiny_obj_loader` Replace `assert()` by runtime checks - ROS: `CLN-012` by @raysan5
|
[external] REVIEWED: `tiny_obj_loader` Replace `assert()` by runtime checks - ROS: `CLN-012` by @raysan5
|
||||||
[external] REVIEWED: `fix_win32_compatibility.h`, fix for newer windows SDK versions (#6088) by @JeffM2501
|
[external] REVIEWED: `fix_win32_compatibility.h`, fix for newer windows SDK versions (#6088) by @JeffM2501
|
||||||
|
[external] REVIEWED: `vox_loader`, added bounds checks to `Vox_SetVoxel()` and chunk parsing (#6175) by @AvAl4nch
|
||||||
|
[external] REVIEWED: `vox_loader`, Prevent memory leak when loading voxel models (#6208) by @Ne0nWinds
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
Release: raylib 6.0 (23 April 2026)
|
Release: raylib 6.0 (23 April 2026)
|
||||||
|
|||||||
@ -68,6 +68,14 @@ void SomeFunction()
|
|||||||
{
|
{
|
||||||
// TODO: Do something here!
|
// TODO: Do something here!
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
- When checking pointers, use full verbose check against `NULL`
|
||||||
|
```c
|
||||||
|
if (dataPtr != NULL)
|
||||||
|
{
|
||||||
|
RL_FREE(dataPtr);
|
||||||
|
dataPtr = NULL;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**If proposing new functions, please try to use a clear naming for function-name and functions-parameters, in case of doubt, open an issue for discussion.**
|
**If proposing new functions, please try to use a clear naming for function-name and functions-parameters, in case of doubt, open an issue for discussion.**
|
||||||
|
|||||||
@ -131,7 +131,7 @@ int main(void)
|
|||||||
DrawText("Left/right to change wave type", 10, 30, 20, DARKGRAY);
|
DrawText("Left/right to change wave type", 10, 30, 20, DARKGRAY);
|
||||||
|
|
||||||
// Draw the last 10 ms of uploaded audio
|
// Draw the last 10 ms of uploaded audio
|
||||||
for (int i = 0; i < screenWidth; i++)
|
for (int i = 0; i < screenWidth - 1; i++)
|
||||||
{
|
{
|
||||||
Vector2 startPos = {(float)i, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + i*SAMPLE_RATE/100/screenWidth] };
|
Vector2 startPos = {(float)i, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + i*SAMPLE_RATE/100/screenWidth] };
|
||||||
Vector2 endPos = { (float)(i + 1), 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + (i + 1)*SAMPLE_RATE/100/screenWidth] };
|
Vector2 endPos = { (float)(i + 1), 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + (i + 1)*SAMPLE_RATE/100/screenWidth] };
|
||||||
|
|||||||
@ -50,7 +50,7 @@ int main(void)
|
|||||||
// NOTE: The gesture log uses an array (as an inverted circular queue) to store the performed gestures
|
// NOTE: The gesture log uses an array (as an inverted circular queue) to store the performed gestures
|
||||||
char gestureLog[GESTURE_LOG_SIZE][12] = { "" };
|
char gestureLog[GESTURE_LOG_SIZE][12] = { "" };
|
||||||
// NOTE: The index for the inverted circular queue (moving from last to first direction, then looping around)
|
// NOTE: The index for the inverted circular queue (moving from last to first direction, then looping around)
|
||||||
int gestureLogIndex = GESTURE_LOG_SIZE;
|
int gestureLogIndex = 0;
|
||||||
int previousGesture = 0;
|
int previousGesture = 0;
|
||||||
|
|
||||||
// Log mode values:
|
// Log mode values:
|
||||||
|
|||||||
@ -114,7 +114,7 @@ int main(void)
|
|||||||
|
|
||||||
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
||||||
|
|
||||||
if (!animPause)
|
if (!animPause && (animCount > 0)) // Animations could fail to load
|
||||||
{
|
{
|
||||||
// Start transition from anim0[] to anim1[]
|
// Start transition from anim0[] to anim1[]
|
||||||
if (IsKeyPressed(KEY_SPACE) && !animTransition)
|
if (IsKeyPressed(KEY_SPACE) && !animTransition)
|
||||||
@ -256,6 +256,8 @@ int main(void)
|
|||||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize);
|
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize);
|
||||||
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||||
|
|
||||||
|
if (animCount > 0)
|
||||||
|
{
|
||||||
// Draw playing timeline with keyframes for anim0[]
|
// Draw playing timeline with keyframes for anim0[]
|
||||||
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 60.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 0",
|
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 60.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 0",
|
||||||
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||||
@ -271,6 +273,7 @@ int main(void)
|
|||||||
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
||||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
||||||
GetScreenHeight() - 30, 1, 20, BLUE);
|
GetScreenHeight() - 30, 1, 20, BLUE);
|
||||||
|
}
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|||||||
@ -316,7 +316,7 @@ static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3])
|
|||||||
static void FreeMeshBuilder(MeshBuilder *mb)
|
static void FreeMeshBuilder(MeshBuilder *mb)
|
||||||
{
|
{
|
||||||
MemFree(mb->vertices);
|
MemFree(mb->vertices);
|
||||||
if (mb->uvs) MemFree(mb->uvs);
|
if (mb->uvs != NULL) MemFree(mb->uvs);
|
||||||
*mb = (MeshBuilder){ 0 };
|
*mb = (MeshBuilder){ 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ static Mesh BuildMesh(MeshBuilder *mb)
|
|||||||
outMesh.vertexCount = mb->vertexCount;
|
outMesh.vertexCount = mb->vertexCount;
|
||||||
outMesh.triangleCount = mb->vertexCount/3;
|
outMesh.triangleCount = mb->vertexCount/3;
|
||||||
outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float));
|
outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float));
|
||||||
if (mb->uvs) outMesh.texcoords = MemAlloc(outMesh.vertexCount*2*sizeof(float));
|
if (mb->uvs != NULL) outMesh.texcoords = MemAlloc(outMesh.vertexCount*2*sizeof(float));
|
||||||
|
|
||||||
for (int i = 0; i < mb->vertexCount; i++)
|
for (int i = 0; i < mb->vertexCount; i++)
|
||||||
{
|
{
|
||||||
@ -336,7 +336,7 @@ static Mesh BuildMesh(MeshBuilder *mb)
|
|||||||
outMesh.vertices[3*i+1] = mb->vertices[i].y;
|
outMesh.vertices[3*i+1] = mb->vertices[i].y;
|
||||||
outMesh.vertices[3*i+2] = mb->vertices[i].z;
|
outMesh.vertices[3*i+2] = mb->vertices[i].z;
|
||||||
|
|
||||||
if (mb->uvs)
|
if (mb->uvs != NULL)
|
||||||
{
|
{
|
||||||
outMesh.texcoords[2*i+0] = mb->uvs[i].x;
|
outMesh.texcoords[2*i+0] = mb->uvs[i].x;
|
||||||
outMesh.texcoords[2*i+1] = mb->uvs[i].y;
|
outMesh.texcoords[2*i+1] = mb->uvs[i].y;
|
||||||
|
|||||||
@ -149,7 +149,7 @@ int main(void)
|
|||||||
|
|
||||||
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib [others] example - rlgl standalone", NULL, NULL);
|
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib [others] example - rlgl standalone", NULL, NULL);
|
||||||
|
|
||||||
if (!window)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@ -50,7 +50,7 @@ int main(void)
|
|||||||
if (IsKeyPressed(KEY_R)) // Reset image collection
|
if (IsKeyPressed(KEY_R)) // Reset image collection
|
||||||
{
|
{
|
||||||
// Unload textures to avoid memory leaks
|
// Unload textures to avoid memory leaks
|
||||||
for (int i = 0; i < MAX_TEXTURE_COLLECTION; i++) UnloadTexture(collection[i].texture);
|
for (int i = 0; i < currentCollectionIndex; i++) UnloadTexture(collection[i].texture);
|
||||||
|
|
||||||
currentCollectionIndex = 0;
|
currentCollectionIndex = 0;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
for (int i = 0; i < MAX_TEXTURE_COLLECTION;i ++)
|
for (int i = 0; i < currentCollectionIndex; i++)
|
||||||
{
|
{
|
||||||
UnloadTexture(collection[i].texture);
|
UnloadTexture(collection[i].texture);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,7 +95,7 @@ int main(void)
|
|||||||
if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON)) curveSelectedPoint = NULL;
|
if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON)) curveSelectedPoint = NULL;
|
||||||
|
|
||||||
// If a point was selected, move it
|
// If a point was selected, move it
|
||||||
if (curveSelectedPoint) *curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta());
|
if (curveSelectedPoint != NULL) *curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta());
|
||||||
|
|
||||||
// The mouse is down, and nothing was selected, so see if anything was picked
|
// The mouse is down, and nothing was selected, so see if anything was picked
|
||||||
Vector2 mouse = GetMousePosition();
|
Vector2 mouse = GetMousePosition();
|
||||||
|
|||||||
@ -30,7 +30,7 @@ target_link_libraries(${PROJECT_NAME} raylib)
|
|||||||
# Web Configurations
|
# Web Configurations
|
||||||
if (${PLATFORM} STREQUAL "Web")
|
if (${PLATFORM} STREQUAL "Web")
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") # Tell Emscripten to build an example.html file.
|
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") # Tell Emscripten to build an example.html file.
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s GL_ENABLE_GET_PROC_ADDRESS=1")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
|
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
|
||||||
|
|||||||
@ -285,7 +285,6 @@ static int android_close(void *cookie);
|
|||||||
// CMake: handled automatically — the PUBLIC flag propagates as INTERFACE_LINK_OPTIONS
|
// CMake: handled automatically — the PUBLIC flag propagates as INTERFACE_LINK_OPTIONS
|
||||||
// to the consumer's final link via target_link_libraries
|
// to the consumer's final link via target_link_libraries
|
||||||
// Make: pass -Wl,--wrap=fopen to the linker command producing the final artifact
|
// Make: pass -Wl,--wrap=fopen to the linker command producing the final artifact
|
||||||
// build.zig: pass -Wl,--wrap=fopen to the linker command producing the final artifact
|
|
||||||
// custom: pass -Wl,--wrap=fopen to the linker command producing the final artifact
|
// custom: pass -Wl,--wrap=fopen to the linker command producing the final artifact
|
||||||
//
|
//
|
||||||
// SHARED library (.so) — wrapping is self-contained:
|
// SHARED library (.so) — wrapping is self-contained:
|
||||||
@ -296,8 +295,6 @@ static int android_close(void *cookie);
|
|||||||
// only raylib internals are wrapped, app code requires a separate flag
|
// only raylib internals are wrapped, app code requires a separate flag
|
||||||
// Make: handled automatically — src/Makefile sets LDFLAGS += -Wl,--wrap=fopen;
|
// Make: handled automatically — src/Makefile sets LDFLAGS += -Wl,--wrap=fopen;
|
||||||
// only raylib internals are wrapped, app code requires a separate flag
|
// only raylib internals are wrapped, app code requires a separate flag
|
||||||
// build.zig: NOT supported — std.Build has no dedicated linker wrap helper, the flag
|
|
||||||
// is not correctly applied at the .so link step
|
|
||||||
// custom: apply -Wl,--wrap=fopen to the linker command producing the .so
|
// custom: apply -Wl,--wrap=fopen to the linker command producing the .so
|
||||||
FILE *__real_fopen(const char *fileName, const char *mode); // Real fopen, provided by the linker (--wrap=fopen)
|
FILE *__real_fopen(const char *fileName, const char *mode); // Real fopen, provided by the linker (--wrap=fopen)
|
||||||
FILE *__wrap_fopen(const char *fileName, const char *mode); // Replacement for fopen()
|
FILE *__wrap_fopen(const char *fileName, const char *mode); // Replacement for fopen()
|
||||||
|
|||||||
@ -2093,7 +2093,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
|
|||||||
// GLFW3: Keyboard callback, runs on key pressed
|
// GLFW3: Keyboard callback, runs on key pressed
|
||||||
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||||
{
|
{
|
||||||
if (key < 0) return; // Security check, macOS fn key generates -1
|
if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return; // Security check, macOS fn key generates -1
|
||||||
|
|
||||||
// WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1
|
// WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1
|
||||||
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
|
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
|
||||||
|
|||||||
@ -97,6 +97,8 @@ typedef struct {
|
|||||||
unsigned int desiredFlags;
|
unsigned int desiredFlags;
|
||||||
|
|
||||||
LARGE_INTEGER timerFrequency;
|
LARGE_INTEGER timerFrequency;
|
||||||
|
|
||||||
|
char *clipboardText;
|
||||||
} PlatformData;
|
} PlatformData;
|
||||||
|
|
||||||
// Define WGL function pointer types (no wglext.h needed)
|
// Define WGL function pointer types (no wglext.h needed)
|
||||||
@ -393,7 +395,7 @@ static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigne
|
|||||||
SIZE clientSize = { rect.right, rect.bottom };
|
SIZE clientSize = { rect.right, rect.bottom };
|
||||||
|
|
||||||
// If client size is alread desired size, no need to update
|
// If client size is alread desired size, no need to update
|
||||||
if ((clientSize.cx == desiredSize.cx) || (clientSize.cy == desiredSize.cy)) return false;
|
if ((clientSize.cx == desiredSize.cx) && (clientSize.cy == desiredSize.cy)) return false;
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "WIN32: Restoring client size from [%dx%d] to [%dx%d] (dpi:%lu dpiScaling:%d app:%ix%i)",
|
TRACELOG(LOG_INFO, "WIN32: Restoring client size from [%dx%d] to [%dx%d] (dpi:%lu dpiScaling:%d app:%ix%i)",
|
||||||
clientSize.cx, clientSize.cy, desiredSize.cx, desiredSize.cy, dpi, dpiScaling, width, height);
|
clientSize.cx, clientSize.cy, desiredSize.cx, desiredSize.cy, dpi, dpiScaling, width, height);
|
||||||
@ -925,7 +927,8 @@ void SetWindowIcon(Image image)
|
|||||||
{
|
{
|
||||||
// Set both large and small icons
|
// Set both large and small icons
|
||||||
SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||||
SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
HICON previousIcon = (HICON)SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||||
|
if (previousIcon) DestroyIcon(previousIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,14 +1122,101 @@ Vector2 GetWindowScaleDPI(void)
|
|||||||
// Set clipboard text content
|
// Set clipboard text content
|
||||||
void SetClipboardText(const char *text)
|
void SetClipboardText(const char *text)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "SetClipboardText not implemented");
|
if (OpenClipboard(platform.hwnd))
|
||||||
|
{
|
||||||
|
if (text == NULL)
|
||||||
|
{
|
||||||
|
EmptyClipboard();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t length = strlen(text);
|
||||||
|
|
||||||
|
int clipboardTextLength = MultiByteToWideChar(CP_UTF8, 0, text, (int)(length + 1), NULL, 0);
|
||||||
|
if (clipboardTextLength != 0)
|
||||||
|
{
|
||||||
|
HGLOBAL globalHandle = GlobalAlloc(GMEM_MOVEABLE, clipboardTextLength*sizeof(wchar_t));
|
||||||
|
|
||||||
|
if (globalHandle)
|
||||||
|
{
|
||||||
|
LPVOID clipboardText = GlobalLock(globalHandle);
|
||||||
|
int charactersCopied = 0;
|
||||||
|
if (clipboardText != NULL)
|
||||||
|
{
|
||||||
|
// Directly copies text to clipboardText and converts from UTF-8 to UTF-16
|
||||||
|
charactersCopied = MultiByteToWideChar(CP_UTF8, 0, text, (int)(length + 1), clipboardText, clipboardTextLength);
|
||||||
|
GlobalUnlock(globalHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (charactersCopied != 0)
|
||||||
|
{
|
||||||
|
EmptyClipboard();
|
||||||
|
|
||||||
|
// We don't need to call GlobalFree when SetClipboardData succeeds; Windows takes control of the memory
|
||||||
|
HANDLE clipboardData = SetClipboardData(CF_UNICODETEXT, globalHandle);
|
||||||
|
if (!clipboardData)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "Clipboard: Failed to set clipboard text.");
|
||||||
|
GlobalFree(globalHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GlobalFree(globalHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseClipboard();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "Clipboard: Failed to write to clipboard. It may be locked by another program.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get clipboard text content
|
// Get clipboard text content
|
||||||
const char *GetClipboardText(void)
|
const char *GetClipboardText(void)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GetClipboardText not implemented");
|
if (platform.clipboardText != NULL)
|
||||||
return NULL;
|
{
|
||||||
|
RL_FREE(platform.clipboardText);
|
||||||
|
platform.clipboardText = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpenClipboard(platform.hwnd))
|
||||||
|
{
|
||||||
|
HANDLE clipboardDataHandle = GetClipboardData(CF_UNICODETEXT);
|
||||||
|
if (clipboardDataHandle)
|
||||||
|
{
|
||||||
|
wchar_t *clipboardText = GlobalLock(clipboardDataHandle);
|
||||||
|
if (clipboardText != NULL)
|
||||||
|
{
|
||||||
|
// The clipboard data can't be trusted. It may or may not be null-terminated!
|
||||||
|
size_t maxLength = GlobalSize(clipboardDataHandle)/sizeof(wchar_t);
|
||||||
|
int length = (int)wcsnlen(clipboardText, maxLength);
|
||||||
|
|
||||||
|
int size = WideCharToMultiByte(CP_UTF8, 0, clipboardText, length, NULL, 0, NULL, NULL);
|
||||||
|
char *utf8Text = (char *)RL_MALLOC(size + 1);
|
||||||
|
|
||||||
|
if ((size > 0) && (WideCharToMultiByte(CP_UTF8, 0, clipboardText, length, utf8Text, size, NULL, NULL) == 0)) size = 0;
|
||||||
|
utf8Text[size] = '\0';
|
||||||
|
|
||||||
|
platform.clipboardText = utf8Text;
|
||||||
|
|
||||||
|
GlobalUnlock(clipboardDataHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseClipboard();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "Clipboard: Failed to read clipboard. It may be locked by another program.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform.clipboardText;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
|
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
|
||||||
@ -1401,7 +1491,23 @@ void PollInputEvents(void)
|
|||||||
// NOTE: Creating a dummy context first to query required extensions
|
// NOTE: Creating a dummy context first to query required extensions
|
||||||
HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||||
{
|
{
|
||||||
// First, create a dummy context to get WGL extensions
|
// Create an invisible window for initial dummy OpenGL context
|
||||||
|
WNDCLASSEXW dummyWindowClass = {
|
||||||
|
.cbSize = sizeof(WNDCLASSEXW),
|
||||||
|
.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||||
|
.lpfnWndProc = DefWindowProcW,
|
||||||
|
.hInstance = GetModuleHandleW(NULL),
|
||||||
|
.lpszClassName = L"wglDummy"
|
||||||
|
};
|
||||||
|
RegisterClassExW(&dummyWindowClass);
|
||||||
|
|
||||||
|
HWND dummyWindow = CreateWindowExW(
|
||||||
|
0, dummyWindowClass.lpszClassName, L"dummyWindow",
|
||||||
|
0, 0, 0, 1, 1, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
HDC dummyHDC = GetDC(dummyWindow);
|
||||||
|
|
||||||
|
// Create a dummy OpenGL context to get WGL extensions
|
||||||
PIXELFORMATDESCRIPTOR pixelFormatDesc = {
|
PIXELFORMATDESCRIPTOR pixelFormatDesc = {
|
||||||
.nSize = sizeof(PIXELFORMATDESCRIPTOR),
|
.nSize = sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
.nVersion = 1,
|
.nVersion = 1,
|
||||||
@ -1410,18 +1516,19 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
|||||||
.cColorBits = 32,
|
.cColorBits = 32,
|
||||||
.cAlphaBits = 8,
|
.cAlphaBits = 8,
|
||||||
.cDepthBits = 24,
|
.cDepthBits = 24,
|
||||||
|
.cStencilBits = 8,
|
||||||
.iLayerType = PFD_MAIN_PLANE
|
.iLayerType = PFD_MAIN_PLANE
|
||||||
};
|
};
|
||||||
|
|
||||||
int pixelFormat = ChoosePixelFormat(hdc, &pixelFormatDesc);
|
int dummyPixelFormat = ChoosePixelFormat(dummyHDC, &pixelFormatDesc);
|
||||||
SetPixelFormat(hdc, pixelFormat, &pixelFormatDesc);
|
SetPixelFormat(dummyHDC, dummyPixelFormat, &pixelFormatDesc);
|
||||||
//int pixelFormat = ChoosePixelFormat(platform.hdc, &pixelFormatDesc);
|
//int pixelFormat = ChoosePixelFormat(platform.hdc, &pixelFormatDesc);
|
||||||
//if (!pixelFormat) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ChoosePixelFormat", GetLastError()); return -1; }
|
//if (!pixelFormat) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ChoosePixelFormat", GetLastError()); return -1; }
|
||||||
//if (!SetPixelFormat(platform.hdc, pixelFormat, &pixelFormatDesc)) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetPixelFormat", GetLastError()); return -1; }
|
//if (!SetPixelFormat(platform.hdc, pixelFormat, &pixelFormatDesc)) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetPixelFormat", GetLastError()); return -1; }
|
||||||
|
|
||||||
HGLRC tempContext = wglCreateContext(hdc);
|
HGLRC tempContext = wglCreateContext(dummyHDC);
|
||||||
//if (!tempContext) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "wglCreateContext", GetLastError()); return -1; }
|
//if (!tempContext) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "wglCreateContext", GetLastError()); return -1; }
|
||||||
BOOL result = wglMakeCurrent(hdc, tempContext);
|
BOOL result = wglMakeCurrent(dummyHDC, tempContext);
|
||||||
//if (!result) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "wglMakeCurrent", GetLastError()); return -1; }
|
//if (!result) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "wglMakeCurrent", GetLastError()); return -1; }
|
||||||
|
|
||||||
// Load WGL extension entry points
|
// Load WGL extension entry points
|
||||||
@ -1431,8 +1538,11 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
|||||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||||
|
|
||||||
// Setup modern pixel format if extension is available
|
// Setup modern pixel format if extension is available
|
||||||
|
BOOL setPixelFormatSucceeded = FALSE;
|
||||||
if (wglChoosePixelFormatARB)
|
if (wglChoosePixelFormatARB)
|
||||||
{
|
{
|
||||||
|
bool useMSAA = FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT);
|
||||||
|
|
||||||
int pixelFormatAttribs[] = {
|
int pixelFormatAttribs[] = {
|
||||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||||
@ -1440,12 +1550,14 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
|||||||
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
|
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
|
||||||
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
|
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
|
||||||
WGL_COLOR_BITS_ARB, 32,
|
WGL_COLOR_BITS_ARB, 32,
|
||||||
//WGL_RED_BITS_ARB, 8,
|
WGL_RED_BITS_ARB, 8,
|
||||||
//WGL_GREEN_BITS_ARB, 8,
|
WGL_GREEN_BITS_ARB, 8,
|
||||||
//WGL_BLUE_BITS_ARB, 8,
|
WGL_BLUE_BITS_ARB, 8,
|
||||||
//WGL_ALPHA_BITS_ARB, 8,
|
WGL_ALPHA_BITS_ARB, 8,
|
||||||
WGL_DEPTH_BITS_ARB, 24,
|
WGL_DEPTH_BITS_ARB, 24,
|
||||||
WGL_STENCIL_BITS_ARB, 8,
|
WGL_STENCIL_BITS_ARB, 8,
|
||||||
|
WGL_SAMPLES_ARB, (useMSAA)? 4 : 0,
|
||||||
|
WGL_SAMPLE_BUFFERS_ARB, (int)useMSAA,
|
||||||
0 // Terminator
|
0 // Terminator
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1455,7 +1567,23 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
|||||||
{
|
{
|
||||||
PIXELFORMATDESCRIPTOR newPixelFormatDescriptor = { 0 };
|
PIXELFORMATDESCRIPTOR newPixelFormatDescriptor = { 0 };
|
||||||
DescribePixelFormat(hdc, format, sizeof(newPixelFormatDescriptor), &newPixelFormatDescriptor);
|
DescribePixelFormat(hdc, format, sizeof(newPixelFormatDescriptor), &newPixelFormatDescriptor);
|
||||||
SetPixelFormat(hdc, format, &newPixelFormatDescriptor);
|
setPixelFormatSucceeded = SetPixelFormat(hdc, format, &newPixelFormatDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!setPixelFormatSucceeded)
|
||||||
|
{
|
||||||
|
// If modern pixel format selection failed, fall back to old SetPixelFormat
|
||||||
|
int pixelFormat = ChoosePixelFormat(hdc, &pixelFormatDesc);
|
||||||
|
setPixelFormatSucceeded = SetPixelFormat(hdc, pixelFormat, &pixelFormatDesc);
|
||||||
|
|
||||||
|
if (setPixelFormatSucceeded)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "WGL: Using legacy pixel format, MSAA not available");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "WGL: Unable to find a suitable pixel format with this graphics driver");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1521,10 +1649,18 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
|||||||
// ERROR_INVALID_PROFILE_ARB (0x2096)
|
// ERROR_INVALID_PROFILE_ARB (0x2096)
|
||||||
if (realContext == NULL) TRACELOG(LOG_ERROR, "GL: Error creating requested context: %lu", GetLastError());
|
if (realContext == NULL) TRACELOG(LOG_ERROR, "GL: Error creating requested context: %lu", GetLastError());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If modern context extension isn't available, fall back to classic context creation
|
||||||
|
realContext = wglCreateContext(hdc);
|
||||||
|
}
|
||||||
|
|
||||||
// Cleanup dummy temp context
|
// Cleanup dummy temp context and window
|
||||||
wglMakeCurrent(NULL, NULL);
|
wglMakeCurrent(NULL, NULL);
|
||||||
wglDeleteContext(tempContext);
|
wglDeleteContext(tempContext);
|
||||||
|
ReleaseDC(dummyWindow, dummyHDC);
|
||||||
|
DestroyWindow(dummyWindow);
|
||||||
|
UnregisterClassW(dummyWindowClass.lpszClassName, dummyWindowClass.hInstance);
|
||||||
|
|
||||||
// Activate real context
|
// Activate real context
|
||||||
if (realContext) wglMakeCurrent(hdc, realContext);
|
if (realContext) wglMakeCurrent(hdc, realContext);
|
||||||
@ -1721,12 +1857,43 @@ int InitPlatform(void)
|
|||||||
// Close platform
|
// Close platform
|
||||||
void ClosePlatform(void)
|
void ClosePlatform(void)
|
||||||
{
|
{
|
||||||
|
// Undo disable cursor if it's locked and unregister raw input devices
|
||||||
|
EnableCursor();
|
||||||
|
|
||||||
|
// Calling DestroyWindow invokes a WindowProc event that sets the FLAG_WINDOW_HIDDEN flag to true
|
||||||
|
// If InitWindow is called again, the hidden flag will be interpreted as something the user requested
|
||||||
|
// Save the current flags and restore them after
|
||||||
|
unsigned int savedFlags = CORE.Window.flags;
|
||||||
|
|
||||||
if (platform.hwnd)
|
if (platform.hwnd)
|
||||||
{
|
{
|
||||||
int result = DestroyWindow(platform.hwnd);
|
// SetWindowIcon uses the same resource for both ICON_BIG and ICON_SMALL
|
||||||
if (result == 0) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed on window destroy [ERROR: %u]", GetLastError());
|
// If this ever changes, this code may have to be updated
|
||||||
|
HICON icon = (HICON)SendMessage(platform.hwnd, WM_GETICON, ICON_BIG, (LPARAM)0);
|
||||||
|
|
||||||
|
BOOL result = DestroyWindow(platform.hwnd);
|
||||||
|
if (!result) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed on window destroy [ERROR: %u]", GetLastError());
|
||||||
|
|
||||||
|
HINSTANCE hInstance = GetModuleHandleW(0);
|
||||||
|
result = UnregisterClassW(CLASS_NAME, hInstance);
|
||||||
|
if (!result) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed to unregister window class [ERROR: %u]", GetLastError());
|
||||||
|
|
||||||
|
if (icon != NULL) DestroyIcon(icon);
|
||||||
|
|
||||||
platform.hwnd = NULL;
|
platform.hwnd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (platform.clipboardText != NULL)
|
||||||
|
{
|
||||||
|
RL_FREE(platform.clipboardText);
|
||||||
|
platform.clipboardText = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CORE.Window.flags = savedFlags;
|
||||||
|
|
||||||
|
#if SUPPORT_WINMM_HIGHRES_TIMER && !SUPPORT_BUSY_WAIT_LOOP
|
||||||
|
timeEndPeriod(1); // Restore time period
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window procedure, message processing callback
|
// Window procedure, message processing callback
|
||||||
|
|||||||
@ -111,6 +111,9 @@ static const char cursorLUT[11][12] = {
|
|||||||
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||||
void ClosePlatform(void); // Close platform
|
void ClosePlatform(void); // Close platform
|
||||||
|
|
||||||
|
// OpenGL extensions loader
|
||||||
|
static void *WebGLGetProcAddress(const char *procName); // Get WebGL extension procedure address, used by rlLoadExtensions()
|
||||||
|
|
||||||
// Error callback event
|
// Error callback event
|
||||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||||
|
|
||||||
@ -1442,7 +1445,7 @@ int InitPlatform(void)
|
|||||||
|
|
||||||
// Load OpenGL extensions
|
// Load OpenGL extensions
|
||||||
// NOTE: GL procedures address loader is required to load extensions
|
// NOTE: GL procedures address loader is required to load extensions
|
||||||
rlLoadExtensions(glfwGetProcAddress);
|
rlLoadExtensions(WebGLGetProcAddress);
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Initialize events callbacks
|
// Initialize events callbacks
|
||||||
@ -1499,6 +1502,24 @@ void ClosePlatform(void)
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get WebGL extension procedure address
|
||||||
|
// WARNING: rlGetProcAddress() uses this loader, so it only returns the functions listed below
|
||||||
|
static void *WebGLGetProcAddress(const char *procName)
|
||||||
|
{
|
||||||
|
void *proc = NULL;
|
||||||
|
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
if (strcmp(procName, "glGenVertexArraysOES") == 0) proc = (void *)glGenVertexArraysOES;
|
||||||
|
else if (strcmp(procName, "glBindVertexArrayOES") == 0) proc = (void *)glBindVertexArrayOES;
|
||||||
|
else if (strcmp(procName, "glDeleteVertexArraysOES") == 0) proc = (void *)glDeleteVertexArraysOES;
|
||||||
|
else if (strcmp(procName, "glDrawArraysInstancedANGLE") == 0) proc = (void *)glDrawArraysInstancedANGLE;
|
||||||
|
else if (strcmp(procName, "glDrawElementsInstancedANGLE") == 0) proc = (void *)glDrawElementsInstancedANGLE;
|
||||||
|
else if (strcmp(procName, "glVertexAttribDivisorANGLE") == 0) proc = (void *)glVertexAttribDivisorANGLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
// GLFW3 callback functions, called on GLFW registered events
|
// GLFW3 callback functions, called on GLFW registered events
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
// GLFW3: Called on errors
|
// GLFW3: Called on errors
|
||||||
|
|||||||
@ -209,6 +209,9 @@ static const char cursorLUT[11][12] = {
|
|||||||
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||||
void ClosePlatform(void); // Close platform
|
void ClosePlatform(void); // Close platform
|
||||||
|
|
||||||
|
// OpenGL extensions loader
|
||||||
|
static void *WebGLGetProcAddress(const char *procName); // Get WebGL extension procedure address, used by rlLoadExtensions()
|
||||||
|
|
||||||
// Emscripten window callback events
|
// Emscripten window callback events
|
||||||
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
|
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
|
||||||
static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData);
|
static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData);
|
||||||
@ -1387,7 +1390,7 @@ int InitPlatform(void)
|
|||||||
|
|
||||||
// Load OpenGL extensions
|
// Load OpenGL extensions
|
||||||
// NOTE: GL procedures address loader is required to load extensions
|
// NOTE: GL procedures address loader is required to load extensions
|
||||||
if (platform.glContext != 0) rlLoadExtensions(emscripten_webgl_get_proc_address);
|
if (platform.glContext != 0) rlLoadExtensions(WebGLGetProcAddress);
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Initialize events callbacks
|
// Initialize events callbacks
|
||||||
@ -1450,6 +1453,24 @@ void ClosePlatform(void)
|
|||||||
if (platform.glContext != 0) emscripten_webgl_destroy_context(platform.glContext);
|
if (platform.glContext != 0) emscripten_webgl_destroy_context(platform.glContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get WebGL extension procedure address
|
||||||
|
// WARNING: rlGetProcAddress() uses this loader, so it only returns the functions listed below
|
||||||
|
static void *WebGLGetProcAddress(const char *procName)
|
||||||
|
{
|
||||||
|
void *proc = NULL;
|
||||||
|
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
if (strcmp(procName, "glGenVertexArraysOES") == 0) proc = (void *)glGenVertexArraysOES;
|
||||||
|
else if (strcmp(procName, "glBindVertexArrayOES") == 0) proc = (void *)glBindVertexArrayOES;
|
||||||
|
else if (strcmp(procName, "glDeleteVertexArraysOES") == 0) proc = (void *)glDeleteVertexArraysOES;
|
||||||
|
else if (strcmp(procName, "glDrawArraysInstancedANGLE") == 0) proc = (void *)glDrawArraysInstancedANGLE;
|
||||||
|
else if (strcmp(procName, "glDrawElementsInstancedANGLE") == 0) proc = (void *)glDrawElementsInstancedANGLE;
|
||||||
|
else if (strcmp(procName, "glVertexAttribDivisorANGLE") == 0) proc = (void *)glVertexAttribDivisorANGLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
// Emscripten callback functions, called on specific browser events
|
// Emscripten callback functions, called on specific browser events
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
// Emscripten: Called on resize event
|
// Emscripten: Called on resize event
|
||||||
|
|||||||
@ -988,7 +988,7 @@ Sound LoadSoundAlias(Sound source)
|
|||||||
{
|
{
|
||||||
Sound sound = { 0 };
|
Sound sound = { 0 };
|
||||||
|
|
||||||
if (source.stream.buffer->data != NULL)
|
if ((source.stream.buffer != NULL) && (source.stream.buffer->data != NULL))
|
||||||
{
|
{
|
||||||
AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
|
AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
|
||||||
|
|
||||||
|
|||||||
@ -2381,10 +2381,31 @@ RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
|
|||||||
float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to)
|
float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to)
|
||||||
Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to)
|
Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to)
|
||||||
|
|
||||||
|
float lengths = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z + cos2Theta*cos2Theta); // |from|*|to|
|
||||||
|
|
||||||
result.x = cross.x;
|
result.x = cross.x;
|
||||||
result.y = cross.y;
|
result.y = cross.y;
|
||||||
result.z = cross.z;
|
result.z = cross.z;
|
||||||
result.w = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z + cos2Theta*cos2Theta) + cos2Theta;
|
result.w = lengths + cos2Theta;
|
||||||
|
|
||||||
|
// Opposite vectors: cross product is zero, rotate 180 degrees around any axis perpendicular to 'from'
|
||||||
|
if ((lengths > 0.0f) && (result.w <= lengths*EPSILON))
|
||||||
|
{
|
||||||
|
if (fabsf(from.x) > fabsf(from.z))
|
||||||
|
{
|
||||||
|
result.x = -from.y;
|
||||||
|
result.y = from.x;
|
||||||
|
result.z = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.x = 0.0f;
|
||||||
|
result.y = -from.z;
|
||||||
|
result.z = from.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.w = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// QuaternionNormalize(q);
|
// QuaternionNormalize(q);
|
||||||
// NOTE: Normalize to essentially nlerp the original and identity to 0.5
|
// NOTE: Normalize to essentially nlerp the original and identity to 0.5
|
||||||
@ -2717,9 +2738,9 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
|||||||
translation->z = mat.m14;
|
translation->z = mat.m14;
|
||||||
|
|
||||||
// Matrix Columns - Rotation will be extracted into here
|
// Matrix Columns - Rotation will be extracted into here
|
||||||
Vector3 matColumns[3] = {{ mat.m0, mat.m4, mat.m8 },
|
Vector3 matColumns[3] = {{ mat.m0, mat.m1, mat.m2 },
|
||||||
{ mat.m1, mat.m5, mat.m9 },
|
{ mat.m4, mat.m5, mat.m6 },
|
||||||
{ mat.m2, mat.m6, mat.m10 }};
|
{ mat.m8, mat.m9, mat.m10 }};
|
||||||
|
|
||||||
// Shear Parameters XY, XZ, and YZ (extract and ignored)
|
// Shear Parameters XY, XZ, and YZ (extract and ignored)
|
||||||
float shear[3] = { 0 };
|
float shear[3] = { 0 };
|
||||||
@ -2783,9 +2804,9 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
|||||||
*scale = Vector3Scale(scl, stabilizer);
|
*scale = Vector3Scale(scl, stabilizer);
|
||||||
|
|
||||||
// Extract Rotation
|
// Extract Rotation
|
||||||
Matrix rotationMatrix = { matColumns[0].x, matColumns[0].y, matColumns[0].z, 0,
|
Matrix rotationMatrix = { matColumns[0].x, matColumns[1].x, matColumns[2].x, 0,
|
||||||
matColumns[1].x, matColumns[1].y, matColumns[1].z, 0,
|
matColumns[0].y, matColumns[1].y, matColumns[2].y, 0,
|
||||||
matColumns[2].x, matColumns[2].y, matColumns[2].z, 0,
|
matColumns[0].z, matColumns[1].z, matColumns[2].z, 0,
|
||||||
0, 0, 0, 1 };
|
0, 0, 0, 1 };
|
||||||
*rotation = QuaternionFromMatrix(rotationMatrix);
|
*rotation = QuaternionFromMatrix(rotationMatrix);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4174,31 +4174,45 @@ RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius)
|
|||||||
|
|
||||||
Vector3 raySpherePos = Vector3Subtract(center, ray.position);
|
Vector3 raySpherePos = Vector3Subtract(center, ray.position);
|
||||||
float vector = Vector3DotProduct(raySpherePos, ray.direction);
|
float vector = Vector3DotProduct(raySpherePos, ray.direction);
|
||||||
float distance = Vector3Length(raySpherePos);
|
float distanceToCenter = Vector3Length(raySpherePos);
|
||||||
float d = radius*radius - (distance*distance - vector*vector);
|
float d = radius*radius - (distanceToCenter*distanceToCenter - vector*vector);
|
||||||
|
|
||||||
collision.hit = d >= 0.0f;
|
// Check if the ray's line intersects with the sphere
|
||||||
|
if (d >= 0.0f)
|
||||||
|
{
|
||||||
|
Vector3 point = { 0 };
|
||||||
|
Vector3 normal = { 0 };
|
||||||
|
float hitDistance = 0.0f;
|
||||||
|
|
||||||
// Check if ray origin is inside the sphere to calculate the correct collision point
|
// Check if ray origin is inside the sphere to calculate the correct collision point
|
||||||
if (distance < radius)
|
if (distanceToCenter < radius)
|
||||||
{
|
{
|
||||||
collision.distance = vector + sqrtf(d);
|
hitDistance = vector + sqrtf(d);
|
||||||
|
|
||||||
// Calculate collision point
|
// Calculate collision point
|
||||||
collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
|
point = Vector3Add(ray.position, Vector3Scale(ray.direction, hitDistance));
|
||||||
|
|
||||||
// Calculate collision normal (pointing outwards)
|
// Calculate collision normal (pointing outwards)
|
||||||
collision.normal = Vector3Negate(Vector3Normalize(Vector3Subtract(collision.point, center)));
|
normal = Vector3Negate(Vector3Normalize(Vector3Subtract(point, center)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
collision.distance = vector - sqrtf(d);
|
hitDistance = vector - sqrtf(d);
|
||||||
|
|
||||||
// Calculate collision point
|
// Calculate collision point
|
||||||
collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
|
point = Vector3Add(ray.position, Vector3Scale(ray.direction, hitDistance));
|
||||||
|
|
||||||
// Calculate collision normal (pointing inwards)
|
// Calculate collision normal (pointing inwards)
|
||||||
collision.normal = Vector3Normalize(Vector3Subtract(collision.point, center));
|
normal = Vector3Normalize(Vector3Subtract(point, center));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hitDistance >= 0.0f)
|
||||||
|
{
|
||||||
|
collision.hit = true;
|
||||||
|
collision.point = point;
|
||||||
|
collision.normal = normal;
|
||||||
|
collision.distance = hitDistance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return collision;
|
return collision;
|
||||||
|
|||||||
@ -4242,29 +4242,15 @@ void ImageDrawImageEx(Image *dst, Image src, Vector2 position, float rotation, f
|
|||||||
|
|
||||||
Color srcColor = GetImageColor(src, srcX, srcY);
|
Color srcColor = GetImageColor(src, srcX, srcY);
|
||||||
|
|
||||||
// Apply tint
|
|
||||||
srcColor.r = (unsigned char)(srcColor.r*tint.r/255.0f);
|
|
||||||
srcColor.g = (unsigned char)(srcColor.g*tint.g/255.0f);
|
|
||||||
srcColor.b = (unsigned char)(srcColor.b*tint.b/255.0f);
|
|
||||||
srcColor.a = (unsigned char)(srcColor.a*tint.a/255.0f);
|
|
||||||
|
|
||||||
// Skip fully transparent pixels
|
// Skip fully transparent pixels
|
||||||
if (srcColor.a == 0) continue;
|
if (srcColor.a == 0) continue;
|
||||||
|
|
||||||
// Read destination pixel for alpha blending
|
// Read destination pixel and blend source over it, applying tint
|
||||||
|
// NOTE: ColorAlphaBlend() takes destination alpha into account,
|
||||||
|
// same as ImageDrawImagePro(), required to draw on transparent images
|
||||||
Color dstColor = GetImageColor(*dst, x, y);
|
Color dstColor = GetImageColor(*dst, x, y);
|
||||||
|
|
||||||
unsigned int alpha = srcColor.a;
|
ImageDrawPixel(dst, x, y, ColorAlphaBlend(dstColor, srcColor, tint));
|
||||||
unsigned int invA = 255 - alpha;
|
|
||||||
|
|
||||||
Color out = {
|
|
||||||
(unsigned char)((srcColor.r*alpha + dstColor.r*invA)/255), // red
|
|
||||||
(unsigned char)((srcColor.g*alpha + dstColor.g*invA)/255), // green
|
|
||||||
(unsigned char)((srcColor.b*alpha + dstColor.b*invA)/255), // blue
|
|
||||||
(unsigned char)(alpha + (dstColor.a*invA)/255) // alpha
|
|
||||||
};
|
|
||||||
|
|
||||||
ImageDrawPixel(dst, x, y, out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1161,7 +1161,8 @@ int main(int argc, char *argv[])
|
|||||||
// Validate: example screenshot is not the template default one
|
// Validate: example screenshot is not the template default one
|
||||||
Image imScreenshot = LoadImage(TextFormat("%s/%s/%s.png", exBasePath, exInfo->category, exInfo->name));
|
Image imScreenshot = LoadImage(TextFormat("%s/%s/%s.png", exBasePath, exInfo->category, exInfo->name));
|
||||||
Image imTemplate = LoadImage(TextFormat("%s/examples_template.png", exBasePath));
|
Image imTemplate = LoadImage(TextFormat("%s/examples_template.png", exBasePath));
|
||||||
if (memcmp(imScreenshot.data, imTemplate.data, GetPixelDataSize(imScreenshot.width, imScreenshot.height, imScreenshot.format)) == 0)
|
bool imSameSize = (imScreenshot.width == imTemplate.width) && (imScreenshot.height == imTemplate.height);
|
||||||
|
if (imSameSize && (memcmp(imScreenshot.data, imTemplate.data, GetPixelDataSize(imScreenshot.width, imScreenshot.height, imScreenshot.format)) == 0))
|
||||||
exInfo->status |= VALID_INVALID_PNG;
|
exInfo->status |= VALID_INVALID_PNG;
|
||||||
UnloadImage(imTemplate);
|
UnloadImage(imTemplate);
|
||||||
UnloadImage(imScreenshot);
|
UnloadImage(imScreenshot);
|
||||||
|
|||||||
Reference in New Issue
Block a user