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

DrawCylinder() draws overlapping geometry in certain cases #4024

Closed
4 tasks done
paulmelis opened this issue Jun 1, 2024 · 2 comments
Closed
4 tasks done

DrawCylinder() draws overlapping geometry in certain cases #4024

paulmelis opened this issue Jun 1, 2024 · 2 comments

Comments

@paulmelis
Copy link
Contributor

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

Depending on the number of sides passed to DrawCylinder() (and it looks like DrawCylinderWires() as well) too much geometry is drawn, in effect one angle step too many, leading to overlapping geometry (or imprecisely placed) and z-fighting. This is noticeable when using a semi-transparent color.

Using the simple example below, with varying numbers of sides for the cylinder:

7 sides (incorrect)

7-sides

8 sides (correct)

8-sides

15 sides (correct)

15-sides

16 sides (incorrect)

16-sides

This seems to be caused by the integer math used in

for (int i = 0; i < 360; i += 360/sides)

The rlVertex3f() calls within the loop correctly use 360.0f/sides for the angle step, but the (integer) base offset i is imprecise due to rounding.

Environment

Arch Linux, GTX Titan V

Issue Screenshot

See above

Code Example

#include <stdlib.h>
#include "raylib.h"
#include "raymath.h"

int main(int argc, char *argv[])
{
    int sides = 16;
    if (--argc == 1) sides = atoi(argv[1]);

    InitWindow(800, 450, TextFormat("%i sides", sides));

    Camera camera = { 0 };
    // Top view (ortho)
    camera.position = (Vector3){ 0.0f, 3.0f, -3.0f }; // Camera position
    camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };     // Camera looking at point
    camera.up = (Vector3){ 0.0f, 0.0f, 1.0f };          // Camera up vector (rotation towards target)
    camera.projection = CAMERA_PERSPECTIVE;            // Camera mode type
    camera.fovy = 50.0f;                                 // Camera field-of-view Y (perspective); width (orthographic)

    while (!WindowShouldClose())
    {
        BeginDrawing();
            ClearBackground(RAYWHITE);
            BeginMode3D(camera);
                DrawCylinder(Vector3Zero(), 1.0f, 1.0f, 1.0f, sides, (Color){0, 0, 255, 40});
            EndMode3D();
        EndDrawing();

        if (IsKeyPressed(KEY_S)) {
            TakeScreenshot(TextFormat("%i-sides.png", sides));
        }
    }

    CloseWindow();

    return 0;
}
@raysan5
Copy link
Owner

raysan5 commented Jun 2, 2024

@paulmelis Oh! Good catch! Feel free to send a PR with the review!

paulmelis added a commit to paulmelis/raylib that referenced this issue Jun 3, 2024
stepping (mostly noticeable with semi-transparent cylinders)
@paulmelis
Copy link
Contributor Author

With updated code e.g. 16 sides looks much better:

16-sides

@raysan5 raysan5 closed this as completed in e1379af Jun 4, 2024
JayLCypher pushed a commit to JayLCypher/raylib that referenced this issue Jun 9, 2024
…le (raysan5#4034)

* Fix raysan5#4024, cylinder drawing was incorrect due to imprecise angle
stepping (mostly noticeable with semi-transparent cylinders)

* Fix var name and spacing
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