同一个对象opengl4csharp上的多个纹理

时间:2016-12-30 21:39:06

标签: c# visual-studio opengl

我有一个带有opengl4csharp库的c#程序,它创建了一个3D立方体,可以用鼠标和键盘在空间中移动。

实际上,我只对一个立方体应用了一个纹理。我的问题是我想为每张脸应用不同的纹理。

我尝试按如下方式启动纹理数组和textureId数组:

 diceTextures = new Texture[6];
        diceTextures[0] = new Texture("top.jpg");
        diceTextures[1] = new Texture("bottom.jpg");
        diceTextures[2] = new Texture("left.jpg");
        diceTextures[3] = new Texture("right.jpg");
        diceTextures[4] = new Texture("front.jpg");
        diceTextures[5] = new Texture("back.jpg");

        diceUint = new uint[diceTextures.Length];

        for (uint ui = 0; ui < diceTextures.Length; ui++)
        {
            diceUint[ui] = diceTextures[ui].TextureID;
        }

然后在OnRenderFrame方法中,将它们绑定到:

        Gl.UseProgram(program);
        Gl.ActiveTexture(TextureUnit.Texture0);
        Gl.BindTextures(0, diceTextures.Length, diceUint);

但是没有任何改变,只有数组的第一个纹理显示在立方体上,就像之前只绑定一个纹理一样。

如何实现纹理应用于面部?

1 个答案:

答案 0 :(得分:1)

  

Gl.BindTextures(0,diceTextures.Length,diceUint);

这将6个纹理绑定到6个单独的纹理单元,0到diceTextures.Length - 1。实际上,如果您要使用glBindTexture s ,则不需要glActiveTexture调用。

在任何情况下,如果您的目标是为每个脸部赋予不同的纹理,则首先必须能够从着色器中识别特定的脸部。这意味着每个面需要被赋予每顶点值,该顶点值与其他面的顶点值分开。这也意味着这些面孔不能与其他面孔共享位置,因为它们的一个属性不是面对面共享的。

因此,您需要一个新的vertex attribute,其中包含您希望该面孔使用的纹理的索引。

从那里,您可以使用array textures。这些是包含图像数组的单个纹理。从数组纹理中采样时,您可以指定(作为纹理坐标的一部分)要从中采样的数组中的哪个索引。

当然,这会改变纹理构建代码,因为必须对纹理类型使用GL_TEXTURE_2D_ARRAY,并为每个mipmap面分配多个数组图层。

总的来说,着色器代码看起来像这样:

#version 330

layout(location = 0) in vec3 position;
layout(location = 2) in vec2 vertTexCoord;
layout(location = 6) in float textureLayer;

out vec2 texCoord;
flat out float layer;

void main()
{
  gl_Position = //your usual stuff.
  texCoord = vertTexCoord;
  layer = textureLayer;
}

片段着色器:

#version 330

in vec2 texCoord;
flat in float layer;

uniform sampler2DArray arrayTexture;

out vec4 outColor;

void main()
{
  outColor = texture(arrayTexture, vec3(texCoord, layer));
}