繁体   English   中英

OpenGL中的纹理单位和顶点数组

[英]Texture units and vertex arrays in OpenGL

我正在尝试为每个面孔绘制一个具有不同纹理的立方体。 我遇到过许多教程,其中指出在display()例程中,需要在调用glDrawElements()之前启用所有纹理单元。 我打电话给我:

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);

这一切对我来说都是有意义的。 但是,当填充缓冲区时(例如,当加载模型数据时),我将如何确定要引用的纹理。 谢谢克里斯

您正在寻找的是一个立方体贴图 在OpenGL中,您可以一次定义六个纹理(代表一个立方体的大小边),并使用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);

现在,在进行着色器处理时,您需要顶点着色器接受和/或传递3D坐标(vec3)而不是2D坐标(vec2)。

// 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);

呼! 好多 我有遗漏什么吗?

但是,当填充缓冲区时(例如,当加载模型数据时),我将如何确定要引用的纹理。

您所指的是您最近一次用ActiveTexture调用最后指定的纹理-该调用实际上不执行任何操作,它只是设置一个隐藏状态,该状态会影响以后对纹理执行任何操作的所有调用。

在openGL上,通常很难按面选择纹理(除了一些最近的卡片可以索引纹理数组,例如使用EXT_texture_array)。 这样通常可以通过将所有纹理打包在一个纹理中来避免此问题

但是,在您的特定情况下,立方体贴图是完美的-如果您确实确定只有立方体,则别无选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM