Skip to content

DrawCylinder() draws overlapping geometry in certain cases #4024

@paulmelis

Description

@paulmelis

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;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions