功能启动
为使用纹理,我们需要打开OpenGL的一些开关以启动我们需要的一些功能:
gl.glEnable(GL10.GL_TEXTURE_2D);
。这个调用是必不可缺的;如果你没有打开此功能,那么你就无法将图像映射到多边形上。它可以在需要时打开和关闭,通常在初始化时打开。
创建纹理
生成纹理
OpenGL 中的纹理通过一个唯一号引用,通过函数 glBindTexture() 实现。你 可以自己指定这个唯一号,或者通过调用 glGenTextures () 函数生成一个唯一 号。
int[] tmp_tex = new int[1];//尽管只有一个纹理,但使用一个元素的数组//glGenTextures(申请个数,存放数组,偏移值)gl.glGenTextures(1, tmp_tex, 0); //向系统申请可用的,用于标示纹理的ID int texture = tmp_tex[0];纹理绑定
在为纹理生成名称后,在为纹理提供图像数据之前,我们必须绑定纹理。绑定使得指定纹理处于活动状态。一次只能激活一个纹理。活动的或“被绑定”的纹理是绘制多边形时使用的纹理,也是新纹理数据将加载其上纹理,所以在提供图像数据前必须绑定纹理。
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
绑定纹理数据,传入指定图片
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
纹理限制
用于纹理的图像宽和高必须为乘方,比如 2, 4, 8, 16, 32, 64, 128, 256, 512, 或 1024。例如图像可能为 64×128 或 512×512。
纹理坐标
当纹理映射启动后绘图时,你必须为OpenGL ES提供其他数据,即顶点数组中各顶点的 纹理坐标。纹理坐标定义了图像的哪一部分将被映射到多边形。它的工作方式有点奇怪。与我们顶点坐标方向不一致,假设你有一个正方形或长方形的纹理,其左下角为二维平面的原点,高和宽的单位为一。像这样:
这就是我们的“纹理坐标系统”,不使用x 和 y 来代表二维空间,我们使用 s 和 t 作为纹理坐标轴,但原理上是一样的。
除了 s 和 t 轴外,被映射的纹理在多边形同样有两个轴,它们称为 u 和 v轴。这是源于许多3D图像程序中的UV 映射 的术语。
好,我们明白了纹理坐标系统,我们现在讨论怎样使用这些纹理坐标。当我们指定顶点数组中的顶点时,我们需要在另一个数组中提供纹理坐标,它称为纹理坐标数组。 每个顶点,我们使用float 来指定顶点在上图所示坐标系统的位置。让我们看看一个可能是最为简单的例子,将整个图像映射到一个由三角形条组成的正方形上。首先,我们创建一个由四个顶点组成的顶点数组:
现在将两个框图叠在一起,所使用的坐标数组的值变得很明显:
将其转化为坐标数组:
float texCoords[] = new float[]{ 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
纹理坐标对应纹理在物体上的图片位置和方向。
我们还需要传递纹理坐标给系统
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuff); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //开启纹理坐标数组
我们今天实例的效果:
代码:
- public class CubeRenderer implements Renderer {
-
- Bitmap bmp;
- float box[] = new float[] {
-
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
-
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
-
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
-
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- -0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- };
-
- float lightAmbient[] = new float[] { 0.5f, 0.5f, 0.6f, 1.0f };
- float lightDiffuse[] = new float[] { 0.6f, 0.6f, 0.6f, 1.0f };
- float[] lightPos = new float[] {0,0,3,1};
-
-
-
- float norms[] = new float[] {
-
- 0f, 0f, 1f,
- 0f, 0f, 1f,
- 0f, 0f, 1f,
- 0f, 0f, 1f,
-
- 0f, 0f, -1f,
- 0f, 0f, -1f,
- 0f, 0f, -1f,
- 0f, 0f, -1f,
-
- -1f, 0f, 0f,
- -1f, 0f, 0f,
- -1f, 0f, 0f,
- -1f, 0f, 0f,
-
- 1f, 0f, 0f,
- 1f, 0f, 0f,
- 1f, 0f, 0f,
- 1f, 0f, 0f,
-
- 0f, 1f, 0f,
- 0f, 1f, 0f,
- 0f, 1f, 0f,
- 0f, 1f, 0f,
-
- 0f, -1f, 0f,
- 0f, -1f, 0f,
- 0f, -1f, 0f,
- 0f, -1f, 0f
- };
-
-
- float texCoords[] = new float[] {
-
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 1.0f,
-
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 0.0f, 1.0f,
-
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 0.0f, 1.0f,
-
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 0.0f, 1.0f,
-
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 1.0f,
-
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 0.0f, 1.0f
- };
-
-
- FloatBuffer cubeBuff;
- FloatBuffer normBuff;
- FloatBuffer texBuff;
-
- float xrot = 0.0f;
- float yrot = 0.0f;
-
-
-
-
-
-
- public FloatBuffer makeFloatBuffer(float[] arr) {
- ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
- bb.order(ByteOrder.nativeOrder());
- FloatBuffer fb = bb.asFloatBuffer();
- fb.put(arr);
- fb.position(0);
- return fb;
- }
-
- public CubeRenderer(Context c) {
-
- cubeBuff = makeFloatBuffer(box);
- normBuff = makeFloatBuffer(norms);
- texBuff = makeFloatBuffer(texCoords);
- bmp = BitmapFactory.decodeResource(c.getResources(), R.drawable.face);
- }
-
-
- protected void init(GL10 gl) {
- gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-
- gl.glEnable(GL10.GL_LIGHTING);
- gl.glEnable(GL10.GL_LIGHT0);
-
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
-
- gl.glNormalPointer(GL10.GL_FLOAT, 0, normBuff);
- gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
-
-
-
- gl.glEnable(GL10.GL_TEXTURE_2D);
-
-
- int[] tmp_tex = new int[1];
-
- gl.glGenTextures(1, tmp_tex, 0);
- int texture = tmp_tex[0];
-
-
- gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
-
-
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
-
-
- gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuff);
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-
-
-
-
-
-
-
-
-
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
-
-
- gl.glEnable(GL10.GL_DEPTH_TEST);
- gl.glEnable(GL10.GL_CULL_FACE);
- gl.glClearDepthf(1.0f);
- gl.glDepthFunc(GL10.GL_LEQUAL);
- gl.glShadeModel(GL10.GL_SMOOTH);
- }
-
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-
- init(gl);
- }
-
- @Override
- public void onSurfaceChanged(GL10 gl, int w, int h) {
-
- gl.glViewport(0, 0, w, h);
- gl.glMatrixMode(GL10.GL_PROJECTION);
- gl.glLoadIdentity();
- GLU.gluPerspective(gl, 45.0f, ((float) w) / h, 0.1f, 10f);
- }
-
- @Override
- public void onDrawFrame(GL10 gl) {
-
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glLoadIdentity();
- GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);
-
- gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff);
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-
- gl.glRotatef(xrot, 1, 0, 0);
- gl.glRotatef(yrot, 0, 1, 0);
-
- gl.glColor4f(1.0f, 0, 0, 1.0f);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
-
- gl.glColor4f(0, 1.0f, 0, 1.0f);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
-
- gl.glColor4f(0, 0, 1.0f, 1.0f);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
-
- xrot += 0.5f;
- yrot += 0.5f;
- }
-
- }
阅读(1930) | 评论(1) | 转发(2) |