fixes 3372 by implement hi dpi aware in raylib
This commit is contained in:
parent
87cd7aee4d
commit
e014ce32c1
|
|
@ -99,6 +99,7 @@ elseif (${PLATFORM} MATCHES "Web")
|
|||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
|
||||
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s EXPORTED_FUNCTIONS=_main,_SetHighDPIAware,_FullscreenCallback -s EXPORTED_RUNTIME_METHODS=cwrap")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||
bool isHighDPIAware;
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -116,6 +117,15 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
|
|||
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
|
||||
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData);
|
||||
|
||||
static bool IsHighDPIAware();
|
||||
static float GetDevicePixelRatio();
|
||||
static void InstallModuleJSAPI();
|
||||
static void AdjustWindowSize(int width, int height, int fbWidth, int fbHeight);
|
||||
static void AdjustFrameBufferSize(int fbWidth, int fbHeight);
|
||||
|
||||
void SetHighDPIAware(bool flag);
|
||||
void FullscreenCallback(bool isFullscreen);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -298,7 +308,8 @@ void SetWindowMaxSize(int width, int height)
|
|||
// Set window dimensions
|
||||
void SetWindowSize(int width, int height)
|
||||
{
|
||||
glfwSetWindowSize(platform.handle, width, height);
|
||||
// glfwSetWindowSize(platform.handle, width, height);
|
||||
WindowSizeCallback(platform.handle, width, height);
|
||||
}
|
||||
|
||||
// Set window opacity, value opacity is between 0.0 and 1.0
|
||||
|
|
@ -723,6 +734,11 @@ int InitPlatform(void)
|
|||
glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0
|
||||
}
|
||||
|
||||
if (CORE.Window.flags & FLAG_WINDOW_HIGHDPI)
|
||||
{
|
||||
platform.isHighDPIAware = true;
|
||||
}
|
||||
|
||||
// NOTE: When asking for an OpenGL context version, most drivers provide the highest supported version
|
||||
// with backward compatibility to older OpenGL versions.
|
||||
// For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context.
|
||||
|
|
@ -867,25 +883,14 @@ int InitPlatform(void)
|
|||
glfwMakeContextCurrent(platform.handle);
|
||||
result = true; // TODO: WARNING: glfwGetError(NULL); symbol can not be found in Web
|
||||
|
||||
InstallModuleJSAPI();
|
||||
|
||||
// Check context activation
|
||||
if (result == true) //(result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR))
|
||||
{
|
||||
CORE.Window.ready = true;
|
||||
|
||||
int fbWidth;
|
||||
int fbHeight;
|
||||
|
||||
glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight);
|
||||
|
||||
// Screen scaling matrix is required in case desired screen area is different from display area
|
||||
CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f);
|
||||
|
||||
// no need to scale mouse as glfw is doing it already
|
||||
|
||||
CORE.Window.render.width = fbWidth;
|
||||
CORE.Window.render.height = fbHeight;
|
||||
CORE.Window.currentFbo.width = fbWidth;
|
||||
CORE.Window.currentFbo.height = fbHeight;
|
||||
AdjustFrameBufferSize((int) CORE.Window.screen.width, (int) CORE.Window.screen.height);
|
||||
emscripten_set_element_css_size("#canvas", CORE.Window.screen.width, CORE.Window.screen.height);
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
|
||||
TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
|
@ -969,32 +974,56 @@ static void ErrorCallback(int error, const char *description)
|
|||
TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description);
|
||||
}
|
||||
|
||||
// AdjustWindowSize
|
||||
static void AdjustWindowSize(int width, int height, int fbWidth, int fbHeight)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "AdjustWindowSize: %dx%d | %dx%d", width, height, fbWidth, fbHeight);
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
|
||||
AdjustFrameBufferSize(width, height);
|
||||
|
||||
emscripten_set_element_css_size("#canvas", width, height);
|
||||
|
||||
EM_ASM({
|
||||
GLFW.active.width = $0;
|
||||
GLFW.active.height = $1;
|
||||
},
|
||||
width, height
|
||||
);
|
||||
}
|
||||
|
||||
// AdjustFrameBufferSize
|
||||
static void AdjustFrameBufferSize(int fbWidth, int fbHeight)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "AdjustFrameBufferSize: %dx%d", fbWidth, fbHeight);
|
||||
|
||||
float scale = GetDevicePixelRatio();
|
||||
fbWidth = (int) ((float) fbWidth * scale);
|
||||
fbHeight = (int) ((float) fbHeight * scale);
|
||||
|
||||
// Screen scaling matrix is required in case desired screen area is different from display area
|
||||
CORE.Window.screenScale = MatrixScale((float)fbWidth/(float)CORE.Window.screen.width, (float)fbHeight/(float)CORE.Window.screen.height, 1.0f);
|
||||
|
||||
SetMouseScale(1.0f / scale, 1.0f / scale);
|
||||
|
||||
CORE.Window.render.width = fbWidth;
|
||||
CORE.Window.render.height = fbHeight;
|
||||
CORE.Window.currentFbo.width = fbWidth;
|
||||
CORE.Window.currentFbo.height = fbHeight;
|
||||
CORE.Window.resizedLastFrame = true;
|
||||
|
||||
emscripten_set_canvas_element_size("#canvas", fbWidth, fbHeight);
|
||||
|
||||
SetupViewport(fbWidth, fbHeight);
|
||||
}
|
||||
|
||||
// GLFW3 WindowSize Callback, runs when window is resizedLastFrame
|
||||
// NOTE: Window resizing not allowed by default
|
||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
||||
{
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
|
||||
// Same logic from InitPlatform
|
||||
|
||||
int fbWidth;
|
||||
int fbHeight;
|
||||
|
||||
glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight);
|
||||
|
||||
// Screen scaling matrix is required in case desired screen area is different from display area
|
||||
CORE.Window.screenScale = MatrixScale((float)fbWidth/(float)CORE.Window.screen.width, (float)fbHeight/(float)CORE.Window.screen.height, 1.0f);
|
||||
|
||||
CORE.Window.render.width = fbWidth;
|
||||
CORE.Window.render.height = fbHeight;
|
||||
CORE.Window.currentFbo.width = fbWidth;
|
||||
CORE.Window.currentFbo.height = fbHeight;
|
||||
CORE.Window.resizedLastFrame = true;
|
||||
|
||||
SetupViewport(fbWidth, fbHeight);
|
||||
|
||||
// NOTE: Postprocessing texture is not scaled to new size
|
||||
TRACELOG(LOG_INFO, "WindowSizeCallback: %dx%d", width, height);
|
||||
AdjustWindowSize(width, height, width, height);
|
||||
}
|
||||
|
||||
// GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
|
|
@ -1204,7 +1233,7 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *
|
|||
if (height < CORE.Window.screenMin.height) height = CORE.Window.screenMin.height;
|
||||
else if (height > CORE.Window.screenMax.height && CORE.Window.screenMax.height > 0) height = CORE.Window.screenMax.height;
|
||||
|
||||
SetWindowSize(width, height); // will trigger callback
|
||||
SetWindowSize(width, height);
|
||||
|
||||
return 1; // The event was consumed by the callback handler
|
||||
}
|
||||
|
|
@ -1299,4 +1328,88 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
|
|||
return 1; // The event was consumed by the callback handler
|
||||
}
|
||||
|
||||
// InstallModuleJSAPI
|
||||
void InstallModuleJSAPI()
|
||||
{
|
||||
EM_ASM(
|
||||
{
|
||||
Module.raylib = {}; // used to store width/height before fullscreen
|
||||
const cb = Module.requestFullscreen;
|
||||
Module.requestFullscreen = (pointerLock, resize) => {
|
||||
const canvas = document.getElementById('canvas');
|
||||
Module.raylib.screenWidth = canvas.clientWidth;
|
||||
Module.raylib.screenHeight = canvas.clientHeight;
|
||||
cb(pointerLock, $0);
|
||||
};
|
||||
Module.onFullscreen = Module.cwrap('FullscreenCallback', null, ['boolean']); // called by emscripten
|
||||
Module.setHighDPIAware = Module.cwrap('SetHighDPIAware', null, ['boolean']);
|
||||
},
|
||||
(CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0
|
||||
);
|
||||
}
|
||||
|
||||
// FullscreenCallback
|
||||
void FullscreenCallback(bool isFullscreen)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "FullscreenCallback(%s)", isFullscreen ? "true" : "false");
|
||||
if (isFullscreen)
|
||||
{
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0)
|
||||
{
|
||||
if(IsHighDPIAware())
|
||||
{
|
||||
int screenWidth, screenHeight;
|
||||
emscripten_get_screen_size(&screenWidth, &screenHeight);
|
||||
AdjustFrameBufferSize(screenWidth, screenWidth);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int screenWidth, screenHeight;
|
||||
emscripten_get_screen_size(&screenWidth, &screenHeight);
|
||||
TRACELOG(LOG_INFO, "fullscreen resizable %dx%d", screenWidth, screenHeight);
|
||||
SetWindowSize(screenWidth, screenHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowSize(EM_ASM_INT(return Module.raylib.screenWidth;), EM_ASM_INT(return Module.raylib.screenHeight;));
|
||||
}
|
||||
|
||||
CORE.Window.fullscreen = isFullscreen;
|
||||
}
|
||||
|
||||
// SetHighDPIAware
|
||||
void SetHighDPIAware(bool flag)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "SetHighDPIAware(%s)", flag ? "true" : "false");
|
||||
if (platform.isHighDPIAware != flag)
|
||||
{
|
||||
platform.isHighDPIAware = flag;
|
||||
if(CORE.Window.fullscreen)
|
||||
{
|
||||
int screenWidth, screenHeight;
|
||||
emscripten_get_screen_size(&screenWidth, &screenHeight);
|
||||
AdjustFrameBufferSize(screenWidth, screenWidth);
|
||||
}
|
||||
else
|
||||
SetWindowSize(GetScreenWidth(), GetScreenHeight());
|
||||
}
|
||||
}
|
||||
|
||||
// IsHighDPIAware
|
||||
static bool IsHighDPIAware()
|
||||
{
|
||||
return platform.isHighDPIAware;
|
||||
}
|
||||
|
||||
// GetDevicePixelRatio
|
||||
static float GetDevicePixelRatio()
|
||||
{
|
||||
if (IsHighDPIAware())
|
||||
return (float) EM_ASM_DOUBLE({ console.log("dpr: " + devicePixelRatio); return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0; });
|
||||
else
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
|
|||
|
||||
<span id='controls'>
|
||||
<span><input type="button" value="📜 SOURCE CODE" onclick="location.href='https://github.com/raysan5/raylib';"/></span>
|
||||
<span><label><input type="checkbox" id="4k" value="4k" onclick="Module.setHighDPIAware(document.getElementById('4k').checked)">4k</label> </span>
|
||||
<span><input type="button" value="🖵 FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span>
|
||||
<span><input type="button" id="btn-audio" value="🔇 MUTE" onclick="toggleAudio()"></span>
|
||||
</span>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user