OpenGL阵列纹理根本不渲染

OpenGL阵列纹理根本不渲染,opengl,textures,lwjgl,Opengl,Textures,Lwjgl,我目前正在将一个项目从使用纹理图集转换为阵列纹理,但就我而言,我无法让它工作 关于我的环境的一些注意事项: 我正在使用OpenGL3.3核心上下文和GLSL版本3.30 纹理都是128x128,在使用atlas时渲染得非常精细(除了说服我切换的边缘瑕疵) 我认为我已经排除了以下问题: 解决问题-128x128,是2的幂,应该可以 纹理加载(与以前一样工作正常) 不完整的纹理(mipmap问题)-我已经讨论了关于mipmap的常见问题,我不认为OpenGL应该期待它们 以下是我创建阵列纹理

我目前正在将一个项目从使用纹理图集转换为阵列纹理,但就我而言,我无法让它工作

关于我的环境的一些注意事项:

  • 我正在使用OpenGL3.3核心上下文和GLSL版本3.30
  • 纹理都是128x128,在使用atlas时渲染得非常精细(除了说服我切换的边缘瑕疵)
我认为我已经排除了以下问题:

  • 解决问题-128x128,是2的幂,应该可以
  • 纹理加载(与以前一样工作正常)
  • 不完整的纹理(mipmap问题)-我已经讨论了关于mipmap的常见问题,我不认为OpenGL应该期待它们
以下是我创建阵列纹理的代码:

public void createTextureArray(){
glTexParameteri(GL_纹理2D_数组、GL_纹理minu过滤器、GL_线性);
glTexParameteri(GL_纹理2D_数组,GL_纹理MAG_过滤器,GL_线性);
glTexParameteri(GL_纹理2D_数组、GL_纹理包裹、GL_夹紧到边);
glTexParameteri(GL_纹理2D_数组、GL_纹理包裹、GL_夹紧到边);
int handle=glGenTextures();
玻璃纹理(GL_纹理0);
glBindTexture(GL_纹理_2D_数组,句柄);
glPixelStorei(GL_解包_行长度、纹理、大小);
glPixelStorei(GLU解包对齐,4);
glTexStorage3D(GL_纹理_2D_数组,1,GL_RGBA8,TEXTURE.SIZE,TEXTURE.SIZE,textures.SIZE());
试一试{
int层=0;
对于(纹理纹理:textures.values()){
//接下来的几行只是用于加载纹理。它们已被排除在问题之外。
PNGDecoder解码器=新的PNGDecoder(ImageHelper.asInputStream(tex.getImage());
ByteBuffer buffer=BufferUtils.createByteBuffer(decoder.getWidth()*decoder.getHeight()*4);
decoder.decode(buffer,decoder.getWidth()*4,PNGDecoder.Format.RGBA);
flip();
glTexSubImage3D(GL_纹理_2D_数组,0,0,层,解码器.getWidth(),解码器.getHeight(),1,
GL_RGBA,GL_无符号字节,缓冲区);
tex.setLayer(层);
层++;
}
}捕获(IOEX异常){
例如printStackTrace();
System.err.println(“未能创建/加载纹理数组”);
系统退出(-1);
}
}
创建VAO/VBO的代码:

private static int prepareVbo(int句柄,FloatBuffer vbo){
IntBuffer vaoHandle=BufferUtils.createIntBuffer(1);
Glgenvertexarray(沃汉德尔);
glBindVertexArray(vaoHandle.get());
glBindBuffer(GL_数组_缓冲区,句柄);
glBufferData(GLU数组缓冲区、vbo、GLU静态绘图);
玻璃纹理(GL_纹理0);
glBindTexture(GL_纹理_2D_数组,GraphicsMain.TEXTURE_注册表.atlasHandle);
glEnableVertexAttribArray(位置属性索引);
GlenableVertexAttributeArray(texCoordAttrIndex);
GLVertexAttributePointer(positionAttrIndex,3,GL_FLOAT,false,24,0);
glvertexattributepointer(texCoordAttrIndex,3,GL_FLOAT,false,24,12);
glBindVertexArray(0);
vaoHandle.rewind();
返回vaoHandle.get();
}
片段着色器:

#版本330核心
均匀采样阵列;
可变vec3-texCoord;
void main(){
gl_FragColor=纹理(texArray,texCoord);
}
texCoord
工作正常;它从顶点着色器正确传递。)

我已经没有想法了,所以对于现代OpenGL来说还是有点陌生,我想知道我的代码是否有明显的错误。

一些注意事项:

  • 你不需要更多的东西来拥有两种纹理的力量
  • 确保每个层的级别/mipmap数与wiki相同
  • 前四个
    glTexParameteri
    将影响此时绑定到
    GL\u TEXTURE\u 2D\u数组的内容,因此您最好在
    glBindTexture
    之后移动它们
  • 如何指定要使用
    glGenTextures()
    创建多少纹理?如果你有一个更具体的方法的可能性,请使用它
  • 如果大于0,则定义行中的像素数。然后我想
    Texture.SIZE
    实际上不是纹理大小,而是一侧的尺寸(在您的例子中是128)。不管怎样,你不需要设置它,你可以跳过它
  • 仅当行长度是行长度的倍数时,才将
    GL\u UNPACK\u对齐设置为4。大多数情况下,人们在加载纹理之前将其设置为1以避免任何麻烦,然后在完成后将其设置回4
  • glTexStorage3D
    的最后一个参数应该是层数,我希望
    textures.size()
    能更好地返回层数,而不是大小(128x128)
  • glActiveTexture
    glBindTexture
    内部
    prepareVbo
    是无用的,它们不是vao的一部分
  • 不要在glsl中使用
    variable
    ,它已被弃用,请切换到简单的
    in-out
  • 你可能想从中获得灵感
  • 使用采样器,他们给你更多的灵活性
  • 如果可用,请使用,否则
    glGetError()
    ,渲染输出可能无法清楚地看到一些无声错误
  • 您调用了它
    prepareVbo
    ,但您确实在其中初始化了vao和vbo
一些注意事项:

  • 你不需要更多的东西来拥有两种纹理的力量
  • 确保每个层的级别/mipmap数与wiki相同
  • 前四个
    glTexParameteri
    将影响此时绑定到
    GL\u TEXTURE\u 2D\u数组的内容,因此您最好在
    glBindTexture
    之后移动它们
  • 如何指定要使用
    glGenTextures()
    创建多少纹理?如果你有一个更具体的方法的可能性,请使用它
  • 如果大于0,则定义行中的像素数。我想