4 Commits

Author SHA1 Message Date
Ray
e18de07224 Update rcore_desktop_win32.c 2026-10-05 10:19:16 +02:00
Ray
3c1ab87ae1 Update Makefile 2026-10-05 10:19:08 +02:00
Ray
e8b23bfbe4 Minor tweaks 2026-10-05 09:39:02 +02:00
e5c0709fa2 [Examples] Clarify Camera2d.offset and how it works with High DPI scale mode (#6203)
* rlparser: update raylib_api.* by CI

* Notate that the offset in Camera2d is in pixels space (unscaled by DPI)
Update all the examples that use Camera2d.offset so that they are DPI aware if the user enables DPI scaling.

* rlparser: update raylib_api.* by CI

* remove DPI flag

* remove gltf tests that should not have been part of this PR

* formatting

* formatting

* formatting

* more formatting

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-05 09:29:59 +02:00
17 changed files with 50 additions and 51 deletions

View File

@ -54,7 +54,7 @@ int main(void)
Camera2D camera = { 0 };
camera.target = (Vector2){ player.x + 20.0f, player.y + 20.0f };
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
camera.rotation = 0.0f;
camera.zoom = 1.0f;

View File

@ -65,8 +65,8 @@ int main(void)
// Get the world point that is under the mouse
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
// Set the offset to where the mouse is
camera.offset = GetMousePosition();
// Set the offset to where the mouse is, mouse is scaled to viewport space, but offset is in unscaled pixels
camera.offset = Vector2Multiply(GetMousePosition(), GetWindowScaleDPI());
// Set the target to match, so that the camera maps the world space point
// under the cursor to the screen space point under the cursor at any zoom
@ -86,8 +86,8 @@ int main(void)
// Get the world point that is under the mouse
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
// Set the offset to where the mouse is
camera.offset = GetMousePosition();
// Set the offset to where the mouse is, mouse is scaled to viewport space, but offset is in unscaled pixels
camera.offset = Vector2Multiply(GetMousePosition(), GetWindowScaleDPI());
// Set the target to match, so that the camera maps the world space point
// under the cursor to the screen space point under the cursor at any zoom

View File

@ -75,7 +75,7 @@ int main(void)
Camera2D camera = { 0 };
camera.target = player.position;
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
camera.rotation = 0.0f;
camera.zoom = 1.0f;

View File

@ -19,6 +19,7 @@
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#define PLAYER_SIZE 40
@ -39,13 +40,13 @@ int main(void)
Camera2D camera1 = { 0 };
camera1.target = (Vector2){ player1.x, player1.y };
camera1.offset = (Vector2){ 200.0f, 200.0f };
camera1.offset = Vector2Multiply((Vector2){ 200.0f, 200.0f }, GetWindowScaleDPI());
camera1.rotation = 0.0f;
camera1.zoom = 1.0f;
Camera2D camera2 = { 0 };
camera2.target = (Vector2){ player2.x, player2.y };
camera2.offset = (Vector2){ 200.0f, 200.0f };
camera2.offset = Vector2Multiply((Vector2){ 200.0f, 200.0f }, GetWindowScaleDPI());
camera2.rotation = 0.0f;
camera2.zoom = 1.0f;

View File

@ -69,7 +69,7 @@ int main(void)
// Define camera
Camera2D camera = { 0 };
camera.target = player.position;
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
camera.rotation = 0.0f;
camera.zoom = 1.0f;
@ -117,7 +117,7 @@ int main(void)
player.canJump = false;
camera.target = player.position;
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
camera.rotation = 0.0f;
camera.zoom = 1.0f;
}
@ -169,7 +169,7 @@ int main(void)
player.canJump = false;
camera.target = player.position;
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
camera.rotation = 0.0f;
camera.zoom = 1.0f;
}
@ -205,7 +205,7 @@ int main(void)
// Update camera
//----------------------------------------------------------------------------------
camera.target = player.position;
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
float minX = 1000, minY = 1000, maxX = -1000, maxY = -1000;
// WARNING: On event replay, mouse-wheel internal value is set
@ -267,7 +267,7 @@ int main(void)
player.canJump = false;
camera.target = player.position;
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
camera.rotation = 0.0f;
camera.zoom = 1.0f;
}

View File

@ -106,4 +106,3 @@ int main(void)
}

View File

@ -56,7 +56,7 @@ int main(void)
Vector2 mousePos = { 0 };
Vector2 prevMousePos = { 0 };
Vector2 scaleVector = { 1.0f, -1.0f };
Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
Vector2 offset = { GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
Camera2D camera = { 0 };
camera.target = (Vector2){ 0 };

View File

@ -16,12 +16,13 @@
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#include <stdio.h>
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
#include <math.h>
#include <stdio.h>
#define MAX_PIE_SLICES 10 // Max pie slices
//------------------------------------------------------------------------------------
@ -39,12 +40,8 @@ int main(void)
int sliceCount = 7;
float donutInnerRadius = 25.0f;
float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
char labels[MAX_PIE_SLICES][32] = { 0 };
bool editingLabel[MAX_PIE_SLICES] = { 0 };
for (int i = 0; i < MAX_PIE_SLICES; i++)
snprintf(labels[i], 32, "Slice %02i", i + 1);
bool showValues = true;
bool showPercentages = false;
bool showDonut = false;
@ -59,7 +56,7 @@ int main(void)
// UI Panel top-left anchor
const Vector2 panelPos = {
(float)screenWidth - panelMargin - panelWidth,
(float)screenWidth - panelMargin - panelWidth,
(float)panelMargin
};
@ -72,7 +69,7 @@ int main(void)
// Pie chart geometry
const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
const Vector2 center = { canvas.width/2.0f, canvas.height/2.0f};
const Vector2 center = { canvas.width/2.0f, canvas.height/2.0f };
const float radius = 205.0f;
// Total value for percentage calculations
@ -93,6 +90,7 @@ int main(void)
// Check for mouse hover over slices
hoveredSlice = -1; // Reset hovered slice
Vector2 mousePos = GetMousePosition();
if (CheckCollisionPointRec(mousePos, canvas)) // Only check if mouse is inside the canvas
{
float dx = mousePos.x - center.x;
@ -176,7 +174,7 @@ int main(void)
if (showDonut) GuiDisable();
GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
"Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
"Inner Radius", NULL, & donutInnerRadius, 5.0f, radius - 10.0f);
GuiEnable();
GuiLine((Rectangle){ panelPos.x + 10, (float)panelPos.y + 12 + 170, panelRect.width - 20, 1 }, NULL);
@ -190,8 +188,7 @@ int main(void)
};
int contentHeight = sliceCount*35;
GuiScrollPanel(scrollPanelBounds, NULL,
(Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
GuiScrollPanel(scrollPanelBounds, NULL, (Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
&scrollContentOffset, &view);
const float contentX = view.x + scrollContentOffset.x; // Left of content
@ -208,7 +205,8 @@ int main(void)
DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
// Label textbox
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, labels[i], 32, editingLabel[i])) editingLabel[i] = !editingLabel[i];
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, TextFormat("Slice %02i", i + 1), 32, editingLabel[i]))
editingLabel[i] = !editingLabel[i];
GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
}

View File

@ -16,7 +16,9 @@
********************************************************************************************/
#include "raylib.h"
#include "rlgl.h" // for rlSetBlendFactorsSeparate()
#include "rlgl.h" // Required for: rlSetBlendFactorsSeparate()
#include "raymath.h" // Required for: Vector2Multiply()
//------------------------------------------------------------------------------------
// Program main entry point
@ -45,8 +47,7 @@ int main(void)
// Set magnifying glass zoom
camera.zoom = 2;
// Offset by half the size of the magnifying glass to counteract drawing the texture centered on the mouse position
camera.offset = (Vector2){128, 128};
camera.offset = Vector2Multiply((Vector2){ 128, 128 }, GetWindowScaleDPI());
SetTargetFPS(60);
//--------------------------------------------------------------------------------------

View File

@ -356,6 +356,16 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
AR = $(ANDROID_TOOLCHAIN)/bin/llvm-ar
endif
# NOTE: Native Linux links against glibc, on glibc >= 2.38, _GNU_SOURCE redirects
# sscanf(), strtol()... to __isoc23_*(), so the library fails to link with older glibc
# Web and Android set PLATFORM_OS from the host, but they are not glibc and keep _GNU_SOURCE
DEFINED_SOURCE_MACRO = _GNU_SOURCE
ifeq ($(PLATFORM_OS), LINUX)
ifeq ($(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW PLATFORM_ANDROID),)
DEFINED_SOURCE_MACRO = _DEFAULT_SOURCE
endif
endif
# Define compiler flags: CFLAGS
#------------------------------------------------------------------------------------------------
# -O1 defines optimization level
@ -370,17 +380,7 @@ endif
# -D_GNU_SOURCE access to lots of nonstandard GNU/Linux extension functions
# -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers
# -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing)
# NOTE: Native Linux links against glibc. On glibc >= 2.38, _GNU_SOURCE redirects
# sscanf(), strtol()... to __isoc23_*(), so the library fails to link with older glibc.
# Web and Android set PLATFORM_OS from the host, but they are not glibc and keep _GNU_SOURCE.
FEATURE_TEST_MACRO = _GNU_SOURCE
ifeq ($(PLATFORM_OS), LINUX)
ifeq ($(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW PLATFORM_ANDROID),)
FEATURE_TEST_MACRO = _DEFAULT_SOURCE
endif
endif
CFLAGS = -Wall -D$(FEATURE_TEST_MACRO) -D$(TARGET_PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing
CFLAGS = -Wall -D$(DEFINED_SOURCE_MACRO) -D$(TARGET_PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing
ifneq ($(RAYLIB_CONFIG_FLAGS), NONE)
CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS)

View File

@ -92,8 +92,8 @@ typedef struct {
HBITMAP hbitmap; // GDI bitmap handler
unsigned int *pixels; // Pointer to pixel data buffer (BGRA format)
unsigned int appScreenWidth;
unsigned int appScreenHeight;
int appScreenWidth;
int appScreenHeight;
unsigned int desiredFlags;
LARGE_INTEGER timerFrequency;
@ -1957,8 +1957,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
case WM_DPICHANGED:
{
// Get current dpi scale factor
float scalex = HIWORD(wparam)/96.0f;
float scaley = LOWORD(wparam)/96.0f;
//float scalex = HIWORD(wparam)/96.0f;
//float scaley = LOWORD(wparam)/96.0f;
RECT *suggestedRect = (RECT *)lparam;

View File

@ -336,7 +336,7 @@ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
// Camera2D, defines position/orientation in 2d space
typedef struct Camera2D {
Vector2 offset; // Camera offset (screen space offset from window origin)
Vector2 offset; // Camera offset (screen space offset from window origin, unscaled by DPI, real pixel size)
Vector2 target; // Camera target (world space target point that is mapped to screen space offset)
float rotation; // Camera rotation in degrees (pivots around target)
float zoom; // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale

View File

@ -763,7 +763,7 @@
{
"type": "Vector2",
"name": "offset",
"description": "Camera offset (screen space offset from window origin)"
"description": "Camera offset (screen space offset from window origin, unscaled by DPI, real pixel size)"
},
{
"type": "Vector2",

View File

@ -763,7 +763,7 @@ return {
{
type = "Vector2",
name = "offset",
description = "Camera offset (screen space offset from window origin)"
description = "Camera offset (screen space offset from window origin, unscaled by DPI, real pixel size)"
},
{
type = "Vector2",

View File

@ -486,7 +486,7 @@
(fields
((type "Vector2")
(name "offset")
(description "Camera offset (screen space offset from window origin)"))
(description "Camera offset (screen space offset from window origin, unscaled by DPI, real pixel size)"))
((type "Vector2")
(name "target")
(description "Camera target (world space target point that is mapped to screen space offset)"))

View File

@ -394,7 +394,7 @@ Struct 13: Camera3D (5 fields)
Struct 14: Camera2D (4 fields)
Name: Camera2D
Description: Camera2D, defines position/orientation in 2d space
Field[1]: Vector2 offset // Camera offset (screen space offset from window origin)
Field[1]: Vector2 offset // Camera offset (screen space offset from window origin, unscaled by DPI, real pixel size)
Field[2]: Vector2 target // Camera target (world space target point that is mapped to screen space offset)
Field[3]: float rotation // Camera rotation in degrees (pivots around target)
Field[4]: float zoom // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale

View File

@ -154,7 +154,7 @@
<Field type="int" name="projection" desc="Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC" />
</Struct>
<Struct name="Camera2D" fieldCount="4" desc="Camera2D, defines position/orientation in 2d space">
<Field type="Vector2" name="offset" desc="Camera offset (screen space offset from window origin)" />
<Field type="Vector2" name="offset" desc="Camera offset (screen space offset from window origin, unscaled by DPI, real pixel size)" />
<Field type="Vector2" name="target" desc="Camera target (world space target point that is mapped to screen space offset)" />
<Field type="float" name="rotation" desc="Camera rotation in degrees (pivots around target)" />
<Field type="float" name="zoom" desc="Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale" />