raysan5 / raylib

A simple and easy-to-use library to enjoy videogames programming

Home Page:http://www.raylib.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DrawCylinder() draws overlapping geometry in certain cases

paulmelis opened this issue · 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

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

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

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

16-sides