Кривые в OpenGL

Форум Форумы ГЛАВНЫЙ ФОРУМ Кривые в OpenGL

Просмотр 2 сообщений - с 1 по 2 (из 2 всего)
  • Автор
    Записи
  • #67
    KillokerKilloker
    Участник

    Портировал пример выше на C++, чтобы собирать EXE, так как из Python он слишком большой получается. Прикрепил архив с EXE. Данный пример очень просто портируется на SDL2/C++. Есть очень близкий аналог библиотеки beziers на C++: https://github.com/oysteinmyrmo/bezier Это библиотека header-only, то есть нужен только один файл – bezier.h

    Вроде бы программы одинаковые, но на Python почему-то выглядит более плавно, а на С++ какие-то выемки на кривой, там где она круто изгибается:

    Собираю из CMD командой mingw32-make с помощью набора инструментов MinGW 64-bit.

    makefile

    CodeСкопировано
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # Building Command: mingw32-make
    # Command to run: app
    # Key to hide console: -mwindows

    INC = -I”E:\Libs\SDL2-2.24.0-mingw-64bit\include” \
    -I”E:\Libs\glad-0.1.36-mingw-64bit\include” \
    -I”E:\Libs\bezier\include”

    LIB = -L”E:\Libs\SDL2-2.24.0-mingw-64bit\lib” \
    -L”E:\Libs\glad-0.1.36-mingw-64bit\lib”

    all: main.o
    g++ main.o $(LIB) -lSDL2.dll -lglad -static-libgcc \
    -Wl,-Bstatic -lstdc++ -lwinpthread -o app.exe

    main.o: main.cpp
    g++ -c $(INC) main.cpp
    main.cpp

    C++Скопировано
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #define SDL_MAIN_HANDLED
    #include <SDL2/SDL.h>
    #include <bezier.h>
    #include <glad/glad.h>
    #include <iostream>

    SDL_Window *window;
    const float maxFPS = 20.f;

    void fatalError(const std::string &message)
    {
    std::cout << message << std::endl;
    if (window)
    {
    SDL_DestroyWindow(window);
    }
    SDL_Quit();
    exit(-1);
    }

    int main()
    {
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
    fatalError(“Failed to initialize”);
    }

    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    window = SDL_CreateWindow(“Beziers, OpenGL1, SDL2, C++”,
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
    400, 400, SDL_WINDOW_OPENGL);
    if (!window)
    {
    fatalError(“Failed to create the SDL window”);
    }

    SDL_GLContext glContext = SDL_GL_CreateContext(window);
    if (!glContext)
    {
    fatalError(“Failed to create the SDL_GL context”);
    }

    if (!gladLoadGL())
    {
    fatalError(“Failed to initialize the GLAD library”);
    }

    glClearColor(0.2f, 0.2f, 0.2f, 1.f);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.f, 250.f, 0.f, 250.f, 1.f, -1.f);

    Bezier::Bezier<3> cubicBezier(
    { { 120, 160 }, { 35, 200 }, { 220, 260 }, { 220, 40 } });

    bool running = true;
    while (running)
    {
    SDL_Event event;

    while (SDL_PollEvent(&event))
    {
    switch (event.type)
    {
    case SDL_QUIT:
    running = false;
    break;
    }
    }
    float startTicks = SDL_GetTicks();

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(0.5f, 1.f, 0.7f);
    glLineWidth(3.f);

    glBegin(GL_LINES);
    {
    for (int i = 0; i < 100; ++i)
    {
    Bezier::Point start = cubicBezier.valueAt(i / 100.f);
    Bezier::Point end = cubicBezier.valueAt((i + 1) / 100.f);
    glVertex2f(start.x, start.y);
    glVertex2f(end.x, end.y);
    }
    }
    glEnd();

    SDL_GL_SwapWindow(window);

    // Limit FPS to the max FPS
    float frameTicks = SDL_GetTicks() – startTicks;
    if (1000.f / maxFPS > frameTicks)
    {
    SDL_Delay(1000.f / maxFPS – frameTicks);
    }
    }

    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
    }

    #87
    Kostyan_MinskKostyan_Minsk
    Участник

    Скорее всего, дело в фиксированном количестве сегментов (100) при аппроксимации кривой линиями. На участках с большой кривизной этого недостаточно, и видны прямые отрезки. В Python-библиотеке, возможно, используется адаптивное разбиение. Увеличь количество точек в цикле (например, до 1000) или реализуй рекурсивное разбиение по порогу угла/отклонения.

Просмотр 2 сообщений - с 1 по 2 (из 2 всего)
  • Для ответа в этой теме необходимо авторизоваться.