我使用纹理数组来存储纹理图集。对于支持OpenGL 4.2的硬件,我使用glTexStorage3D
方法,但我也想使用4.2之前的纹理数组。
我检查了其他一些问题,例如this或this。我尝试按照那里提供的解决方案,但纹理数组似乎是空的,在渲染过程中没有纹理可见。
我的glTexStorage3D
解决方案没有任何问题:
glTexStorage3D(GL_TEXTURE_2D_ARRAY,
1,
GL_R8,
2048, 2048,
100);
然而,glTexImage3D
应该是等价的,但不会显示:
glTexImage3D(GL_TEXTURE_2D_ARRAY,
0,
GL_R8,
2048, 2048, 100,
0,
GL_RED,
GL_UNSIGNED_BYTE,
0);
使用以下代码段将纹理数据上传到指定的索引(图集宽度和高度均为2048,深度为1):
glBindTexture(GL_TEXTURE_2D_ARRAY, m_arrayTexture);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
0,
0, 0, m_nextTextureLevel,
atlas->width, atlas->height, atlas->depth,
GL_RED,
GL_UNSIGNED_BYTE,
atlas->data);
我在这里缺少什么?任何帮助都将受到高度赞赏。
修改
不能立即将纹理数据上传到数组,因为在执行期间可以将新纹理添加到数组中。
编辑v2,解决方案
通常问题是我忽略的一些微不足道的问题。我深入研究了Nazar554的解决方案并尝试将其与我的代码进行比较。问题是我不小心使用错误的常量设置了纹理参数,因此glTexParameteri
调用是使用GL_TEXTURE_2D
而不是GL_TEXTURE_2D_ARRAY
进行的。在改变这些价值之后,一切都像魅力一样。
答案 0 :(得分:0)
您可以查看我在项目中使用的Texture.cpp。
但是我没有在后备情况下使用glTexSubImage()
。相反,我立即上传了纹理数据(您传递的是0
以预先分配缓冲区)
您可能感兴趣的功能:Texture::loadTexStorageInternal(const std::string& fileName)
和
bool Texture::loadTexInternal(const std::string& fileName)
以下是其中之一,它在glTexStorage3D
不可用时处理后备。它很长,因为它试图处理压缩格式/ mipmap。
bool Texture::loadTexInternal(const std::string& fileName)
{
gli::texture Texture = gli::load(fileName);
if(Texture.empty())
return 0;
const gli::gl GL(gli::gl::PROFILE_GL33);
const gli::gl::format Format = GL.translate(Texture.format(), Texture.swizzles());
GLenum Target = static_cast<GLenum>(GL.translate(Texture.target()));
Binder texBinder(*this, Target);
glTexParameteri(Target, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(Target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(Texture.levels() - 1));
glTexParameteri(Target, GL_TEXTURE_SWIZZLE_R, Format.Swizzles[0]);
glTexParameteri(Target, GL_TEXTURE_SWIZZLE_G, Format.Swizzles[1]);
glTexParameteri(Target, GL_TEXTURE_SWIZZLE_B, Format.Swizzles[2]);
glTexParameteri(Target, GL_TEXTURE_SWIZZLE_A, Format.Swizzles[3]);
if(Texture.levels() >= 1)
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
//glm::tvec3<GLsizei> const Extent(Texture.extent());
for(std::size_t Layer = 0; Layer < Texture.layers(); ++Layer)
for(std::size_t Level = 0; Level < Texture.levels(); ++Level)
for(std::size_t Face = 0; Face < Texture.faces(); ++Face)
{
GLsizei const LayerGL = static_cast<GLsizei>(Layer);
glm::tvec3<GLsizei> loopExtent(Texture.extent(Level));
Target = gli::is_target_cube(Texture.target())
? static_cast<GLenum>(static_cast<GLint>(GL_TEXTURE_CUBE_MAP_POSITIVE_X) + static_cast<GLint>(Face))
: Target;
switch(Texture.target())
{
case gli::TARGET_1D:
if(gli::is_compressed(Texture.format()))
glCompressedTexImage1D(
Target,
static_cast<GLint>(Level),
static_cast<GLenum>(static_cast<GLenum>(Format.Internal)),
0, loopExtent.x,
static_cast<GLsizei>(Texture.size(Level)),
Texture.data(Layer, Face, Level));
else
glTexImage1D(
Target, static_cast<GLint>(Level),
static_cast<GLenum>(Format.Internal),
loopExtent.x,
0,
static_cast<GLenum>(Format.External), static_cast<GLenum>(Format.Type),
Texture.data(Layer, Face, Level));
break;
case gli::TARGET_1D_ARRAY:
case gli::TARGET_2D:
case gli::TARGET_CUBE:
if(gli::is_compressed(Texture.format()))
glCompressedTexImage2D(
Target, static_cast<GLint>(Level),
static_cast<GLenum>(Format.Internal),
loopExtent.x,
Texture.target() == gli::TARGET_1D_ARRAY ? LayerGL : loopExtent.y,
0,
static_cast<GLsizei>(Texture.size(Level)),
Texture.data(Layer, Face, Level));
else
glTexImage2D(
Target, static_cast<GLint>(Level),
static_cast<GLenum>(Format.Internal),
loopExtent.x,
Texture.target() == gli::TARGET_1D_ARRAY ? LayerGL : loopExtent.y,
0,
static_cast<GLenum>(Format.External), static_cast<GLenum>(Format.Type),
Texture.data(Layer, Face, Level));
break;
case gli::TARGET_2D_ARRAY:
case gli::TARGET_3D:
case gli::TARGET_CUBE_ARRAY:
if(gli::is_compressed(Texture.format()))
glCompressedTexImage3D(
Target, static_cast<GLint>(Level),
static_cast<GLenum>(Format.Internal),
loopExtent.x, loopExtent.y,
Texture.target() == gli::TARGET_3D ? loopExtent.z : LayerGL,
0,
static_cast<GLsizei>(Texture.size(Level)),
Texture.data(Layer, Face, Level));
else
glTexImage3D(
Target, static_cast<GLint>(Level),
static_cast<GLenum>(Format.Internal),
loopExtent.x, loopExtent.y,
Texture.target() == gli::TARGET_3D ? loopExtent.z : LayerGL,
0,
static_cast<GLenum>(Format.External), static_cast<GLenum>(Format.Type),
Texture.data(Layer, Face, Level));
break;
default:
return false;
}
}
return true;
}