0

Create a simple 2D sprite engine with a cross platform, abstracted API ■ The demo should be completely cross platform and have no platform specific headers ■ The cross platform code is isolated completely from platform dependent code, in that there is no trace of any includes of platform specific headers in any platform independent files.

I have this assignment, but I'm terribly confused as to how I can make something cross platform. I already have an engine capable of doing the things it has to, but I need it to be crossplatform. I am mostly wondering what things I can include (or, How do i know if something uses platform specific code), and if i can't include things because they are platform specific, I don't know how i can use that functionality without including it. Solution lies somewhere in abstraction and Pimpl according to a fellow student, but I can't find it.

  • [I literally just answered this](http://stackoverflow.com/q/15849419/150634). But it's possible that your teacher is looking for a simpler solution. – Joseph Mansfield Apr 06 '13 at 10:47

2 Answers2

1

Besides simply building your 2d engine on top of a multi-platform library as @ddriver is suggesting, you can allocate a large buffer for pixel colors and write code to render all your primitives (individual pixels, lines, boxes, circles, ellipses, arcs, textures/bitmaps/images, text characters) into it. Once you've completed rendering of a frame in this buffer you can then call whatever library is there to display this buffer as an image on the screen or in a window. Or, if your code is running on bare hardware w/o any support libraries, you can simply copy this buffer into the video buffer of the graphics card.

Your API could look something like this:

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;
  }
}

And then you could use it like this:

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);
}

This should give you some ideas.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
0

Well, if you want a platform independent engine then you need a portable library.

First and foremost, there is Qt, which itself offers abstraction to do OpenGL graphics(just opening an OpenGL context on a few different platforms can be a major pain i the bottom area, but Qt makes it portable, flexible and just in a few lines of code). It also has QML, which is a declarative language that is much faster to develop with. There is a number of 2d and 3d engines built around Qt (check out V-Play). With QtQuick2 you have hardware accelerated graphics. You can even type run fragment and vector shaders on your 2d objects during the runtime.

Then there are libraries like Allegro and SDL - they are fairly portable, although support for mobile platforms is in a pretty raw stage. The libraries themselves are far more basic than Qt. Both support OpenGL, but their own graphics capabilities are miniscule.

There is also JUCE, that offers some graphics capabilities, although you will pretty much have to rely on raw OpenGL, there is no high level abstraction.

Then there are libraries like MoSync or Marmalade, which are mobile platform focused and desktop support seems to be absent, so maybe not as good of a choice.

The reason I started with Qt is because it by far the most powerful, flexible and platform independent of all alternatives. Not to mention there are many books, tons of tutorials, great detailed documentation and a significant community. It is what I use and often recommended. You can even develop commercial applications with it for free, the only condition is you link dynamically.

dtech
  • 47,916
  • 17
  • 112
  • 190