mirror of
https://github.com/raysan5/raylib.git
synced 2026-10-10 19:51:55 -04:00
Compare commits
17 Commits
607a659363
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 453cc35f27 | |||
| bc77441de0 | |||
| 89650b5b9e | |||
| 0b5fab1123 | |||
| e453e80bed | |||
| c5958f5832 | |||
| fd0f4c185b | |||
| 84e4a2a257 | |||
| 9056ea3299 | |||
| 806d68a9bc | |||
| 3825bbf2d4 | |||
| c8b19b297b | |||
| a043255aa7 | |||
| 8c23ce44a0 | |||
| 48aaf6e2df | |||
| 0ed3570469 | |||
| 2dee47282a |
84
CHANGELOG
84
CHANGELOG
@ -4,14 +4,14 @@ changelog
|
||||
Current Release: raylib 6.0 (23 April 2026)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Release: raylib 6.2 (xx Sep 2026)
|
||||
Release: raylib 6.2 (xx Oct 2026)
|
||||
-------------------------------------------------------------------------
|
||||
KEY CHANGES:
|
||||
- REDESIGNED: Image API for more alignment with Texture API
|
||||
- REDESIGNED: File API for more standard return result values
|
||||
- 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: `IsPathAbsolute()`, check absolute paths 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: `GetPrevDirectoryPath()` behavior to better support side cases (#6073) by @luphi
|
||||
[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: Borderless-windowed mode being always on top (#5868) by @auwsmit
|
||||
[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][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][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: 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: 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][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: Security fixes (#5899) by @M374LX
|
||||
[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: 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: Invert emscripten scroll wheel direction (#6104) 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: `DrawRectangleLinesEx()` (#6027) 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: `ImageDrawLineStrip()` by @raysan5
|
||||
[rtextures] ADDED: `DrawTriangleGradient()` by @raysan5
|
||||
[rtextures] ADDED: `DrawCircleLinesEx()`, simpler naming than `DrawRing()` 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] REDESIGNED: `ImageDraw()`, align with `DrawTexture()` 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: `GetPixelDataSize()`, avoid allocations >2GB - ROS: `CLN-013` 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: `TextToSnake()`, not considering spaces properly by @raysan5
|
||||
[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: `TextInsert()`/`TextInsertAlloc()` (#6021) by @SewerynKaminski
|
||||
[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] 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: 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: `IsModelValid()` #5780 by @raysan5
|
||||
[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: `DrawCapsule()`, `DrawCapsuleWires()`, validate minimum rings (#5909) by @LuisR385
|
||||
[rmodels] REVIEWED: `UnloadModel()`, fix memory leak (#5907) by @LuisR385
|
||||
[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: `UpdateModelAnimation()`, compute bone normal matrices once per bone instead of per vertex (#6191) by @4RH1T3CT0R7 -WARNING-
|
||||
[raudio] REVIEWED: `UpdateSound()`, missleading parameter name by @raysan5
|
||||
[raudio] REVIEWED: `UnloadSoundAlias()`, prevent leak (#5857) by @Peter0x44
|
||||
[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
|
||||
[raymath] ADDED: Operator overload for (float * Vector) (#5815) by @alphahex99
|
||||
[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: 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: 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: 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][CMake] ADDED: Support for Win32 platform + examples (#5855) by @CrackedPixel
|
||||
[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 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: Fix install export with vendored SDL (#6173) by @RobLoach
|
||||
[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 web examples all the time (#6006) 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: `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: `setup-emsdk`, use latest actions version by @raysan5
|
||||
|
||||
[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: gclang-raylib (6.0) (#5850) by @gnuchanos
|
||||
[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: raylib-py to raylib 6.0 (#6095) by @overdev
|
||||
[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: `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_thickness` (#6037) 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] REVIEWED: `shaders_shadowmap_rendering` by @raysan5
|
||||
[examples] REVIEWED: `models_mesh_uv_painting` by @raysan5
|
||||
[examples] REVIEWED: `shaders_lights_bloom` by @raysan5
|
||||
[examples] REVIEWED: `textures_portal_window` by @raysan5
|
||||
[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] 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_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: `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_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_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] 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: miniaudio to 0.11.25 (#6050) by @M374LX
|
||||
[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: `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: `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)
|
||||
|
||||
@ -68,6 +68,14 @@ void SomeFunction()
|
||||
{
|
||||
// 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.**
|
||||
|
||||
@ -131,7 +131,7 @@ int main(void)
|
||||
DrawText("Left/right to change wave type", 10, 30, 20, DARKGRAY);
|
||||
|
||||
// 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 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
|
||||
char gestureLog[GESTURE_LOG_SIZE][12] = { "" };
|
||||
// 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;
|
||||
|
||||
// Log mode values:
|
||||
|
||||
@ -114,7 +114,7 @@ int main(void)
|
||||
|
||||
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
||||
|
||||
if (!animPause)
|
||||
if (!animPause && (animCount > 0)) // Animations could fail to load
|
||||
{
|
||||
// Start transition from anim0[] to anim1[]
|
||||
if (IsKeyPressed(KEY_SPACE) && !animTransition)
|
||||
@ -256,21 +256,24 @@ int main(void)
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize);
|
||||
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||
|
||||
// Draw playing timeline with keyframes for anim0[]
|
||||
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 60.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 0",
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex0].keyframeCount; i++)
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 60, 1, 20, BLUE);
|
||||
if (animCount > 0)
|
||||
{
|
||||
// Draw playing timeline with keyframes for anim0[]
|
||||
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 60.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 0",
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex0].keyframeCount; i++)
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 60, 1, 20, BLUE);
|
||||
|
||||
// Draw playing timeline with keyframes for anim1[]
|
||||
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 30.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 1",
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
|
||||
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 30, 1, 20, BLUE);
|
||||
// Draw playing timeline with keyframes for anim1[]
|
||||
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 30.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 1",
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
|
||||
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 30, 1, 20, BLUE);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
EndDrawing();
|
||||
|
||||
@ -316,7 +316,7 @@ static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3])
|
||||
static void FreeMeshBuilder(MeshBuilder *mb)
|
||||
{
|
||||
MemFree(mb->vertices);
|
||||
if (mb->uvs) MemFree(mb->uvs);
|
||||
if (mb->uvs != NULL) MemFree(mb->uvs);
|
||||
*mb = (MeshBuilder){ 0 };
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ static Mesh BuildMesh(MeshBuilder *mb)
|
||||
outMesh.vertexCount = mb->vertexCount;
|
||||
outMesh.triangleCount = mb->vertexCount/3;
|
||||
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++)
|
||||
{
|
||||
@ -336,7 +336,7 @@ static Mesh BuildMesh(MeshBuilder *mb)
|
||||
outMesh.vertices[3*i+1] = mb->vertices[i].y;
|
||||
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+1] = mb->uvs[i].y;
|
||||
|
||||
@ -149,7 +149,7 @@ int main(void)
|
||||
|
||||
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib [others] example - rlgl standalone", NULL, NULL);
|
||||
|
||||
if (!window)
|
||||
if (window == NULL)
|
||||
{
|
||||
glfwTerminate();
|
||||
return 2;
|
||||
|
||||
@ -50,7 +50,7 @@ int main(void)
|
||||
if (IsKeyPressed(KEY_R)) // Reset image collection
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
@ -98,7 +98,7 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < MAX_TEXTURE_COLLECTION;i ++)
|
||||
for (int i = 0; i < currentCollectionIndex; i++)
|
||||
{
|
||||
UnloadTexture(collection[i].texture);
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ int main(void)
|
||||
if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON)) curveSelectedPoint = NULL;
|
||||
|
||||
// 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
|
||||
Vector2 mouse = GetMousePosition();
|
||||
|
||||
@ -97,6 +97,8 @@ typedef struct {
|
||||
unsigned int desiredFlags;
|
||||
|
||||
LARGE_INTEGER timerFrequency;
|
||||
|
||||
char *clipboardText;
|
||||
} PlatformData;
|
||||
|
||||
// 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 };
|
||||
|
||||
// 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)",
|
||||
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
|
||||
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
|
||||
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
|
||||
const char *GetClipboardText(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetClipboardText not implemented");
|
||||
return NULL;
|
||||
if (platform.clipboardText != 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
|
||||
@ -1767,12 +1857,43 @@ int InitPlatform(void)
|
||||
// Close platform
|
||||
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)
|
||||
{
|
||||
int result = DestroyWindow(platform.hwnd);
|
||||
if (result == 0) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed on window destroy [ERROR: %u]", GetLastError());
|
||||
// SetWindowIcon uses the same resource for both ICON_BIG and ICON_SMALL
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -988,7 +988,7 @@ Sound LoadSoundAlias(Sound source)
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
@ -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)
|
||||
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.y = cross.y;
|
||||
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);
|
||||
// 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;
|
||||
|
||||
// Matrix Columns - Rotation will be extracted into here
|
||||
Vector3 matColumns[3] = {{ mat.m0, mat.m4, mat.m8 },
|
||||
{ mat.m1, mat.m5, mat.m9 },
|
||||
{ mat.m2, mat.m6, mat.m10 }};
|
||||
Vector3 matColumns[3] = {{ mat.m0, mat.m1, mat.m2 },
|
||||
{ mat.m4, mat.m5, mat.m6 },
|
||||
{ mat.m8, mat.m9, mat.m10 }};
|
||||
|
||||
// Shear Parameters XY, XZ, and YZ (extract and ignored)
|
||||
float shear[3] = { 0 };
|
||||
@ -2783,10 +2804,10 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
||||
*scale = Vector3Scale(scl, stabilizer);
|
||||
|
||||
// Extract Rotation
|
||||
Matrix rotationMatrix = { matColumns[0].x, matColumns[0].y, matColumns[0].z, 0,
|
||||
matColumns[1].x, matColumns[1].y, matColumns[1].z, 0,
|
||||
matColumns[2].x, matColumns[2].y, matColumns[2].z, 0,
|
||||
0, 0, 0, 1 };
|
||||
Matrix rotationMatrix = { matColumns[0].x, matColumns[1].x, matColumns[2].x, 0,
|
||||
matColumns[0].y, matColumns[1].y, matColumns[2].y, 0,
|
||||
matColumns[0].z, matColumns[1].z, matColumns[2].z, 0,
|
||||
0, 0, 0, 1 };
|
||||
*rotation = QuaternionFromMatrix(rotationMatrix);
|
||||
}
|
||||
|
||||
|
||||
@ -4174,31 +4174,45 @@ RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius)
|
||||
|
||||
Vector3 raySpherePos = Vector3Subtract(center, ray.position);
|
||||
float vector = Vector3DotProduct(raySpherePos, ray.direction);
|
||||
float distance = Vector3Length(raySpherePos);
|
||||
float d = radius*radius - (distance*distance - vector*vector);
|
||||
float distanceToCenter = Vector3Length(raySpherePos);
|
||||
float d = radius*radius - (distanceToCenter*distanceToCenter - vector*vector);
|
||||
|
||||
collision.hit = d >= 0.0f;
|
||||
|
||||
// Check if ray origin is inside the sphere to calculate the correct collision point
|
||||
if (distance < radius)
|
||||
// Check if the ray's line intersects with the sphere
|
||||
if (d >= 0.0f)
|
||||
{
|
||||
collision.distance = vector + sqrtf(d);
|
||||
Vector3 point = { 0 };
|
||||
Vector3 normal = { 0 };
|
||||
float hitDistance = 0.0f;
|
||||
|
||||
// Calculate collision point
|
||||
collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
|
||||
// Check if ray origin is inside the sphere to calculate the correct collision point
|
||||
if (distanceToCenter < radius)
|
||||
{
|
||||
hitDistance = vector + sqrtf(d);
|
||||
|
||||
// Calculate collision normal (pointing outwards)
|
||||
collision.normal = Vector3Negate(Vector3Normalize(Vector3Subtract(collision.point, center)));
|
||||
}
|
||||
else
|
||||
{
|
||||
collision.distance = vector - sqrtf(d);
|
||||
// Calculate collision point
|
||||
point = Vector3Add(ray.position, Vector3Scale(ray.direction, hitDistance));
|
||||
|
||||
// Calculate collision point
|
||||
collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
|
||||
// Calculate collision normal (pointing outwards)
|
||||
normal = Vector3Negate(Vector3Normalize(Vector3Subtract(point, center)));
|
||||
}
|
||||
else
|
||||
{
|
||||
hitDistance = vector - sqrtf(d);
|
||||
|
||||
// Calculate collision normal (pointing inwards)
|
||||
collision.normal = Vector3Normalize(Vector3Subtract(collision.point, center));
|
||||
// Calculate collision point
|
||||
point = Vector3Add(ray.position, Vector3Scale(ray.direction, hitDistance));
|
||||
|
||||
// Calculate collision normal (pointing inwards)
|
||||
normal = Vector3Normalize(Vector3Subtract(point, center));
|
||||
}
|
||||
|
||||
if (hitDistance >= 0.0f)
|
||||
{
|
||||
collision.hit = true;
|
||||
collision.point = point;
|
||||
collision.normal = normal;
|
||||
collision.distance = hitDistance;
|
||||
}
|
||||
}
|
||||
|
||||
return collision;
|
||||
|
||||
@ -1161,7 +1161,8 @@ int main(int argc, char *argv[])
|
||||
// Validate: example screenshot is not the template default one
|
||||
Image imScreenshot = LoadImage(TextFormat("%s/%s/%s.png", exBasePath, exInfo->category, exInfo->name));
|
||||
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;
|
||||
UnloadImage(imTemplate);
|
||||
UnloadImage(imScreenshot);
|
||||
|
||||
Reference in New Issue
Block a user