C++如何使二维引擎平台独立

标签 c++ cross-platform abstraction pimpl-idiom

使用跨平台的抽象 API 创建一个简单的 2D Sprite 引擎 ■ 演示应该是完全跨平台的,并且没有特定于平台的 header ■ 跨平台代码与平台相关代码完全隔离,因为在任何平台独立文件中都没有任何包含平台特定 header 的痕迹。

我有这个任务,但我对如何制作跨平台的东西感到非常困惑。我已经有一个引擎能够完成它必须做的事情,但我需要它是跨平台的。我主要想知道我可以包括什么东西(或者,我怎么知道某些东西是否使用特定于平台的代码),如果我不能包括东西因为它们是特定于平台的,我不知道我如何在没有的情况下使用该功能包括它。根据一位同学的说法,解决方案位于抽象和 Pimpl 的某个地方,但我找不到。

最佳答案

除了像@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);
}

这应该会给你一些想法。

关于C++如何使二维引擎平台独立,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15849921/

相关文章:

c++ - 我什么时候应该为函数/方法写关键字 'inline'?

c++ - 这是什么人物?

android - 这可能吗,GNOME (lib)Clutter with OpenGL ES & Vulkane?

c++ - 如何在 C++ 中获取当前时间和日期?

haskell - 如何在 Haskell 中创建两个具有内部状态的相互生产者/消费者?

c++ - 向上转换一个 const vector

java - JNI_OnLoad 获取Java调用包+类名

c++ - C++ 中的大文件支持

java - 返回一个字符串供父类(super class)的抽象方法显示

language-agnostic - 多少抽象就太多了?