资源下载
package com.rex;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by Rex on 2017/3/20.
* 带贴纸的立方体0
*/
public class MyGLRenderer2 implements GLSurfaceView.Renderer {
MainActivity temp2Activity;
public MyGLRenderer2(MainActivity temp2Activity) {
this.temp2Activity = temp2Activity;
createBuffer();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
boolean SEE_THRU = true;
gl.glDisable(GL10.GL_DITHER);
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//在位置(1,1,1)处定义光源
float lightAmbient[] = new float[]{0.3f, 0.3f, 0.3f, 1};
float lightDiffuse[] = new float[]{1, 1, 1, 1};
float lightPos[] = new float[]{1, 1, 1, 1};
gl.glEnable(GL10.GL_LIGHTING);//禁用颜色抖动 消除可能性的性能高消耗
gl.glEnable(GL10.GL_LIGHT0);//设置清除颜色缓冲区时用的RGBA颜色值
//设置环境光
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);
//定义立方体材质
float matAmbient[] = new float[]{1, 1, 1, 1};
float matDiffuse[] = new float[]{1, 1, 1, 1};
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0);
// 设置需要的OpenGL项目
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glClearDepthf(1f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//设置透明效果
if (SEE_THRU) {
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
}
//加载纹理图片
gl.glEnable(GL10.GL_TEXTURE_2D);
loadTextuer(gl);
}
private void loadTextuer(GL10 gl) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeResource(temp2Activity.getResources(), R.mipmap.jixie999);
int[] textures = new int[1];
gl.glGenTextures(1,textures,0);//生成一组纹理并把纹理的ID存入数组参数中
texture = textures[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);//将指定id的纹理绑定到指定的目标中去
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
//将bitmap设置到纹理目录中
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bitmap,0);
} catch (Exception e) {
}
finally {
if (bitmap != null) {
bitmap.recycle();
}
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//设置视口
gl.glViewport(0, 0, width, height);
//设置当前矩阵堆栈为投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
//宽高比
float aspect = (float) width / (float) (height == 0 ? 1 : height);
GLU.gluPerspective(gl, 45.0f, aspect, 0.1f, 200.0f);
GLU.gluLookAt(gl, -20, -20f, 20f, 0f, 0f, 0f, 0, 0, 1);
}
@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();
gl.glTranslatef(0, 0, -3.0f);
//将旋转矩阵应用到当前矩阵堆栈上,即旋转模型
gl.glRotatef(anglez, 0, 0, 1);
gl.glRotatef(angley, 0, 1, 0);
gl.glRotatef(anglex, 1, 0, 0);
anglex += 0.1;//递增角度值以便每次以不同角度绘制
angley += 0.2;
anglez += 0.3;
//启用顶点数组,法向量,颜色数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//设置正面
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tvertices);
//绑定纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
//绘制triangles标识的三角形
gl.glDrawElements(GL10.GL_TRIANGLES, triangles.remaining(), GL10.GL_UNSIGNED_BYTE, triangles);
//禁用顶点,法向量,纹理坐标数组
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
private int texture;
private FloatBuffer vertices;
private ByteBuffer triangles;
private FloatBuffer tvertices;
private float anglex = 0f;
private float angley = 0f;
private float anglez = 0f;
private float[] data_vertices = {
-5.0f, -5.0f, -5.0f, -5.0f,//1
5.0f, -5.0f, 5.0f, 5.0f,
-5.0f, 5.0f, 5.0f, -5.0f,
5.0f, -5.0f, -5.0f, -5.0f,
-5.0f, -5.0f,
-5.0f, -5.0f, 5.0f, 5.0f,//2
-5.0f, 5.0f, 5.0f, 5.0f,
5.0f, 5.0f, 5.0f, 5.0f,
-5.0f, 5.0f, 5.0f, -5.0f,
-5.0f, 5.0f,
-5.0f, -5.0f, -5.0f, 5.0f,//3
-5.0f, -5.0f, 5.0f, -5.0f,
5.0f, 5.0f, -5.0f, 5.0f,
-5.0f, -5.0f, 5.0f, -5.0f,
-5.0f, -5.0f,
5.0f, -5.0f, -5.0f, 5.0f,//4
5.0f, -5.0f, 5.0f, 5.0f,
5.0f, 5.0f, 5.0f, 5.0f,
5.0f, -5.0f, 5.0f, 5.0f,
-5.0f, -5.0f,
5.0f, 5.0f, -5.0f, -5.0f,//5
5.0f, -5.0f, -5.0f, 5.0f,
5.0f, -5.0f, 5.0f, 5.0f,
5.0f, 5.0f, 5.0f, 5.0f,
5.0f, -5.0f,
-5.0f, 5.0f, -5.0f, -5.0f,
-5.0f, -5.0f, -5.0f, -5.0f,
5.0f, -5.0f, -5.0f, 5.0f,
-5.0f, 5.0f, 5.0f, -5.0f,//6
5.0f, -5.0f,
};
private byte[] data_triangles = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
};
//设置纹理坐标
private float[] data_tvertices = {
1.000f, 1.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f, 1.000f, 1.000f,
0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,
0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,
0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,
0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,
0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,
};
private void createBuffer() {
vertices = new BufferUtil().fBuffer(data_vertices);
//创建三角形顶点索引缓冲,索引使用byte数组,所以无须设置字节顺序,也无须写入适配
triangles = ByteBuffer.allocate(data_triangles.length * 2);
triangles.put(data_triangles);
triangles.position(0);
tvertices = new BufferUtil().fBuffer(data_tvertices);
}
public class BufferUtil {
public FloatBuffer floatBuffer;
public 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;
// //创建顶点缓冲,顶点数组使用float类型,每个float4个字节
// vertices = ByteBuffer.allocateDirect(data_vertices.length * 4);
// //设置字节顺序为本机顺序
// vertices.order(ByteOrder.nativeOrder());
// //通过一个FloatBuffer适配器,将float数组写入ByteBuffer中
// vertices.asFloatBuffer().put(data_vertices);
// //重置当前buffer位置
// vertices.position(0);
}
}
}