【发布时间】:2016-03-23 01:14:27
【问题描述】:
我目前正在努力将一个项目从使用纹理图集转换为数组纹理,但对于我来说,我无法让它工作。
关于我的环境的一些说明:
- 我在 GLSL 3.30 版中使用 OpenGL 3.3 核心上下文
- 纹理都是 128x128 并且在使用图集时渲染得非常好(除非边缘伪影说服我切换)
我认为我已经排除的问题:
- 分辨率问题 - 128x128,是 2 的幂,应该没问题
- 纹理加载(和以前一样完美)
- 纹理不完整(mipmap 问题) - 我已经了解了有关 mipmap 的常见问题,但我认为 OpenGL 不应该期待它们
这是我创建数组纹理的代码:
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值。 -
"
texture2DArray" 这不是合法的 GLSL 3.30 函数。用于从纹理数组中采样的函数称为texture,就像用于从各种纹理中采样的函数一样。 -
@ColonelThirtyTwo xy 坐标为 0 或 1,具体取决于正在渲染的顶点。该层存储为
int,并直接从访问器传递到作为VBO 提供的FloatBuffer。 -
@NicolBolas 奇怪,它编译得很好。无论如何,我已将其替换为
texture,我将立即更新 OP 以反映这一点。 -
@caseif:“图层存储为
int并直接从访问器传递给FloatBuffer”是什么意思?确保在其中传递了正确的浮点值。