学了一些天的OpenGl ES ,觉得网上多纹理的资料太少了,特来做下贡献,先上效果图
参考代码:
package com.myopengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
public class MyRenderer implements Renderer{
private int[] texture = new int[6];
private Context mcontext;
private int one = 0x10000;
public MyRenderer(Context context){
mcontext = context;
}
float[] rectData =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,
};
int []rectColor=new int[]{
0,65535,0,0,
0,0,65535,0,
65535,0,0,0,
65535,65535,0,0
};
private int[] texCoords = {one,0,0,0,0,one,one,one,
0,0,0,one,one,one,one,0,
one,one,one,0,0,0,0,one,
0,one,one,one,one,0,0,0,
0,0,0,one,one,one,one,0,
one,0,0,0,0,one,one,one,
};
ByteBuffer indices1 = ByteBuffer.wrap(new byte[]{
0,1,3,2,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices2 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
4,5,7,6,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices3 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
8,9,11,10,
0,0,0,0,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices4 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
0,0,0,0,
12,13,15,14,
0,0,0,0,
0,0,0,0,
});
ByteBuffer indices5 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
16,17,19,18,
0,0,0,0,
});
ByteBuffer indices6 = ByteBuffer.wrap(new byte[]{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
20,21,23,22,
});
private FloatBuffer rectDataBuffer = BufferUtil.fBuffer(rectData);
private IntBuffer rectColorBuffer = BufferUtil.iBuffer(rectColor);
//纹理映射数据
private IntBuffer texCoordsBuffer = BufferUtil.iBuffer(texCoords);
private float rotateX; //用于正方体x轴的旋转;
private float rotateY; //用于正方体y轴的旋转;
private float rotateZ; //用于正方体z轴的旋转;
//光线参数
FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,1.0f});
FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f,1.0f,1.0f,1.0f});
FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f,0.0f,2.0f,1.0f});
//当窗口被创建时我们可以做些初始化工作
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
//设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值
gl.glClearColor(0, 0, 0, 0);
//启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);//启用深度测试
//以下是关于深度缓存的设置,非常重要
gl.glClearDepthf(1.0f);//设置深度缓存
gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度测试的类型
//告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
//允许2D贴图
gl.glEnable(GL10.GL_TEXTURE_2D);
//设置光线,,1.0f为全光线,a=50%
gl.glColor4f(1.0f,1.0f,1.0f,0.5f);
// 基于源象素alpha通道值的半透明混合函数
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);
IntBuffer intBuffer = IntBuffer.allocate(6);
//创建纹理
gl.glGenTextures(6, intBuffer);
texture[0] = intBuffer.get();
texture[1] = intBuffer.get();
//设置需要使用的纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
Bitmap bmp = BitmapFactory.decodeResource(mcontext.getResources(),
R.drawable.qiuyan);
//生成纹理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
// 线形滤波
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
Bitmap bmp1 = BitmapFactory.decodeResource(mcontext.getResources(),
R.drawable.yangmi);
//生成纹理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp1, 0);
// 线形滤波
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
Bitmap bmp3 = BitmapFactory.decodeResource(mcontext.getResources(),
R.drawable.qiuyan2);
//生成纹理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp3, 0);
// 线形滤波
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
//设置环境光
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);
//设置漫射光
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);
//设置光源位置
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);
//开启一号光源
gl.glEnable(GL10.GL_LIGHT1);
//开启混合
gl.glEnable(GL10.GL_BLEND);
}
//当窗口改变时,调用,至少在创建窗口时调用一次,这边设置下场景大小
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
//设置OpenGL场景大小
float ratio = (float) width / height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);//设置为投影矩阵模式
gl.glLoadIdentity();//重置
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//设置视角
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
//咳,咳现在开始画图了
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
//清楚屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//启用顶点坐标数据
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//设置当前矩阵堆栈为模型堆栈
gl.glMatrixMode(GL10.GL_MODELVIEW);
//重置当前的观察模型矩阵
gl.glLoadIdentity();
//矩阵移动
gl.glTranslatef(0.0f, 0.0f, -1.8f);
//矩阵旋转
gl.glRotatef(rotateX, 1.0f, 0.0f, 0.0f);
gl.glRotatef(rotateY, 0.0f, 1.0f, 0.0f);
gl.glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//纹理的使用与开启颜色渲染一样,需要开启纹理功能
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,rectDataBuffer );
//
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoordsBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE, indices1);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 8, GL10.GL_UNSIGNED_BYTE, indices2);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 12, GL10.GL_UNSIGNED_BYTE, indices3);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 16, GL10.GL_UNSIGNED_BYTE, indices4);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 20, GL10.GL_UNSIGNED_BYTE, indices5);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_BYTE, indices6);
//
gl.glFinish();
//
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
rotateX += 0.5f;
rotateY += 0.3f;
rotateZ += 0.6f;
}
public static class BufferUtil {
public static IntBuffer intBuffer;
public static FloatBuffer floatBuffer;
public static IntBuffer iBuffer(int[] a) {
// 先初始化buffer,数组的长度*4,因为一个float占4个字节
ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
// 数组排列用nativeOrder
mbb.order(ByteOrder.nativeOrder());
intBuffer = mbb.asIntBuffer();
intBuffer.put(a);
intBuffer.position(0);
return intBuffer;
}
public static FloatBuffer fBuffer(float[] a) {
// 先初始化buffer,数组的长度*4,因为一个float占4个字节
ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
// 数组排列用nativeOrder
mbb.order(ByteOrder.nativeOrder());
floatBuffer = mbb.asFloatBuffer();
floatBuffer.put(a);
floatBuffer.position(0);
return floatBuffer;
}
}
}
package com.myopengl;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
MyRenderer myrender;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView glView = new GLSurfaceView(this);
myrender=new MyRenderer(this);
glView.setRenderer(myrender);
setContentView(glView);
}
}