Объектно-ориентированное программирование и OpenGL - PullRequest
4 голосов
/ 10 июля 2011

Я хочу использовать OpenGL в качестве графики моего проекта.Но я очень хочу сделать это в хорошем стиле.Как я могу объявить функцию-член "draw ()" для каждого класса, чтобы вызвать его в функции отображения OpenGL?

Например, я хочу что-то вроде этого:

class Triangle
{
    public:
        void draw()
        {
           glBegin(GL_TRIANGLES);
              ...
           glEnd();
        }
};

Ответы [ 4 ]

2 голосов
/ 10 июля 2011

Ну, это также зависит от того, сколько у вас есть времени и что требуется. Ваш подход не плохой, хотя и немного старомодный. Современный OpenGL использует шейдеры, но я полагаю, это не охватывается вашим (школьным?) Проектом. Для этой цели и для начала, ваш подход должен быть полностью в порядке .

Помимо шейдеров, если вы хотите продвинуться немного дальше, вы также можете пойти в направлении использования более общих многоугольников объектов, просто храня список вершин и комбинируя его с отдельным 'Renderer' класс, способный отображать полигоны, состоящие из треугольников. Код будет выглядеть так:

renderer.draw(triangle);

Конечно, у многоугольника могут быть некоторые дополнительные атрибуты, такие как цвет, текстура, прозрачность и т. Д. Вы также можете иметь несколько более специфических классов многоугольников, таких как TriangleStrip, TriangleFan и т. Д. Тогда все, что вам нужно сделать, это написать общий метод draw() в вашем OpenGL Renderer, который сможет устанавливать все состояния и выдвигать вершины в конвейер рендеринга.

1 голос
/ 20 июля 2011

Нет, так работать не будет. Проблема в том, что функция дисплея GLUT представляет собой функцию one . Поэтому, если вы хотите нарисовать группу треугольников, вы все равно можете зарегистрировать только одну из их функций draw () в качестве функции отображения GLUT. (Кроме того, указатели на функции-члены в C ++ также являются сложной темой).

Итак, как предложено выше, перейдите на специальный класс Renderer. Этот класс будет знать обо всех прорисовываемых объектах в вашем приложении.

class Renderer {
   std::list<Drawable> _objects;

   public:
      drawAllObjects() {
         // iterate through _objects and call the respective draw() functions
      }
};

Ваша функция отображения GLUT будет статической функцией, которая вызывает drawAllObjects () для объекта рендерера (глобального или нет).

1 голос
/ 10 июля 2011

Когда я работал над своей докторской диссертацией, я написал симулятор, который делал то, что вы хотели сделать.Просто помните, что даже если ваш код может выглядеть объектно-ориентированным, движок OpenGL по-прежнему визуализирует вещи последовательно.Кроме того, последовательная природа матричной алгебры, которая скрыта в OpenGL, иногда не в том порядке, в котором вы логично думаете (когда я переводю, когда рисую, когда вращаю и т. Д.?).

Помните ЛОГОТИП назад в старые времена?У него была черепаха, которая была ручкой, и вы перемещали черепаху вокруг, и она рисовала линии.Если ручка была внизу, она рисовала, а если ручка была вверху, то нет.Именно так я и думал, когда работал над этой программой.Я бы начал «черепаху» с известной координаты (0, 0, 0) и использовал математические выражения для ее перевода (переместить ее в центр объекта, который я хочу нарисовать), а затем вызвал бы методы draw ()пытаюсь написать, чтобы нарисовать мою форму на основе относительной системы координат, где "черепаха", а не из абсолютного (0, 0, 0).Тогда я бы двигался, черепаха, рисовал и т. Д. Надеюсь, это поможет ...

0 голосов
/ 10 июля 2011

Ах, старый добрый OpenGL в немедленном режиме.:) Эта подпрограмма выглядит прекрасно.

Я бы, вероятно, сделал метод 'draw' виртуальным, хотя бы и наследовал от базового типа 'Drawable', который определяет методы, которые имеют такие классы.

...