OpenGL中的纹理单位和顶点数组 [英] Texture units and vertex arrays in OpenGL

查看:347
本文介绍了OpenGL中的纹理单位和顶点数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

推荐答案

您正在寻找的是一个多维数据集地图.在OpenGL中,您可以一次定义六个纹理(代表一个立方体的大小边),并使用3D纹理坐标而不是普通的2D纹理坐标进行映射.对于简单的立方体,纹理坐标将与顶点的相应法线相同. (如果仅以这种方式对平面立方体进行纹理化,则也可以在顶点着色器中合并法线和纹理坐标!)与尝试同时绑定六个不同的纹理相比,立方体贴图要简单得多. /p>

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.

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

Now, when doing your shaders, you need the vertex shader to accept and/or pass 3D coordinates (vec3) instead of 2D coordinates (vec2).

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

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

在此示例中,您的顶点着色器将简单地分配vTextureCoordinate = inTextureCoordinate.然后,您的片段着色器需要接受该纹理坐标并对立方体贴图均匀进行采样.

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.

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

哇!好多我有什么遗漏了吗?

Whew! That was a lot. Did I leave anything out?

这篇关于OpenGL中的纹理单位和顶点数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆