Drawing huge amount of lines

86 views Asked by At

My goal is to draw a huge amount of lines in real time. This minimal example is drawing 250000 lines with about 30 fps. Another approach is to draw 250000 capsules with about 14 fps dropping to finally 1 fps after some seconds. (The idea of the capsules is to control the weight of the lines afterwards). Both approaches look very slow to me.

Maybe the problem in this case is the connection between CPU and GPU. The grid is created again every frame. Is there an approach to only draw it again and not recreating it? Is this done with VOB?

What is a decent approach to draw line graphics in C++ with high speed? When taking a look at CAD-programs handling a really large amount of geometry, i guess this is based on Vulkan, Metal or other?

#include "raylib.h"
#include "rcamera.h"

int main() {
    const int screenWidth = 1280;
    const int screenHeight = 720;
    
    InitWindow(screenWidth, screenHeight, "Test lines");
    
    SetTargetFPS(60);
    SetConfigFlags(FLAG_MSAA_4X_HINT);
    int display = GetCurrentMonitor();
    SetWindowSize(GetMonitorWidth(0), GetMonitorHeight(0));
    ToggleBorderlessWindowed();
    
    Camera3D camera = {0};
    camera.position = (Vector3){0.00f, -5.00f, 1.75f};
    camera.target = (Vector3){0.00f, 0.00f, 0.00f};
    camera.up = (Vector3){0.00f, 0.00f, 1.00f};
    camera.fovy = 60.0f;
    camera.projection = CAMERA_PERSPECTIVE;

    DisableCursor();
    
    // loop
    while (!WindowShouldClose()) {
        // update camera
        UpdateCamera(&camera, CAMERA_FREE);
        
        BeginDrawing();
            ClearBackground(RAYWHITE);
            
            BeginMode3D(camera);
                // draw grid
                for (int x=-250; x<=250; x++){
                    for (int y=-250; y<=250; y++){
                        Vector3 start1;
                        start1.x = float(x+0.1f);
                        start1.y = float(y);
                        start1.z = 0.0f;
                        
                        Vector3 end1;
                        end1.x = float(x-0.1f);
                        end1.y = float(y);
                        end1.z = 0.0f;
                            
                        Vector3 start2;
                        start2.x = float(x);
                        start2.y = float(y+0.1f);
                        start2.z = 0.0f;
                        
                        Vector3 end2;
                        end2.x = float(x);
                        end2.y = float(y-0.1f);
                        end2.z = 0.0f;
                        
                        //DrawLine3D(start1, end1, LIGHTGRAY);
                        //DrawLine3D(start2, end2, LIGHTGRAY);
                        
                        DrawCapsule(start1, end1, 0.01f, 1, 1, BLACK);
                        DrawCapsule(start2, end2, 0.01f, 1, 1, BLACK);
                    }
                }
            EndMode3D();
            
            // fps
            DrawText(TextFormat("fps: %d", GetFPS()), 10.0f, 40.0f, 16, BLACK);
            
        EndDrawing();
    }
    CloseWindow();
    return 0;
}

Update: Thanks again for all your Feedback! I will take this in account for next projects. For my current issue i have decided to create a workaround. The idea is to fade out the lines, that are to far away to be visible anyway. So for anyone interested. This approach is not addressing the initial question but maybe it is working for some other cases:

#include "raylib.h"
#include "raymath.h"
#include "rcamera.h"
#include "iostream"

int main() {
    SetTraceLogLevel(7);
    SetTargetFPS(60);    
    const int screenWidth = 1280;
    const int screenHeight = 720;
    InitWindow(screenWidth, screenHeight, "Test lines");
    SetConfigFlags(FLAG_MSAA_4X_HINT);
    int display = GetCurrentMonitor();
    SetWindowSize(GetMonitorWidth(0), GetMonitorHeight(0));
    ToggleBorderlessWindowed();
    
    Camera3D camera = {0};
    camera.position = (Vector3){0.00f, -5.00f, 1.75f};
    camera.target = (Vector3){0.00f, 0.00f, 0.00f};
    camera.up = (Vector3){0.00f, 0.00f, 1.00f};
    camera.fovy = 60.0f;
    camera.projection = CAMERA_PERSPECTIVE;

    DisableCursor();
    
    // loop
    while (!WindowShouldClose()) {
        // update camera
        UpdateCamera(&camera, CAMERA_FREE);
        
        BeginDrawing();
            ClearBackground(RAYWHITE);
            
            BeginMode3D(camera);
                // draw grid
                int size = 25;
                for (int x=-size; x<=size; x++){
                    for (int y=-size; y<=size; y++){
                        // get position of the camera
                        // int is converting the position to fit the grid
                        // the grid is moving with the camera now
                        int pos_x = camera.position.x;
                        int pos_y = camera.position.y;
                        
                        Vector3 start1;
                        start1.x = pos_x + float(x+0.1f);
                        start1.y = pos_y + float(y);
                        start1.z = 0.0f;
                        
                        Vector3 end1;
                        end1.x = pos_x + float(x-0.1f);
                        end1.y = pos_y + float(y);
                        end1.z = 0.0f;
                            
                        Vector3 start2;
                        start2.x = pos_x + float(x);
                        start2.y = pos_y + float(y+0.1f);
                        start2.z = 0.0f;
                        
                        Vector3 end2;
                        end2.x = pos_x + float(x);
                        end2.y = pos_y + float(y-0.1f);
                        end2.z = 0.0f;
                        
                        // fade out the lines that are further away from the camera
                        float dist = Vector3Distance(camera.position, start1);
                        float alpha = Remap(dist, 0, size, 255, 0);
                        if (alpha > 255){alpha = 255;}
                        if (alpha < 0){alpha = 0;}
                        DrawLine3D(start1, end1, Color{0, 0, 0, (unsigned char)alpha});
                        DrawLine3D(start2, end2, Color{0, 0, 0, (unsigned char)alpha});
                    }
                }
            EndMode3D();
            
            // fps
            DrawText(TextFormat("fps: %d", GetFPS()), 10.0f, 40.0f, 16, BLACK);
            
        EndDrawing();
    }
    CloseWindow();
    return 0;
}
0

There are 0 answers