【问题标题】:How to create textures within GPU如何在 GPU 中创建纹理
【发布时间】:2010-12-01 08:48:22
【问题描述】:

谁能告诉我如何使用硬件内存在 OpenGL 中创建纹理?目前我在窗口模式下运行我的游戏,我是否需要切换到全屏才能使用硬件?

如果我可以在硬件中创建纹理,纹理数量是否有限制(硬件内存除外)?然后如何将我的纹理缓存到硬件中?谢谢。

【问题讨论】:

  • 您要创建纹理对象还是纹理数据?
  • 再一次,我的意思是有没有办法在GPU中缓存纹理数据,而不是在我们需要绘制的时候发送纹理的所有数据?

标签: opengl textures


【解决方案1】:

几乎所有的 OpenGL 纹理教程都应该涵盖这一点。例如hereherehere

对于每个纹理,您首先需要一个纹理名称。纹理名称就像单个纹理的唯一索引。每个名称都指向一个可以有自己的参数、数据等的纹理对象。glGenTextures 用于获取新名称。我不知道除了 uint 范围(2^32)之外是否有任何限制。如果有,那么对于所有新纹理名称,您可能会得到 0(以及 gl 错误)。

下一步是绑定你的纹理(见glBindTexture)。之后,所有使用或影响纹理的操作都将使用您用作 glBindTexture 参数的纹理名称指定的纹理。您现在可以设置纹理参数 (glTexParameter) 并使用 glTexImage2D 上传纹理数据(用于 2D 纹理)。调用 glTexImage 后,您还可以使用纹理数据释放系统内存。

对于静态纹理,所有这些都只需要完成一次。如果要使用纹理,只需再次绑定并启用纹理 (glEnable(GL_TEXTURE_2D))。

单个纹理的大小(宽度/高度)受 GL_MAX_TEXTURE_SIZE 限制。这通常是 4096、8192 或 16384。它还受到可用图形内存的限制,因为它必须与帧缓冲区或顶点缓冲区等其他一些资源一起适应它。所有纹理加在一起可以大于可用内存,但随后它们将被交换。

在大多数情况下,图形驱动程序应决定哪些纹理存储在系统内存中,哪些存储在图形内存中。但是,您可以使用 glPrioritizeTextures 或 glTexParameter 为某些纹理赋予更高的优先级。

编辑: 我不会太担心纹理的存储位置,因为驱动程序通常在这方面做得很好。经常使用的纹理也更有可能存储在图形内存中。如果您设置了一个优先级,这只是对驱动程序的“提示”,即纹理保留在显卡上的重要性。也有可能完全忽略优先级。您还可以使用glAreTexturesResident 检查纹理当前的位置。

【讨论】:

  • 除了 glPrioritizeTextures 之外,我自己已经完成了所有这些工作。但是感谢您花时间详细解释它。关于您的遗言,这就是我要问的...强制纹理存储在图形内存中,而不是让驱动程序决定? glPrioritizeTextures,这是完成此任务的唯一方法吗?
【解决方案2】:

通常当您谈论在 GPU 上生成纹理时,您实际上并不是在创建纹理图像并像普通纹理一样应用它们。更简单和更常见的方法是使用片段着色器从头开始实时程序计算每个像素的颜色。
典型的例子是在一个物体的表面上生成一个曼德布洛图案,比如一个茶壶。茶壶由应用程序使用其多边形和纹理坐标进行渲染。在渲染管道的某个阶段,茶壶的每个像素都通过片段着色器,片段着色器是应用程序发送到 GPU 的小程序。片段着色器读取 2D 纹理坐标并计算 2D 坐标的 Mandelbrot 集颜色并将其应用于像素。

全屏模式与它无关。即使您处于窗口模式,也可以使用着色器并生成纹理。正如我所提到的,您创建的纹理实际上从未占用纹理内存中的空间,它们是动态创建的。人们可能会想到一种方法来捕获和缓存生成的纹理,但这可能有点复杂并且需要多次渲染。

如果您在 google 中查找“GLSL” - OpenGL 着色语言,您可以了解更多信息。
This somewhat dated tutorial 展示了如何创建一个简单的片段着色器来绘制 Mandelbrot 集(第 4 页)。
如果您可以阅读“OpenGL Shading Language, 2nd Edition”一书,您会发现它包含许多简单的示例,这些示例通过应用程序的外部 3D Perlin 噪声纹理生成天空、火和木材纹理.

【讨论】:

    【解决方案3】:

    要在 GPU 上创建纹理,请查看“渲染到纹理”教程。有两种常用方法:将 PBuffer 上下文绑定为纹理,或使用帧缓冲区对象。 PBuffer 渲染到纹理是较旧的方法,并且具有更广泛的支持。帧缓冲区对象更易于使用。

    此外,您不必切换到“全屏”模式即可让 OpenGL 进行硬件加速。事实上,OpenGL 根本不知道窗口。全屏 OpenGL 窗口就是这样:在所有其他窗口之上的一个顶部窗口,没有任何装饰并且输入焦点被抓取。一些驱动程序绕过窗口屏蔽和剪辑代码,如果具有活动 OpenGL 上下文的窗口覆盖整个屏幕,则采用更简单、更快的缓冲区交换方法,从而获得一点性能,但与当前的硬件和软件相比,效果非常小其他影响。

    【讨论】:

      猜你喜欢
      • 2013-01-01
      • 2020-01-09
      • 1970-01-01
      • 2013-10-27
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 2011-08-13
      相关资源
      最近更新 更多