raysan5/raylib

[rshape] Line drawing functions are no longer pixel-perfect

bohonghuang opened this issue · 1 comments

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

Hello! I noticed that in the latest Git version of Raylib, the line drawing function is no longer pixel-perfect, which is reflected in the following aspects:

  1. The DrawRectangleLines function no longer perfectly encloses its region, where an additional pixel is added in the vertical direction.
  2. In a 2D game that utilizes normalized coordinates along with Camera2D (which is common for tile-based games as it decouples the game's coordinates from the tile size), line drawing functions like DrawLine and DrawLineV produce incorrect results with a 0.5 offset in both dimensions.

Code Example

Here is the code for the issue demonstration:

#include "raylib.h"
#include "rlgl.h"

int main(void) {

  const int screenWidth = 800;
  const int screenHeight = 450;

  InitWindow(screenWidth, screenHeight, "Line Drawing Functions Test");

  Camera2D camera = {0};
  camera.target = (Vector2){0.0f, 0.0f};
  camera.offset = (Vector2){screenWidth / 2.0f, screenHeight / 2.0f};
  camera.rotation = 0.0f;
  camera.zoom = 32.0f;

  SetTargetFPS(60);

  while (!WindowShouldClose()) {
    if (IsKeyDown(KEY_RIGHT))
      camera.target.x += 2;
    if (IsKeyDown(KEY_LEFT))
      camera.target.x -= 2;
    if (IsKeyDown(KEY_UP))
      camera.target.y -= 2;
    if (IsKeyDown(KEY_DOWN))
      camera.target.y += 2;

    BeginDrawing();
      ClearBackground(RAYWHITE);
      BeginMode2D(camera);
        DrawRectangleRec((Rectangle) { 0.0f, 0.0f, 1.0f, 1.0f}, RED);
        DrawLineV((Vector2){0.0, 0.0}, (Vector2){1.0f, 0.0}, BLUE);
        DrawLineV((Vector2){1.0f, 0.0}, (Vector2){1.0f, 1.0f}, BLUE);
        DrawLineV((Vector2){1.0f, 1.0f}, (Vector2){0.0, 1.0f}, BLUE);
        DrawLineV((Vector2){0.0, 1.0f}, (Vector2){0.0, 0.0}, BLUE);
        DrawRectangleLines(0, 0, 2, 2, GREEN);
      EndMode2D();
      DrawRectangle(1, 1, 30, 30, RED);
      DrawRectangleLines(0, 0, 32, 32, BLUE);
    EndDrawing();
  }
  CloseWindow();
  return 0;
}

Issue Screenshot

The result of the above code under the Git version of Raylib:

1

The result of the above code under Raylib 5.0:

2

I noticed that the changes causing these issues may have been made to address other problems in the recent commits, so perhaps some trade-offs in design need to be considered.

I noticed that the changes causing these issues may have been made to address other problems in the recent commits, so perhaps some trade-offs in design need to be considered.

@bohonghuang Yes, this is the issue it tried to address: #3884. And it also break some projects for me...

One solution could be using DrawRectangleLinesEx(), that still uses RL_QUADS but all DrawRectangleLines() could still fail. Also note that the pixel offset is GPU/driver dependant so it could be very difficult to properly address.

Other possible solution is enabling a flag (like previous implementation) to force RL_QUADS when required.