简体   繁体   English

(LWJGL3)使用glTexSubImage3D上传图像数据后,OpenGL 2D纹理阵列保持为空

[英](LWJGL3) OpenGL 2D Texture Array stays empty after uploading image data with glTexSubImage3D

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. 我的每一层的错误代码均为0,因此我假设一切顺利。 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. 但是,当我使用RenderDoc调试游戏时,我可以看到在每个图层上每一位都是0,因此它只是具有正确宽度和高度的透明纹理。

I can't figure out what I'm doing wrong since openGL tells me everything went well. 我无法弄清楚自己在做什么错,因为openGL告诉我一切进展顺利。 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 3.3及更低版本,因为我希望游戏也可以在较旧的PC上玩,所以不能使用glTexStorage3D预先分配内存。

The 8th paramter of glTexSubImage3D should be 1 ( depth ). glTexSubImage3D的第8个参数应为1( depth )。
Note, the size of the layer is textureLayer.getWidth() , textureLayer.getHeight() , 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. glTexSubImage3D传递widthheightdepth 0 glTexSubImage3D ,但是对纹理对象数据存储区没有任何影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM