2011-02-07 36 views
1

我试图为每个面绘制一个具有不同纹理的立方体。我遇到过很多教程,其中指出在display()例程中,您需要在调用glDrawElements()之前启用所有纹理单元。我这样做我的电话:OpenGL中的纹理单元和顶点数组

gl.glClientActiveTexture(GL.GL_TEXTURE0); 
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); 

gl.glClientActiveTexture(GL.GL_TEXTURE1); 
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId+1); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); 

... 

gl.glClientActiveTexture(GL.GL_TEXTURE5); 
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId+5); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject()); 
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); 

这一切都对我有意义。然而,我不知道当我填充缓冲区时(例如,当我加载模型数据时),我如何确定我所指的纹理。 感谢 克里斯

回答

2

你在找什么是cube map。在OpenGL中,您可以一次定义6个纹理(代表立方体的大小),并使用3D纹理坐标而不是通用的2D纹理坐标来映射它们。对于简单的立方体,纹理坐标将与顶点各自的法线相同。 (如果您只是以这种方式对平面立方体进行纹理化处理,则还可以在顶点着色器中合并法线和纹理坐标!)立方体贴图比尝试将六种不同纹理同时绑定到现在的方式要简单得多。

GLuint mHandle; 
glGenTextures(1, &mHandle); // create your texture normally 

// Note the target being used instead of GL_TEXTURE_2D! 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle); 

// Now, load in your six distinct images. They need to be the same dimensions! 
// Notice the targets being specified: the six sides of the cube map. 
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data1); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data2); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data3); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data4); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data5); 
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0, 
    format, GL_UNSIGNED_BYTE, data6); 

glGenerateMipmap(GL_TEXTURE_CUBE_MAP); 
glTextParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 

// And of course, after you are all done using the textures... 
glDeleteTextures(1, &mHandle); 

现在,做你的着色器时,你需要的顶点着色器接受和/或通过三维坐标(VEC 3),而不是二维坐标(VEC 2)。

// old GLSL style 
attribute vec3 inTextureCoordinate; 
varying vec3 vTextureCoordinate; 

// more recent GLSL 
in vec3 inTextureCoordinate; 
out vec3 vTextureCoordinate; 

在这个例子中,你的顶点着色器将只分配vTextureCoordinate = inTextureCoordinate。你的片段着色器需要接受纹理坐标并对立方体贴图进行采样。

uniform samplerCube cubeMap; 
... 
gl_FragColor = textureCube(cubeMap, vTextureCoordinate); 

哎!这很多。我有没有留下什么?

+0

我想知道更多。 – Mark 2011-02-07 18:20:36

1

什么不不过是我如何确定我指的是,当我填充缓冲其质地(例如,当我打开我的模型数据)。

你指的是哪个质感上次与最近ActiveTexture调用指定 - 该呼叫实际上并没有做任何事情,它甫一设置影响所有后续调用是做什么的纹理隐藏状态。

0

基于per-face的纹理选择通常很难在openGL上进行(除了一些最近可以对纹理数组进行索引的卡片,例如使用EXT_texture_array)。这个问题通常可以通过将所有纹理打包在一个文件中来避免,如this

然而,在您的具体情况下,立方体贴图是完美的 - 如果您确信您只有立方体而没有别的东西。