Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rshapes] DrawRectangleLines() lines flickering when zooming out due to RL_LINES vs RL_QUADS #3884

Closed
4 tasks done
arceryz opened this issue Mar 25, 2024 · 3 comments
Closed
4 tasks done

Comments

@arceryz
Copy link

arceryz commented Mar 25, 2024

Please, before submitting a new issue verify and check:

  • I tested it on latest raylib version from master branch
  • I checked there is no similar issue already reported
  • I checked the documentation on the wiki
  • My code has no errors or misuse of raylib

Issue description

When working with DrawRectangleLines, the behavior as expected is to have the rectangle drawn with RL_LINES, i.e pure OpenGL lines with no artefacts at small distances like DrawLine. However, DrawRectangleLines (and possible other fake *Lines drawing methods) are rendered with Quads when SUPPORT_QUADS_DRAW_MODE is true. While I understand that this may be for avoiding draw order issues (as stated in the source comment), intuitively one would expect that *Lines methods are drawn with pure OpenGL lines to avoid artefacts.

So I would recommend not mixing RL_LINES and Quads when possible and to be clear which or the other any function in rshapes.c is using.

I encountered this when creating an infinite grid when zooming in and out on a tool, using DrawRectangleLines would have the rectangle flickering at high levels of zoom, because the quads become sub-pixel sized. It is not a big issue, because I can just implement a custom DrawRectangleLines that draws 4 lines instead (as expected). But I think it may be better to have all the *Lines function (except the Ex versions with lineWidth) to be rendered always with RL_LINES and not quads.

It is in particular this piece of code in rshapes.c:

// Draw rectangle outline
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
{
#if defined(SUPPORT_QUADS_DRAW_MODE)
    DrawRectangle(posX, posY, width, 1, color);
    DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color);
    DrawRectangle(posX, posY + height - 1, width, 1, color);
    DrawRectangle(posX, posY + 1, 1, height - 2, color);
#else
    rlBegin(RL_LINES);
        rlColor4ub(color.r, color.g, color.b, color.a);
        rlVertex2f(posX + 1, posY + 1);
        rlVertex2f(posX + width, posY + 1);
        ...

See the gif for a demonstration of the issue and how it may work counterintuitively for Raylib users. (Expectation: rectangle remains a rectangle at big distance).

Environment

Windows, vanilla Raylib 5.0 C

Issue Screenshot

The left square is the expected behavior (4 lines) and the right square is DrawRectangleLines.
The camera is zoomed out progressively. With greater zoom levels, DrawRectangleLines becomes basically pointless.
Bug

Code Example

It is python code because I wrote quickly, but it is nothing special and would look the same in C.

from pyray import *

init_window(800, 800, "Bug")

camera: Camera2D = Camera2D(Vector2(0, 0), Vector2(0, 0), 0, 1)

while not window_should_close():
    begin_drawing()
    begin_mode_2d(camera)
    clear_background(BLACK)

    draw_line(10, 10, 210, 10, WHITE)
    draw_line(210, 10, 210, 210, WHITE)
    draw_line(210, 210, 10, 210, WHITE)
    draw_line(10, 210, 10, 10, WHITE)

    draw_rectangle_lines(300, 10, 200, 200, WHITE)

    camera.zoom -= get_frame_time() * 0.1
    end_mode_2d()
    end_drawing()
@raysan5 raysan5 changed the title [rshapes] DrawRectangleLines lines flickering when zooming out due to RL_LINES vs Quads [rshapes] DrawRectangleLines() lines flickering when zooming out due to RL_LINES vs RL_QUADS Apr 7, 2024
@raysan5
Copy link
Owner

raysan5 commented Apr 7, 2024

@arceryz Good catch! And thanks for reporting! I expected OpenGL driver to manage that properly on its side... but effectively lines rendering is completely different than triangles... It probably can't be addressed from raylib side but just be properly documented.

@arceryz
Copy link
Author

arceryz commented Apr 7, 2024

@raysan5 Would it be an option to have all the pure *Lines drawing methods (expect the *Ex variants) just implemented with RL_LINES, and the *LinesEx methods, which have thickness, be implemented using triangles/quads? I think this would make most sense, since of course lines with thickness can't avoid this issue so we can leave *LinesEx untouched. This way you can just say that the *Lines drawing methods are safe at faraway distances.

raysan5 added a commit that referenced this issue Apr 20, 2024
For consistency, now _almost_ all `Draw*Lines()` functions use `RL_LINES` mode for drawing. It solves the linked issue but it can have other implications, as mentioned in the WARNING comment in `DrawRectangleLines()`.

Side note: `DrawRectangleRoundedLines()` now should be reviewed for consistency.
@raysan5
Copy link
Owner

raysan5 commented Apr 20, 2024

@arceryz DrawRectangleLines() has been reviewed with the proposed fix BUT notice that this change can derive in other unexpected issues: When drawing with GL_LINES first pixel position calculation could be offseted by one pixel depending on the GPU/drivers, I'm afraid it's an impossible issue to be fixed.

Also note that DrawRectangleRoundedLines() now should be reviewed for consistency with other Draw*Lines() functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants