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);
这对我来说都是有意义的。然而,当我填充缓冲区时(例如,当我加载模型数据时),我如何确定我所指的纹理。 谢谢 克里斯
I'm trying to draw one cube with different textures for each face. I've come across many tutorials which state that in the display()
routines, you need to enable all texture units before calling glDrawElements()
. I do this my calling:
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);
This all makes sense to me. What doesn't however is how I determine which texture I am referring to when I populate the buffers (e.g. when I load my model data).
Thanks
Chris
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在寻找的是立方体贴图。在 OpenGL 中,您可以一次定义六个纹理(代表立方体的大小边)并使用 3D 纹理坐标而不是常见的 2D 纹理坐标来映射它们。对于简单的立方体,纹理坐标将与顶点各自的法线相同。 (如果您仅以这种方式对平面立方体进行纹理化,则也可以在顶点着色器中合并法线和纹理坐标!)立方体贴图比尝试同时绑定六个不同的纹理要简单得多,就像您现在所做的那样。
现在,在执行着色器时,您需要顶点着色器接受和/或传递 3D 坐标 (vec3),而不是 2D 坐标 (vec2)。
在此示例中,您的顶点着色器将简单地指定 vTextureCooperative = inTextureCooperative。然后,您的片段着色器需要接受该纹理坐标并对立方体贴图统一进行采样。
哇!那是很多。我遗漏了什么吗?
What you are looking for is a cube map. In OpenGL, you can define six textures at once (representing the size sides of a cube) and map them using 3D texture coordinates instead of the common 2D texture coordinates. For a simple cube, the texture coordinates would be the same as the vertices' respective normals. (If you will only be texturing plane cubes in this manner, you can consolidate normals and texture coordinates in your vertex shader, too!) Cube maps are much simpler than trying to bind six distinct textures simultaneously the way you are doing right now.
Now, when doing your shaders, you need the vertex shader to accept and/or pass 3D coordinates (vec3) instead of 2D coordinates (vec2).
In this example, your vertex shader would simply assign vTextureCoordinate = inTextureCoordinate. Your fragment shader then needs to accept that texture coordinate and sample the cube map uniform.
Whew! That was a lot. Did I leave anything out?
您指的是您最后使用最近的 ActiveTexture 调用指定的纹理 - 该调用实际上并不执行任何操作,它只是设置一个隐藏状态,该状态会影响所有对纹理执行任何操作的后续调用。
You are referring to whichever texture you last specified with the most recent ActiveTexture call -- that call doesn't actually do anything, it justs sets a hidden state which affects all subsequent calls that do anything with textures.
在 openGL 上,基于每个面选择纹理通常很困难(除了一些最近可以索引纹理数组的卡,例如使用 EXT_texture_array)。通常可以通过将所有纹理打包在一起来避免此问题,例如这个。
不过,在您的具体情况下,立方体贴图是完美的 - 如果您确实确定只有立方体而没有其他东西。
Selecting a texture on a per-face basis is usually hard on openGL (except for some recent cards that can index an array of textures, for instance with EXT_texture_array). The problem is usually avoided by packing all textures in one, like this.
In your very specific case, though, a cubemap is perfect - if you're really sure you'll just have cubes and nothing else.