Рисование «полого» круга в 3D OpenGL (C++)

Я пытаюсь воссоздать солнечную систему в 3D. Солнце, планеты и луны рассчитываются и рисуются правильно, но я хочу нарисовать «полый» круг, представляющий орбиту каждого объекта, который у меня есть.

Мне удалось вычислить серию точек для каждой орбиты, которую я сохраняю в vector<glm::vec3>, например, с орбитой с 20 точками:

(1.40129, 3.20724, 0)
(2.36675, 2.57846, 0)
(3.07574, 1.67027, 0)
(3.45143, 0.58108, 0)
(3.4531, -0.571081, 0)
(3.08057, -1.66136, 0)
(2.37421, -2.5716, 0)
(1.41057, -3.20317, 0)
(0.294079, -3.48762, 0)
(-0.854285, -3.39414, 0)
(-1.91007, -2.93285, 0)
(-2.75888, -2.15374, 0)
(-3.30871, -1.14124, 0)
(-3.5, -0.00506855, 0)
(-3.312, 1.13165, 0)
(-2.7651, 2.14574, 0)
(-1.91856, 2.92731, 0)
(-0.864112, 3.39165, 0)
(0.283976, 3.48846, 0)
(1.40129, 3.20724, 0)

Здесь орбита остается на z = 0, но это не всегда так.

Я думал, что мне просто нужно провести линии между каждой из этих точек, вот так:

glBegin(GL_LINES);
glColor3f(1.0f, 1.0f, 1.0f); // White color
for (auto& point : planet->orbitPoints) {
    glVertex3f(point.x, point.y, point.z);
}
glEnd();

Но ничего не появляется. Я пытался рисовать простые линии, вручную записывая разные координаты, но это тоже не работает.

Я работаю в трехмерном пространстве, используя glm::perspective в качестве проекции и матрицы модели / вида / проекции для шейдера.

Можно ли в этих условиях просто рисовать линии или это сложнее?

Редактировать: Нашел решение.

Как упоминал genpfault, я пытался объединить шейдеры и код с фиксированной функцией, что является причиной того, что приведенный выше код не работал.

Поскольку точки кругов / орбит, которые я хотел нарисовать, уже были рассчитаны, мне просто нужно было провести линию между этими точками. Для заинтересованных, вот как я это сделал:

1. Сгенерируйте вектор для хранения вершин круга (перед циклом визуализации во время):

// Create the vector which will store the vertices of each orbit, and create a buffer for it
vector<vec3> orbitVertices;
GLuint orbitVertexBuffer;
glGenBuffers(1, &orbitVertexBuffer);

2. В цикле при рендеринге переключитесь на этот буфер и используйте его для рисования линий с помощью функции glDrawArrays:

// Change the vertex buffer to the orbit one
glBindBuffer(GL_ARRAY_BUFFER, orbitVertexBuffer);
glVertexAttribPointer(
    0,                  // attribute
    3,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    0,                  // stride
    (void *) nullptr    // array buffer offset
);

// Re-init the "model" matrix to an identity matrix
mat4 model = mat4(1.0f);
glUniformMatrix4fv(glGetUniformLocation(programID, "model"), 1, GL_FALSE, value_ptr(model));

// Draw the orbits
for (auto &object : objects) { // For each planet, moon, etc.
    orbitVertices = object->orbitPoints; // Get the points making up the circle
    glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * orbitVertices.size(), orbitVertices.data(), GL_DYNAMIC_DRAW); // Pass it as data for the buffer
    glDrawArrays(GL_LINE_LOOP, 0, orbitVertices.size()); // Draw the lines
}

Что, с некоторыми настройками цвета и большим количеством очков для больших кругов, дает мне результаты, которые я хотел:

Рисование «полого» круга в 3D OpenGL (C++)

Комбинация шейдеров и кода с фиксированными функциями - это гигантский красный флаг. Отредактируйте в минимальный воспроизводимый пример.

genpfault 30.03.2021 02:41

Спасибо за разъяснения, это вернуло меня к поиску хорошего решения.

FeuFeve 01.04.2021 19:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
59
1

Ответы 1

Используйте линии для аппроксимации круга: glDrawElements(GL_LINES, ...

Также, как упоминалось в genpfault, переключитесь на поток объектов буфера вершин / индексов.

http://ogldev.atspace.co.uk/www/tutorial10/tutorial10.html

Нашел решение (см. Отредактированный пост). Как вы упомянули genpfault, я переключился на поток объектов буфера вершин. Однако мне не пришлось использовать индексный буфер, так как я хотел только рисовать линии. glDrawArrays, которому нужен только буфер вершин, в этом случае подойдет.

FeuFeve 01.04.2021 19:16

Другие вопросы по теме