raylib
raylib copied to clipboard
[rcore][glfw] `GetScreenHeight()` returns 0 when used inside RenderTexture and window resized
When calling GetScreenHeight() inside BeginTextureMode() AND window is scaled, it returns 0.
Expected result after resizing: MAROON rectangle drawn at the bottom of the RenderTexture.
Result: MAROON rectangle not draw on screen (maybe drawn outside of screen)
Testing code:
#include "raylib.h"
int main(void)
{
const int windowWidth = 800;
const int windowHeight = 450;
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox");
RenderTexture2D target = LoadRenderTexture(600, 400);
SetTargetFPS(60);
while (!WindowShouldClose())
{
BeginTextureMode(target);
ClearBackground(LIGHTGRAY);
DrawRectangle(0, GetScreenHeight() - 80, 200, 80, MAROON); // ISSUE: NOT DRAWN on resizing!
EndTextureMode();
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
-(float)target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndDrawing();
}
UnloadRenderTexture(target);
CloseWindow();
return 0;
}
Does not seem to occur on Linux/Xorg with DESKTOP_GLFW
I even placed assert(GetScreenHeight() != 0); inside of TextureMode and it was never hit.
This is how it looks like on my side
https://github.com/user-attachments/assets/95967dd9-2ed1-420b-9dbb-f72a01c10d7a
@raysan5 I presume, you're using Windows10/11 with GLFW backend ?
@sleeptightAnsiC Thanks for reviewing this issue, that's what I see:
https://github.com/user-attachments/assets/1e7645ba-68ce-4b77-a682-719d1e9200e6
I think there could be some missunderstanding on my side, afair GetScreenHeight() was supposed to return the current framebuffer height, active in the moment of calling the function, but it seems it returns the current main framebuffer height (the window one). When drawing the rectangle, it just does not draw outside RenderTexture bounds.
So I ran the following:
#include "raylib.h"
int main(void)
{
const int windowWidth = 800;
const int windowHeight = 450;
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox");
RenderTexture2D target = LoadRenderTexture(600, 400);
SetTargetFPS(60);
while (!WindowShouldClose())
{
BeginTextureMode(target);
ClearBackground(LIGHTGRAY);
DrawRectangle(0, GetScreenHeight() - 80, 200, 80, MAROON); // ISSUE: NOT DRAWN on resizing!
EndTextureMode();
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
-(float)target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndDrawing();
}
UnloadRenderTexture(target);
CloseWindow();
return 0;
}
with:
CC = g++
CFLAGS = -O3 -Wall -std=c++11 -Wno-missing-braces
LDFLAGS = -L/opt/homebrew/Cellar/raylib/5.5/lib -lraylib
INCLUDES = -I/opt/homebrew/Cellar/raylib/5.5/include
SRC = $(wildcard *.cpp)
OBJ = $(SRC:.cpp=.o)
TARGET = main
# Default target to build the program
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(OBJ) -o $(TARGET) $(LDFLAGS) || (make clean && exit 1) # Clean on linking failure
rm -f $(OBJ) # Clean up object files after building
%.o: %.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ || (make clean && exit 1) # Clean on compilation failure
clean:
rm -f $(OBJ) $(TARGET)
.PHONY: all clean
Terminal output:
g++ -o main -L/opt/homebrew/Cellar/raylib/5.5/lib -lraylib || (make clean && exit 1) # Clean on linking failure
Undefined symbols for architecture arm64:
"_main", referenced from:
<initial-undefines>
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
rm -f main
make: *** [main] Error 1
So I then I kept trying, I added a header file from another raylib project, then even threw away your code entirely and copied my other projects code to see if that would compile, which it did. I come back and completely throw away that code and add your's back verbatim. I still had my other header file but again your code verbatim so it shouldn't have even used it. It compiles. I get rid of that header file, but keep my test as "main.cpp" and your code untouched, and it compiles. I now get the following picture even when I reload VSCode.
I can now only get your code running and get the same pictured window:
make && ./main
g++ -O3 -Wall -std=c++11 -Wno-missing-braces -I/opt/homebrew/Cellar/raylib/5.5/include -c main.cpp -o main.o || (make clean && exit 1) # Clean on compilation failure
g++ main.o -o main -L/opt/homebrew/Cellar/raylib/5.5/lib -lraylib || (make clean && exit 1) # Clean on linking failure
rm -f main.o # Clean up object files after building
INFO: Initializing raylib 5.5
INFO: Platform backend: DESKTOP (GLFW)
INFO: Supported raylib modules:
INFO: > rcore:..... loaded (mandatory)
INFO: > rlgl:...... loaded (mandatory)
INFO: > rshapes:... loaded (optional)
INFO: > rtextures:. loaded (optional)
INFO: > rtext:..... loaded (optional)
INFO: > rmodels:... loaded (optional)
INFO: > raudio:.... loaded (optional)
INFO: DISPLAY: Device initialized successfully
INFO: > Display size: 1440 x 900
INFO: > Screen size: 800 x 450
INFO: > Render size: 800 x 450
INFO: > Viewport offsets: 0, 0
INFO: GLAD: OpenGL extensions loaded successfully
INFO: GL: Supported extensions count: 43
INFO: GL: OpenGL device information:
INFO: > Vendor: Apple
INFO: > Renderer: Apple M1
INFO: > Version: 4.1 Metal - 89.4
INFO: > GLSL: 4.10
INFO: GL: VAO extension detected, VAO functions loaded successfully
INFO: GL: NPOT textures extension detected, full NPOT textures supported
INFO: GL: DXT compressed textures supported
INFO: PLATFORM: DESKTOP (GLFW - Cocoa): Initialized successfully
INFO: TEXTURE: [ID 1] Texture loaded successfully (1x1 | R8G8B8A8 | 1 mipmaps)
INFO: TEXTURE: [ID 1] Default texture loaded successfully
INFO: SHADER: [ID 1] Vertex shader compiled successfully
INFO: SHADER: [ID 2] Fragment shader compiled successfully
INFO: SHADER: [ID 3] Program shader loaded successfully
INFO: SHADER: [ID 3] Default shader loaded successfully
INFO: RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)
INFO: RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)
INFO: RLGL: Default OpenGL state initialized successfully
INFO: TEXTURE: [ID 2] Texture loaded successfully (128x128 | GRAY_ALPHA | 1 mipmaps)
INFO: FONT: Default font loaded successfully (224 glyphs)
INFO: SYSTEM: Working Directory: /Users/ian/VSCodeProjects/C++ Stuff/Cpp_Games/raylib_project/Test
INFO: TEXTURE: [ID 3] Texture loaded successfully (600x400 | R8G8B8A8 | 1 mipmaps)
INFO: TEXTURE: [ID 1] Depth renderbuffer loaded successfully (32 bits)
INFO: FBO: [ID 1] Framebuffer object created successfully
INFO: TIMER: Target time per frame: 16.667 milliseconds
INFO: FBO: [ID 1] Unloaded framebuffer from VRAM (GPU)
INFO: TEXTURE: [ID 2] Unloaded texture data from VRAM (GPU)
INFO: SHADER: [ID 3] Default shader unloaded successfully
INFO: TEXTURE: [ID 1] Default texture unloaded successfully
INFO: Window closed successfully
Changing the file back to main.c results in:
$ make && ./main
g++ -o main -L/opt/homebrew/Cellar/raylib/5.5/lib -lraylib || (make clean && exit 1) # Clean on linking failure
Undefined symbols for architecture arm64:
"_main", referenced from:
<initial-undefines>
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
rm -f main
make: *** [main] Error 1
I tried changing my Makefile to use clang, gcc, etc and got the same error with main.c. But as soon as I change it back to main.cpp I get the result as image and successful compilation.
Here is a video of what happens when I resize the window: https://github.com/user-attachments/assets/ff59917a-648d-442a-884a-e5bc1e369c49
i thought “GetRenderWidth()” was a fancy name for “GetWindowWidth()”, not getting width of current buffer. anyway, if its supposed to stick to the bottom and not teleport outside RenderTexture, then why not using something like:
RenderTexture rend = LoadRenderTexture(1920, 1080);
…
Rectangle rec = {0, rend.texture.height - 40, 100, 40};
Not sure if this will work, my main language is Csharp. although i believe, that RenderTexture contains its resolution too, so u can use that.
You could use the target.texture.height to get the texture height, the GetScreenHeight() only get the full screen height not the texture.
Hi @raysan5 checking again the issue, the GetScreenHeight() returns the size of the windows when updated by EndDrawing. It is never zero for me but it returns the full screen size not the Target one, I don't think it is a bug.
EndDrawing -> Updates the screen height so we start each loop with the full screen height. BeginTextureMode -> Does not update the screen height If done we need to reset it in EndTextureMode(). Is it the Idea?
Hi there, if we change the GetScreenWidth and GetScreenHeight to get the data from CORE.Window.currentFbo it works fine:
@maiconpintoabreu Yes, but those functions are expected to return the working resolution, set by user, not the internal framebuffer render resolution, that it's usually bigger on HighDPI, neither the current active render-texture resolution. It would mangle user code involving that "virtual" screen resolution.
In any case, all these resolutions mess should be carefully reviewed for all platforms... but it's a lot of work.
Can you not use the GetRenderHeight inside the BeginTextureMode instead so? It will get the currentFbo.height.
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height;
It gives the same results as the screenshot before.
Tbh i think this should be in the users hands. GetScreenHeight() seems properly named to get the height of the window and as @maiconpintoabreu mentioned, there is GetRenderHeight() for the current fbo.
the user would just simply use that instead:
DrawRectangle(0, GetRenderHeight() - 80, 200, 80, MAROON);
or the full code:
#include "raylib.h"
int main(void)
{
const int windowWidth = 800;
const int windowHeight = 450;
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox");
RenderTexture2D target = LoadRenderTexture(600, 400);
SetTargetFPS(60);
while (!WindowShouldClose())
{
BeginTextureMode(target);
ClearBackground(LIGHTGRAY);
DrawRectangle(0, GetRenderHeight() - 80, 200, 80, MAROON); // no more issue
EndTextureMode();
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
-(float)target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndDrawing();
}
UnloadRenderTexture(target);
CloseWindow();
return 0;
}