0

クロス プラットフォームの抽象化された API を使用して単純な 2D スプライト エンジンを作成します ■ デモは完全にクロス プラットフォームであり、プラットフォーム固有のヘッダーはありません ■ クロス プラットフォームのコードはプラットフォームに依存するコードから完全に分離されています。プラットフォームに依存しないファイル内のプラットフォーム固有のヘッダー。

私はこの課題を抱えていますが、どうすればクロスプラットフォームのものを作ることができるかについてひどく混乱しています. 必要なことを実行できるエンジンを既に持っていますが、クロスプラットフォームである必要があります。私は主に、どのようなものを含めることができるのか (または、何かがプラットフォーム固有のコードを使用しているかどうかを知るにはどうすればよいのか) を考えています。また、それらがプラットフォーム固有であるために含めることができない場合、その機能を使用する方法がわかりません。それを含めて。仲間の学生によると、解決策は抽象化と Pimpl のどこかにありますが、私はそれを見つけることができません。

4

2 に答える 2

1

@ddriver が提案しているように、マルチプラットフォーム ライブラリの上に 2D エンジンを構築するだけでなく、ピクセルの色に大きなバッファーを割り当て、すべてのプリミティブ (個々のピクセル、線、ボックス、円、楕円、弧) をレンダリングするコードを記述できます。 、テクスチャ/ビットマップ/画像、テキスト文字) をそれに入れます。このバッファ内のフレームのレンダリングが完了したら、そこにあるライブラリを呼び出して、このバッファを画像として画面またはウィンドウに表示できます。または、コードがサポート ライブラリのないベア ハードウェアで実行されている場合は、このバッファをグラフィック カードのビデオ バッファに単純にコピーできます。

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

これにより、いくつかのアイデアが得られるはずです。

于 2013-04-06T12:44:24.370 に答える