纹理数组访问无法使用Opengl 3.3,GLSL 330
我正在尝试使用2D纹理阵列作为纹理图集。我有下面的代码来渲染一个正方形。如果我使用简单的颜色输出替换片段着色器中的纹理查找,则方形会渲染,如果我使用并设置简单的2D纹理而不是2D纹理数组,则它会正确渲染其中一个纹理。然而,当尝试创建和使用2d纹理阵列时,我只得到一个黑屏。有什么好处纹理数组访问无法使用Opengl 3.3,GLSL 330,opengl,glsl,opengl-3,Opengl,Glsl,Opengl 3,我正在尝试使用2D纹理阵列作为纹理图集。我有下面的代码来渲染一个正方形。如果我使用简单的颜色输出替换片段着色器中的纹理查找,则方形会渲染,如果我使用并设置简单的2D纹理而不是2D纹理数组,则它会正确渲染其中一个纹理。然而,当尝试创建和使用2d纹理阵列时,我只得到一个黑屏。有什么好处 //Shader Sources const GLchar* vertexsource = "#version 330\n" "in vec2 position;" "in vec2 texc
//Shader Sources
const GLchar* vertexsource =
"#version 330\n"
"in vec2 position;"
"in vec2 texcoord;"
"out vec2 f_texcoord;"
"void main() {"
" gl_Position = vec4(position, 0.0, 1.0);"
" f_texcoord = texcoord;"
"}";
const GLchar* fragmentsource =
"#version 330\n"
"in vec2 f_texcoord;"
"out vec4 color;"
"uniform float time;"
"uniform sampler2DArray sample;"
"void main() {"
" float layer = step(sin(time), 0.0);"
" color = texture(sample, vec3(f_texcoord, 0.0));\n"
" //color = vec4(1.0,1.0,1.0,1.0);\n"
"}";
//Vertex Data
GLfloat vertices[] = {
//Verts Texture verts
-0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 1.0f
};
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
Shaders::SetLogger(log_);
VertexShader vertexshader("D3 Vertex Shader", vertexsource);
FragmentShader fragshader("D3 Frag Shader", fragmentsource);
program = new ShaderProgram("D3 Shader Program");
program->AttachShader(vertexshader);
program->AttachShader(fragshader);
program->LinkProgram();
glUseProgram(program->glIdentifier());
GLint posattrib = program->GetAttributeLocation("position");
GLint texattrib = program->GetAttributeLocation("texcoord");
//Dont actually need this because only one Texture unit in use
GLint coloruniform = program->GetUniformLocation("sample");
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
glEnableVertexAttribArray(posattrib);
glVertexAttribPointer(posattrib, 2, GL_FLOAT, GL_FALSE,
4 * sizeof(GLfloat),
(GLvoid*)0);
glEnableVertexAttribArray(texattrib);
glVertexAttribPointer(texattrib, 2, GL_FLOAT, GL_FALSE,
4 * sizeof(GLfloat),
(GLvoid*)(2 * sizeof(GLfloat)));
//glUniform1i(coloruniform, 0);
int width, height;
unsigned char* image = SOIL_load_image("sample.png", &width, &height,
0, SOIL_LOAD_RGBA);
int width2, height2;
unsigned char* image2 = SOIL_load_image("sample2.png", &width2, &height2,
0, SOIL_LOAD_RGBA);
errorstream << glGetError() << " ";
glActiveTexture(GL_TEXTURE0);
GLuint texture;
glGenTextures(1, &texture);
errorstream << glGetError() << " ";
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
errorstream << glGetError() << " ";
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA,
width, height, 2,
0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)0);
errorstream << glGetError() << " ";
log_->Debug("Requested memory for texture");
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0,
0, 0, 0,
width, height, 1,
GL_RGBA, GL_UNSIGNED_BYTE, image);
errorstream << glGetError() << " ";
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0,
0, 0, 1,
width2, height2, 1,
GL_RGBA, GL_UNSIGNED_BYTE, image2);
errorstream << glGetError() << " ";
glUniform1i(coloruniform, 0);
errorstream << glGetError() << " ";
log_->Debug(errorstream.str());
编辑:在jozxyqk建议的更改中编辑可能的原因:
- 纹理/采样器未正确绑定(请参见下文)
- 纹理为(另请参见)
常见的问题是默认情况下需要mipmap(大多数教程/示例代码开始时没有mipmap)。一个简单的修复方法是:
glTexParameteri(GL\u纹理\u 2D\u数组、GL\u纹理\u最小\u过滤器、GL\u线性)代码> 有关详细信息,请参阅 如果所有的纹理图像和纹理参数 一致定义了使用纹理应用所需的纹理 使用上述定义,纹理是完整的,除非以下条件之一成立:
- 缩小过滤器需要mipmap(既不是最近的也不是线性的),并且纹理不是mipmap完整的
- 纹理坐标错误(例如,所有零和第一个纹理恰好为黑色)。可通过使用像素颜色坐标轻松验证
- 以上操作正常,图像中的数据仅为黑色
- 调用
,使用glActiveTexture
这在设置过程中不需要,但会在绘制之前选择要绑定到的纹理单元GL\u TEXTURE0+texIndex
- 调用
这应该在glBindTexture
()glActiveTexture
- 设置采样器统一
← 我认为主要的问题是glUniform1i(采样器位置,texIndex)
是texIndex
的GL\u TEXTURE0
,0
的GL\u TEXTURE1
等。使用1
是一种便捷的快捷方式 您的代码使用GL\u TEXTURE0+texIndex
而不是索引,即GL_TEXTURE0
或0x84C0
33984
glActiveTexture
之后也应该有一个绑定调用,但从设置代码开始,该状态应该保持活动状态。现在可以尝试一些调试方法:color=vec4(f_texcoord,0,1)代码>要检查坐标是否正常,请将所有255写入图像
以检查加载是否正常。哦,还要确保(实际上,先做这个)。GL_纹理_MIN_过滤器修复成功了,你是一个救生员。编辑:你能链接任何资源来解释为什么这会修复它吗?
GLint timeuniform = program->GetUniformLocation("time");
GLint sampleuniform = program->GetUniformLocation("sample");
glActiveTexture(GL_TEXTURE0);
glUniform1f(timeuniform, frametimer_.RunningTime().asSeconds());
glUniform1i(sampleuniform, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
window_->display();