将纹理图集用作OpenGL中的纹理阵列

问题描述 投票:1回答:1

我正在构建Voxel游戏。在开始时,我使用了一个纹理图集来存储所有体素纹理,并且效果很好。之后,我决定在游戏中使用贪婪网格划分,因此纹理地图集不再有用。我读过一些文章说应该使用Texture Array代替。然后,我尝试阅读并使用纹理阵列技术进行纹理处理。但是,我得到的结果是我的游戏全黑。那我想念什么?

这是我的纹理图集(600 x 600)

my texture atlas

这是我的Texture2DArray,我使用此类读取和保存纹理数组

Texture2DArray::Texture2DArray() : Internal_Format(GL_RGBA8), Image_Format(GL_RGBA), Wrap_S(GL_REPEAT), Wrap_T(GL_REPEAT), Wrap_R(GL_REPEAT), Filter_Min(GL_NEAREST), Filter_Max(GL_NEAREST), Width(0), Height(0)
{
   glGenTextures(1, &this->ID);
}

void Texture2DArray::Generate(GLuint width, GLuint height, unsigned char* data)
{
   this->Width = width;
   this->Height = height;

   glBindTexture(GL_TEXTURE_2D_ARRAY, this->ID);

   // I cannot decide what the texture array layer (depth) should be (I put here is 1 for layer number)
   //Can anyone explain to me how to decide the texture layer here? 
   glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, this->Internal_Format, this->Width, this->Height, 0, 1 , this->Image_Format, GL_UNSIGNED_BYTE, data);

   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, this->Wrap_S);
   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, this->Wrap_T);
   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, this->Wrap_R);

   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, this->Filter_Min);
   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, this->Filter_Max);

   //unbind this texture for another creating texture
   glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
}

void Texture2DArray::Bind() const
{
   glBindTexture(GL_TEXTURE_2D_ARRAY, this->ID);
}

这是我的片段着色器

#version 330 core

uniform sampler2DArray ourTexture;

in vec2 texCoord;

out vec4 FragColor;

void main(){
   // 1 (the layer number) just for testing
   FragColor = texture(ourTexture,vec3(texCoord, 1));
}

这是我的顶点着色器

#version 330 core

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inTexCoord;

out vec2 texCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main(){
    gl_Position =  projection * view * vec4(inPos,1.0f);
    texCoord = inTexCoord;
}  

这是我的渲染结果

rendering result

编辑1:

我发现纹理图集不适用于纹理数组,因为它是一个网格,因此OpenGl无法确定应该从哪里开始。因此,我创建了一个垂直纹理(18 x 72),然后重试,但到处仍然都是黑色。

my verticle texture atlas

我在使用纹理之前已经检查了它的绑定。

c++ opengl texture-mapping opengl-3 voxel
1个回答
0
投票

当指定3D纹理图像时,深度必须是必须存储在数组中的图像数量(例如imageCount)。图层应为0,border参数必须为0。请参见glTexImage3DglTexImage3D为纹理图像创建数据存储。保留了纹理所需的内存(GPU)。可以将指针传递到图像数据,但这不是必需的。

glTexImage3D

之后,您可以使用glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, this->Internal_Format, this->Width, this->Height, imageCount, 0, this->Image_Format, GL_UNSIGNED_BYTE, nullptr); 将纹理数据放入纹理对象的数据存储中。 glTexSubImage3D使用现有的数据存储并复制数据。例如:

glTexSubImage3D
© www.soinside.com 2019 - 2024. All rights reserved.