Объектно-ориентированная абстракция C ++ - PullRequest
1 голос
/ 22 января 2012

Справочная информация

В настоящее время я учусь на уроке компьютерной графики.Мы изучаем основные понятия, создавая абстракцию, которую может использовать каждый (простая библиотека 3D).Мы используем SDL для реальной графической части.На самом деле все, для чего мы используем SDL - это рендеринг и управление пиксельным буфером.Нам разрешено использовать только это.Но наша абстракция должна позволять клиенту рисовать пиксели, линии, треугольники и т. Д. Вплоть до завершения моделей, составленных из этих треугольников.

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

Мой вопрос

Я не столько ищу обзор своего кода, сколько мне нужны общие советы и предложения о том, как создать этот код.Библиотека SDL, использующая звуковые объектно-ориентированные принципы.

То, что у меня есть до сих пор

Мой код на самом деле хорошо использует некоторые объектно-ориентированные принципы.Пока у меня хорошо работают следующие объекты:

  • Vec4 - представляет координаты или цвета.Это делает операции, связанные с векторами.
  • Mat4 - представляет собой матрицу 4x4, которую я использую для преобразований и тому подобное.Выполняет ли операции, связанные с матрицами, такие как умножение на другую матрицу, на vec4 и т. Д.
  • MatrixFactory - создает различные типы Mat4 (MatrixTranslate, MatrixRotate и т. Д.)
  • Shape - используемый интерфейсчтобы упростить рисование различных фигур
    • Точка: форма
    • Линия: форма
    • Треугольник: форма

My "Сам движок выполняет следующие действия (в некоторой степени основанные на структуре three.js ):

  • Создает окно (главное окно, в котором рисуются предметы)
  • Создает сцену (где отображаются фигуры)
  • Регистрирует функции обратного вызова на основе событий клавиатуры (нажатий клавиш)

Где я особенно борюсь

Главное, с чем я до сих пор борюсь, это обработка обратных вызовов.Например, чтобы нарисовать треугольник, я сейчас делаю что-то вроде следующего:

int main()
{
    // Create instance of my library
    RDL* rdl = new RDL(WIDTH, HEIGHT, 32); 


    // Draw a triangle when T is pressed
    // RDL_KEY_t = #define RDL_KEY_t SDLK_t for consistency 
    rdl->registerKeyEvent(RDL_KEY_t, drawTriangle);

    rdl->show();

    return 0;
}


// X, Y, Z and R, G, B are random values not shown for simplicity
void drawTriangle(RDL* rdl)
{
    RDL_Point p1(Vec4(X, Y, Z), Vec4(R, G, B));
    RDL_Point p2(Vec4(X, Y, Z), Vec4(R, G, B));
    RDL_Point p3(Vec4(X, Y, Z), Vec4(R, G, B));

    rdl->insertShape(RDL_Triangle(pt1, pt2, pt3));
}

Внутри RDL :: show () я запускаю стандартный цикл SDL, где я делаю 2 вещи:

  • Позвоните любым зарегистрированным обратным вызовам
  • Нарисованные фигуры в моем векторе, где хранятся все фигуры

Но это не хорошо.Если я вставлю 10 треугольников, они все хорошо рисуют.Но если я хочу повернуть конкретный объект, я не могу этого сделать, потому что мои обратные вызовы дают мне доступ только к моему объекту RDL из main.

Есть идеи, советы или общие советы?

Большое спасибо.Я знаю, что это длинный вопрос ...

1 Ответ

2 голосов
/ 22 января 2012

Ваши обратные вызовы - простые старые функции.Вот что с ними не так.Представьте, что вы можете иметь только функции без аргументов.Или функции с одним аргументом типа fixrmed.Вы бы не зашли слишком далеко с этим.Но ваши обратные вызовы такие же.

Вы хотите иметь возможность передавать функции и ее аргументы в RegisterXyzEvent().Когда придет время, ваш фреймворк должен вызвать функцию с предоставленными аргументами.

Функция, связанная с (некоторыми из) ее аргументами, вызывается в C ++ - говорят «связанная функция» или «объект функции» или иногда«функтор» (последнее, к сожалению, очень неправильное имя).Вам нужно узнать, как работают эти связанные функции, как их создавать, как использовать те из них, которые поставляются с стандартной библиотекой, и как создавать свои собственные.Затем заставьте RegisterXyzEvent() принимать такие функциональные объекты, и заставьте ваш фреймворк вызывать их.

Некоторые ключевые слова для поиска: объект функции, boost :: bind, std :: function.

Извините закраткий ответ без примеров.Клавиатура моего телефона утомительна, и я думаю, что тебе все равно лучше учить это на своем собственном.

...