2013-04-06 2 views
0

Создайте простой 2D-спрайт-движок с кросс-платформой, абстрагированный API ■ Демонстрационная версия должна быть полностью перекрестной платформой и не иметь конкретных платформ ■ Кодовый код полностью изолирован от зависимого от платформы кода, поскольку в каких-либо независимых по платформе файлах нет следов каких-либо включений определенных в платформе заголовков.C++ как сделать независимую платформу двигателя 2d

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

+0

[Я буквально только что ответил на это] (http://stackoverflow.com/q/15849419/150634). Но возможно, что ваш учитель ищет более простое решение. –

ответ

0

Ну, если вы хотите независимый от платформы двигатель, вам нужна портативная библиотека.

Прежде всего, есть Qt, который сам предлагает абстракцию для графики OpenGL (просто открытие контекста OpenGL на нескольких разных платформах может стать основной болью в нижней области, но Qt делает его портативным, гибким и просто в нескольких строках кода). Он также имеет QML, который является декларативным языком, с которым гораздо быстрее развиваться. Существует множество двигателей 2d и 3d, построенных вокруг Qt (проверьте V-Play). С QtQuick2 у вас есть аппаратная ускоренная графика. Вы можете даже ввести пробельные фрагменты и векторные шейдеры на ваши 2d-объекты во время выполнения.

Тогда есть библиотеки, такие как Allegro и SDL - они довольно портативны, хотя поддержка мобильных платформ находится в довольно насыщенной стадии. Сами библиотеки гораздо более просты, чем Qt. Оба поддерживают OpenGL, но их собственные графические возможности минимальны.

Существует также JUCE, который предлагает некоторые графические возможности, хотя вам в значительной степени придется полагаться на raw OpenGL, нет абстракции высокого уровня.

Тогда есть библиотеки, такие как MoSync или Marmalade, которые ориентированы на мобильную платформу, а поддержка настольных компьютеров, по-видимому, отсутствует, поэтому, возможно, не так хороша в выборе.

Причина, по которой я начинал с Qt, - это то, что она самая мощная, гибкая и независимая от всех альтернатив. Не говоря уже о том, что есть много книг, тонны учебников, отличная документация и значительное сообщество. Это то, что я использую и часто рекомендую. Вы можете даже создавать коммерческие приложения с ним бесплатно, единственное условие - вы динамически связываете.

1

Помимо простого создания вашего 2d-процессора поверх многоплатформенной библиотеки, как предлагает @ddriver, вы можете выделить большой буфер для цветов пикселей и написать код, чтобы отобразить все ваши примитивы (отдельные пиксели, линии, прямоугольники, круги , эллипсы, дуги, текстуры/растровые изображения/изображения, текстовые символы). Когда вы закончите рендеринг кадра в этом буфере, вы можете затем вызвать любую библиотеку, чтобы отобразить этот буфер как изображение на экране или в окне. Или, если ваш код работает на голом оборудовании без каких-либо библиотек поддержки, вы можете просто скопировать этот буфер в видео-буфер видеокарты.

Ваш API может выглядеть следующим образом:

typedef struct 
{ 
    unsigned BitsPerPixel; // 8,16,32 
    unsigned ColorScheme; // something that tells the order of the R, G and B components and how many bits are in each or if there's a palette used instead of RGB 
    unsigned Width; // in pixels 
    unsigned Height; // in pixels 
    size_t Size; // buffer size in bytes 
    void* Buf; // pointer to the beginning of the buffer itself 
    // extra info 
} tBuffer; 

int BufferInit(tBuffer* Buf, unsigned BitsPerPixel, unsigned ColorScheme, unsigned Width, unsigned Height) 
{ 
    Buf->BitsPerPixel = BitsPerPixel; 
    Buf->ColorScheme = ColorScheme; 
    Buf->Width = Width; 
    Buf->Height = Height; 
    Buf->Size = Buf->Width * Buf->Height * Buf->BitsPerPixel/8; 
    Buf->Buf = malloc(Buf->Size); 
    if (Buf->Buf != NULL) 
    { 
    memset(Buf->Buf, 0, Buf->Size); 
    return 1; 
    } 
    return 0; 
} 

void BufferDone(tBuffer* Buf) 
{ 
    free(Buf->Buf); 
    Buf->Buf = NULL; 
} 

unsigned FindClosest8BitPaletteIndex(unsigned R, unsigned G, unsigned B) 
{ 
    // find the palette element that's closest to the given R, G and B 
    // and return its index 
} 

unsigned BufferRgbToColor(tBuffer* Buf, unsigned R, unsigned G, unsigned B) 
{ 
    switch (Buf->BitsPerPixel) 
    { 
    case 8: 
    return FindClosest8BitPaletteIndex(R, G, B); 
    case 16: 
    return ((R & 0x1F) << 11) | ((G & 0x3F) << 6) | (B & 0x1F); // 5-6-5 
    case 32: 
    return ((R & 0xFF) << 16) | ((G & 0xFF) << 8) | (B & 0xFF); // (8)-8-8-8 
    default: 
    return 0; // error 
    } 
} 

void BufferSetPixel(tBuffer* Buf, unsigned X, unsigned Y, unsigned Color) 
{ 
    switch (Buf->BitsPerPixel) 
    { 
    case 8: 
    *((unsigned char*)Buf->Buf + Buf->Width * Y + X) = Color; 
    break; 
    case 16: 
    *((unsigned short*)Buf->Buf + Buf->Width * Y + X) = Color; 
    break; 
    case 32: 
    *((unsigned*)Buf->Buf + Buf->Width * Y + X) = Color; 
    break; 
    } 
} 

И тогда вы могли бы использовать его как это:

tBuffer buf; 
if (BufferInit(&buf, 32, 0, 1024, 768)) 
{ 
    BufferSetPixel(&buf, 512, 384, BufferRgbToColor(&buf, 0xFF, 0xFF, 0xFF)); 
    // make the contents of buf.Buf visible in some way 
    BufferDone(&buf); 
} 

Это должно дать вам некоторые идеи.

Смежные вопросы