So I'm currently trying to replace my old texture atlas stitcher with a 2D texture array to make life simpler with anisotropic filtering and greedy meshing later on.
因此,我目前正在尝试用2D纹理数组替换旧的纹理图集缝合器,以便在以后使用各向异性过滤和贪婪网格化来简化生活。
I'm loading the png files with stb and I know that the buffers are filled properly because if I export every single layer of the soon to be atlas right before uploading it it's the correct png file.
我正在用stb加载png文件,我知道缓冲区已正确填充,因为如果我在上传之前导出即将成为地图册的每一层,那么它就是正确的png文件。
My setup works like this:
我的设置如下:
I'm loading every single texture in my jar file with stb and create an object with it that stores the width, height, layer and pixelData in it.
我正在使用stb加载我的jar文件中的每个纹理,并使用它创建一个对象,该对象存储宽度,高度,图层和pixelData。
When every texture is loaded i look for the biggest texture and scale every smaller texture to the same size as the biggest because i know that 2D texture arrays only work if every single one of the layers has the same size.
当加载每个纹理时,我会寻找最大的纹理,并将每个较小的纹理缩放到与最大纹理相同的大小,因为我知道2D纹理数组只有在每个图层中的每一个具有相同的大小时才有效。
Then I initialize the 2d texture array like this:
然后我像这样初始化2d纹理数组:
public void init(int layerCount, boolean supportsAlpha, int textureSize) {
this.textureId = glGenTextures();
this.maxLayer = layerCount;
int internalFormat = supportsAlpha ? GL_RGBA8 : GL_RGB8;
this.format = supportsAlpha ? GL_RGBA : GL_RGB;
glBindTexture(GL_TEXTURE_2D_ARRAY, this.textureId);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalFormat, textureSize, textureSize, layerCount, 0, this.format, GL_UNSIGNED_BYTE, 0);
}
After that i go through my map of textureLayer objects and upload every single one of them like this:
之后,我浏览了textureLayer对象的地图,并按照以下方式上传每一个对象:
public void upload(ITextureLayer textureLayer) {
if (textureLayer.getLayer() >= this.maxLayer) {
LOGGER.error("Tried uploading a texture with a too big layer.");
return;
} else if (this.textureId == 0) {
LOGGER.error("Tried uploading texture layer to uninitialized texture array.");
return;
}
glBindTexture(GL_TEXTURE_2D_ARRAY, this.textureId);
// Tell openGL how to unpack the RGBA bytes
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Tell openGL to not blur the texture when it is stretched
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Upload the texture data
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureLayer.getLayer(), textureLayer.getWidth(), textureLayer.getHeight(), 0, this.format, GL_UNSIGNED_BYTE, textureLayer.getPixels());
int errorCode = glGetError();
if (errorCode != 0) LOGGER.error("Error while uploading texture layer {} to graphics card. {}", textureLayer.getLayer(), GLHelper.errorToString(errorCode));
}
The error code for every single one of my layers is 0, so I assume that everything went well. But when I debug the game with RenderDoc I can see that on every single layer every bit is 0 and therefore it's just a transparent texture with the correct width and height.
我的每一个图层的错误代码都是0,所以我认为一切都很顺利。但是当我使用RenderDoc调试游戏时,我可以看到每一层都是0,因此它只是一个具有正确宽度和高度的透明纹理。
I can't figure out what I'm doing wrong since openGL tells me everything went well. It is important to me that I only use openGL 3.3 and lower since I want the game to be playable on older PCs aswell so pre allocating memory with glTexStorage3D
is not an option.
我无法弄清楚我做错了什么,因为openGL告诉我一切顺利。对我来说很重要的是我只使用openGL 3.3和更低版本,因为我希望游戏能够在旧PC上播放,所以使用glTexStorage3D预分配内存不是一种选择。
1 个解决方案
#1
2
The 8th paramter of glTexSubImage3D
should be 1 (depth
).
Note, the size of the layer is textureLayer.getWidth()
, textureLayer.getHeight()
, 1
:
glTexSubImage3D的第8个参数应为1(深度)。注意,图层的大小是textureLayer.getWidth(),textureLayer.getHeight(),1:
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureLayer.getLayer(),
textureLayer.getWidth(), textureLayer.getHeight(), 1, // depth is 1
this.format, GL_UNSIGNED_BYTE, textureLayer.getPixels());
It is not an error to pass a width
, height
or depth
of 0 to glTexSubImage3D
, but it won't have any effect to the texture objects data store.
将宽度,高度或深度0传递给glTexSubImage3D并不是错误,但它对纹理对象数据存储没有任何影响。
#1
2
The 8th paramter of glTexSubImage3D
should be 1 (depth
).
Note, the size of the layer is textureLayer.getWidth()
, textureLayer.getHeight()
, 1
:
glTexSubImage3D的第8个参数应为1(深度)。注意,图层的大小是textureLayer.getWidth(),textureLayer.getHeight(),1:
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY, 0, 0, 0, textureLayer.getLayer(),
textureLayer.getWidth(), textureLayer.getHeight(), 1, // depth is 1
this.format, GL_UNSIGNED_BYTE, textureLayer.getPixels());
It is not an error to pass a width
, height
or depth
of 0 to glTexSubImage3D
, but it won't have any effect to the texture objects data store.
将宽度,高度或深度0传递给glTexSubImage3D并不是错误,但它对纹理对象数据存储没有任何影响。