вычисление сферы в opengl - PullRequest
       1

вычисление сферы в opengl

5 голосов
/ 30 октября 2011

Я хочу вычислить все необходимые вершины и соединить их линиями, чтобы в итоге я получил сферу. Сколько есть способов сделать это? А также линии между вершинами будут прямыми; Как я могу сделать их "изогнутыми" Я знаю, что я могу использовать glutWireSphere (), но я заинтересован в фактическом вычислении вершин. Один из способов, который я обдумал, состоял в том, чтобы поместить все вершины вручную в массив, но я полагаю, что это не так.

Ответы [ 5 ]

15 голосов
/ 30 октября 2011

Копирование и вставка кода, который я первоначально написал в Создание трехмерной сферы в Opengl с использованием Visual C ++

class SolidSphere
{
protected
    std::vector<GLfloat> vertices;
    std::vector<GLfloat> normals;
    std::vector<GLfloat> texcoords;
    std::vector<GLushort> indices;

public:
    void SolidSphere(float radius, unsigned int rings, unsigned int sectors)
    {
        float const R = 1./(float)(rings-1);
        float const S = 1./(float)(sectors-1);
        int r, s;

        sphere_vertices.resize(rings * sectors * 3);
        sphere_normals.resize(rings * sectors * 3);
        sphere_texcoords.resize(rings * sectors * 2);
        std::vector<GLfloat>::iterator v = sphere_vertices.begin();
        std::vector<GLfloat>::iterator n = sphere_normals.begin();
        std::vector<GLfloat>::iterator t = sphere_texcoords.begin();
        for(r = 0; r < rings; r++) for(s = 0; s < sectors; s++) {
                float const y = sin( -M_PI_2 + M_PI * r * R );
                float const x = cos(2*M_PI * s * S) * sin( M_PI * r * R );
                float const z = sin(2*M_PI * s * S) * sin( M_PI * r * R );

                *t++ = s*S;
                *t++ = r*R;

                *v++ = x * radius;
                *v++ = y * radius;
                *v++ = z * radius;

                *n++ = x;
                *n++ = y;
                *n++ = z;
        }

        sphere_indices.resize(rings * sectors * 4);
        std:vector<GLushort>::iterator i = sphere_indices.begin();
        for(r = 0; r < rings; r++) for(s = 0; s < sectors; s++) {
                *i++ = r * sectors + s;
                *i++ = r * sectors + (s+1);
                *i++ = (r+1) * sectors + (s+1);
                *i++ = (r+1) * sectors + s;
        }
    }

    void draw(GLfloat x, GLfloat y, GLfloat z)
    {
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glTranslatef(x,y,z);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glVertexPointer(3, GL_FLOAT, 0, &sphere_vertices[0]);
        glNormalPointer(GL_FLOAT, 0, &sphere_normals[0]);
        glTexCoordPointer(2, GL_FLOAT, 0, &sphere_texcoords[0]);
        glDrawElements(GL_QUADS, sphere_indices.size()/4, GL_UNSIGNED_SHORT, sphere_indices);
        glPopMatrix();
    }
}

как я могу сделать их "изогнутыми"

Ты не можешь. Все примитивы OpenGL являются «аффинными», то есть плоскими или прямыми. Кривизна эмулируется путем рисования коротких прямых участков с достаточным разрешением.

4 голосов
/ 30 октября 2011

Существует несколько способов сделать это: а) генерация икосферы и б) генерация УФ сферы. Там может быть больше способов сделать это. Некоторый поиск в Google дал мне этот отличный пост о поколении икосферы . Я не смог найти метод генерации УФ-сферы.

4 голосов
/ 30 октября 2011

У Пола Бурка есть хорошее введение в генерацию сферы .А что касается изогнутых линий, в OpenGL такого нет.Вы можете только сделать их изогнутыми, добавив больше промежуточных соединенных точек.

0 голосов
/ 01 августа 2017

Иконосфера сделает свое дело.Тем не менее, чтобы создать с ним сферу, вам придется разделить ее треугольники.

0 голосов
/ 31 июля 2017

datenwolf ответ велик, но содержит некоторую ошибку. Когда вы используете vbo, состояния клиента должны быть отключены после включения.

Добавьте три линии для рисования кода

void draw(GLfloat x, GLfloat y, GLfloat z)
{
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glTranslatef(x,y,z);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, &sphere_vertices[0]);
    glNormalPointer(GL_FLOAT, 0, &sphere_normals[0]);
    glTexCoordPointer(2, GL_FLOAT, 0, &sphere_texcoords[0]);
    glDrawElements(GL_QUADS, sphere_indices.size()/4, GL_UNSIGNED_SHORT, sphere_indices);

    **glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);**

    glPopMatrix();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...