我目前正在努力将项目从使用纹理图集转换为数组纹理,但对于我的生活,我无法让它工作。
关于我的环境的一些注意事项:
我相信我已经排除了问题:
这是我创建数组纹理的代码:
public void createTextureArray() {
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int handle = glGenTextures();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, handle);
glPixelStorei(GL_UNPACK_ROW_LENGTH, Texture.SIZE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, Texture.SIZE, Texture.SIZE, textures.size());
try {
int layer = 0;
for (Texture tex : textures.values()) {
// Next few lines are just for loading the texture. They've been ruled out as the issue.
PNGDecoder decoder = new PNGDecoder(ImageHelper.asInputStream(tex.getImage()));
ByteBuffer buffer = BufferUtils.createByteBuffer(decoder.getWidth() * decoder.getHeight() * 4);
decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
buffer.flip();
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, decoder.getWidth(), decoder.getHeight(), 1,
GL_RGBA, GL_UNSIGNED_BYTE, buffer);
tex.setLayer(layer);
layer++;
}
} catch (IOException ex) {
ex.printStackTrace();
System.err.println("Failed to create/load texture array");
System.exit(-1);
}
}
创建VAO / VBO的代码:
private static int prepareVbo(int handle, FloatBuffer vbo) {
IntBuffer vaoHandle = BufferUtils.createIntBuffer(1);
glGenVertexArrays(vaoHandle);
glBindVertexArray(vaoHandle.get());
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, vbo, GL_STATIC_DRAW);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, GraphicsMain.TEXTURE_REGISTRY.atlasHandle);
glEnableVertexAttribArray(positionAttrIndex);
glEnableVertexAttribArray(texCoordAttrIndex);
glVertexAttribPointer(positionAttrIndex, 3, GL_FLOAT, false, 24, 0);
glVertexAttribPointer(texCoordAttrIndex, 3, GL_FLOAT, false, 24, 12);
glBindVertexArray(0);
vaoHandle.rewind();
return vaoHandle.get();
}
片段着色器:
#version 330 core
uniform sampler2DArray texArray;
varying vec3 texCoord;
void main() {
gl_FragColor = texture(texArray, texCoord);
}
(texCoord
工作正常;它正在从顶点着色器正确传递。)
我是出于想法,所以对现代OpenGL来说还是有点新鲜,我想知道我的代码是否有任何明显的错误。
答案 0 :(得分:1)
一些注意事项:
glTexParameteri
会影响当时GL_TEXTURE_2D_ARRAY
绑定的内容,因此您最好在glBindTexture
glGenTextures()
指定要创建的纹理数量?如果您有可能采用更具体的方法,请使用它GL_UNPACK_ROW_LENGTH
如果大于0,则定义一行中的像素数。我想那时Texture.SIZE
不是真正的纹理大小,而是一侧的尺寸(在你的情况下为128)。无论如何你不需要设置它,你可以跳过它GL_UNPACK_ALIGNMENT
设置为4。大多数时候人们在加载纹理之前将其设置为1以避免任何麻烦,然后在完成后将其设置为4 glTexStorage3D
的最后一个参数预计是层数,我希望textures.size()
更好地返回而不是大小(128x128)glActiveTexture
和glBindTexture
内的prepareVbo
无用,它们不属于vao varying
,不推荐使用,请切换为简单的in out
glGetError()
,渲染输出可能无法明确看到某些无提示错误prepareVbo
,但你确实在其中初始化了vao和vbo