0

在我正在编写的游戏中,我希望有一个专用服务器连接到具有 OpenGL 渲染的客户端。一切看起来都很好,除了服务器不幸地依赖于 mesa/OpenGL。理想情况下,我希望能够拥有一台专用服务器,而无需在终端上安装任何东西。

基本上,它归结为这一点。我的每个游戏对象都有一个精灵。为了渲染这个精灵,图像数据必须通过 发送到显卡glTexImage2D,并且 aGLuint与纹理数据相关联。要渲染纹理,您需要纹理 ID。

我通过使用两个不同的主文件将客户端与服务器分开,它们共享相同的核心游戏文件。只有客户端#include的图形相关文件。我的整体班级结构如下所示:

//Core game stuff
class Image
{
    int width, height;
    //Image data
}

class Sprite
{
    const Image image;
}

//Graphics namespace
void renderObject()
{
    //Some rendering code...

    GLuint texId = loadTexture(someSprite.image);

    renderTexture(texId);

    unloadTexture(texId);
}

现在,这看起来很棒,直到我们意识到每帧将图像数据发送到显卡很并且需要缓存。GLuint将 存储在图像上,甚至给它一个getTexture()功能是有意义的。如果未设置,该函数将加载纹理并返回 id。因此,图像数据只会被发送到图形卡一次。

//Core game stuff
class Image
{
    int width, height;
    //Image data

    GLuint textureId;

  public:

    ~Image()
    {
        //...

        unloadTexture(textureId);
    }

    GLuint getTexture()
    {
        if(!textureId)
            return textureId = loadTexture();
        else
            return textureId;
    }
}

class Sprite
{
    const Image image;
}

//Graphics namespace
void renderObject()
{
    //Some rendering code...

    renderTexture(someSprite.image.getTexture());  //loadTexture() is only called once
}

但是,由于使用gl*函数和 a#include <GL/gl.h>这使得Image依赖于 OpenGL,这使得我所有的游戏对象都依赖于 OpenGL。此时,我的代码的服务器版本(没有 OpenGL 上下文或渲染)依赖于 OpenGL。

你建议我如何解决这个问题?A#ifdef CLIENT将是一种解决方案,但我想避免它。

4

2 回答 2

5

您将通过放弃整个客户端/服务器架构并正确执行来解决此问题。

服务器根本不需要知道任何关于 OpenGL 的知识。它不需要知道“精灵”或“图像”。它甚至不需要知道特定客户应该绘制什么。服务器需要做的就是维护世界的状态,将该状态发送给各个客户端,并根据这些客户端提供的输入更新该状态。

如果您的服务器甚至加载“图像”和“精灵”,那么您做错了客户端/服务器。它应该加载的只是这些对象具有的任何物理和碰撞属性。由每个单独的客户端来加载“图像”等等。

您的服务器根本不应该使用 OpenGL。

于 2013-05-31T15:57:45.053 回答
1

我读到您的帖子要求(1)对上面的代码进行最小的更改,以及(2)不使用任何预处理器结构。

由于您不允许编译时区分(例如使用#ifdef),解决方案很可能归结为客户端在运行时设置一些数据以更改执行路径。这个想法最直接的体现是全局函数指针:

unsigned int (*loadTexturePtr)(int width, int height, void *pixels) = NULL; 
void (*unloadTexturePtr)(unsigned int texId) = NULL; 

客户端初始化代码将它们设置为指向依赖于 GL 的实现。您的图像代码几乎没有变化:

class Image
{
unsigned int textureId;
public:
~Image() 
{
  if (textureId && unloadTexturePtr) unloadTexturePtr(textureId);
}
unsigned int getTexture()
{
  if(!textureId && loadTexturePtr) textureId = loadTexturePtr(...);
  return textureId;
}
...
}
于 2013-06-01T09:37:10.043 回答