如何在现代OpenGL中渲染多个纹理? [英] How do I render multiple textures in modern OpenGL?

查看:1053
本文介绍了如何在现代OpenGL中渲染多个纹理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为小型游戏编写2d引擎.

我的想法是我可以只用一个平局就可以渲染整个场景.我以为我可以将每个2d图像渲染在一个四边形上,这意味着我可以使用实例化.

我以为我的顶点着色器可能看起来像这样

...
in vec2 pos;
in mat3 model;
in sampler2d tex;
in vec2 uv;
...

我以为我可以像在VBO上那样在gpu上加载纹理并对其进行处理,但这似乎并不那么简单.

似乎我必须打电话

glActiveTexture(GL_TEXTURE0..N);

对于我要加载的每个纹理.现在,这似乎不像我想象的那么容易编程.现代游戏引擎如何渲染多个纹理?

我了解到GL_TEXTURE的纹理限制取决于GPU,但至少为45.如果我要渲染包含45个以上纹理(例如90个)的图像怎么办?

似乎我必须渲染前45个纹理,并从gpu删除所有纹理,然后将其他45个纹理从hdd加载到gpu.对于每一帧来说,这样做似乎都不是很合理.尤其是当我想为2D图像制作动画时.

我很容易想到一个2D角色的简单动画可以包含10个不同的图像.那意味着我可以轻松地超过纹理限制.

我的一个小想法是将多个图像组合成一个大图像,然后通过uv坐标进行偏移.

我想知道我是否误解了纹理在OpenGL中的工作方式.

如何在OpenGL中渲染多个纹理?

解决方案

问题有点广泛,因此,这只是对在同一绘制调用中使用多个纹理的某些选项的简要概述.

绑定到多个纹理单元

对于这种方法,您可以使用典型序列将每个纹理绑定到不同的纹理单元:

glActiveTexture(GL_TEXTUREi);
glBindTexture(GL_TEXTURE_2D, tex[I]);

在着色器中,您可以有一堆单独的sampler2D制服,也可以有一个sampler2D制服数组.

主要缺点是您受到可用纹理单元数量的限制.

阵列纹理

您可以使用数组纹理.这是通过使用GL_TEXTURE_2D_ARRAY纹理目标来完成的.在许多方面,2D纹理阵列类似于3D纹理.它基本上是一堆彼此堆叠的2D纹理,并存储在单个纹理对象中.

缺点是所有纹理都必须具有相同的大小.如果不这样做,则必须使用最大的大小作为纹理数组的大小,而浪费内存用于较小的纹理.如果大小不尽相同,还必须对纹理坐标应用缩放.

纹理图集

这是您已经提出的想法.您将所有纹理存储在一个大的纹理中,并使用纹理坐标来控制使用哪个纹理.

尽管这是一种流行的方法,但与此同时存在一些技术挑战.您必须注意纹理之间的接缝,以免在使用线性采样时它们不会相互渗出.而且,虽然这种方法与纹理阵列不同,但可以在不浪费内存的情况下允许使用不同的纹理大小,但在地图集中分配可变大小的区域会变得有些棘手.

无框纹理

到目前为止,它仅可作为扩展使用: ARB_bindless_texture .

I am currently writing a 2d engine for a small game.

The idea was that I could render the whole scene in just one draw call. I thought I could render every 2d image on a quad which means that I could use instancing.

I imagined that my vertex shader could look like this

...
in vec2 pos;
in mat3 model;
in sampler2d tex;
in vec2 uv;
...

I thought I could just load a texture on the gpu and get a handle to it like I would do with a VBO, but it seems it is not that simple.

It seems that I have to call

glActiveTexture(GL_TEXTURE0..N);

for every texture that I want to load. Now this doesn't seem as easy to program as I thought. How do modern game engines render multiple textures?

I read that the texture limit of GL_TEXTURE is dependent on the GPU but it is at least 45. What if I want to render an image that consists of more than 45 textures for example 90?

It seems that I would have to render the first 45 textures and delete all the texture from the gpu and load the other 45 textures from the hdd to the gpu. That doesn't seem very reasonable to do every frame. Especially when I want to to animate a 2D image.

I could easily think that a simple animation of a 2d character could consist of 10 different images. That would mean I could easily over step the texture limit.

A small idea of mine was to combine multiple images in to one mega image and then offset them via uv coordinates.

I wonder if I just misunderstood how textures work in OpenGL.

How would you render multiple textures in OpenGL?

解决方案

The question is somewhat broad, so this is just a quick overview of some options for using multiple textures in the same draw call.

Bind to multiple texture units

For this approach, you bind each texture to a different texture unit, using the typical sequence:

glActiveTexture(GL_TEXTUREi);
glBindTexture(GL_TEXTURE_2D, tex[I]);

In the shader, you can have either a bunch of separate sampler2D uniforms, or an array of sampler2D uniforms.

The main downside of this is that you're limited by the number of available texture units.

Array textures

You can use array textures. This is done by using the GL_TEXTURE_2D_ARRAY texture target. In many ways, a 2D texture array is similar to a 3D texture. It's basically a bunch of 2D textures stacked on top of each other, and stored in a single texture object.

The downside is that all textures need to have the same size. If they don't, you have to use the largest size for the size of the texture array, and you waste memory for the smaller textures. You'll also have to apply scaling to your texture coordinates if the sizes aren't all the same.

Texture atlas

This is the idea you already presented. You store all textures in a single large texture, and use the texture coordinates to control which texture is used.

While a popular approach, there are some technical challenges with this. You have to be careful at the seams between textures so that they don't bleed into each other when using linear sampling. And while this approach, unlike texture arrays, allows for different texture sizes without wasting memory, allocating regions within the atlas gets a little trickier with variable sizes.

Bindless textures

This is only available as an extension so far: ARB_bindless_texture.

这篇关于如何在现代OpenGL中渲染多个纹理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆