//设置光线,,1.0f为全光线,a=50%
gl.glColor4f(1.0f,1.0f,1.0f,0.5f);
// 基于源象素alpha通道值的半透明混合函数
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);
只需增加上述方法即可开启,现在我们通过点触事件来控制其开启:
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_DOWN){
key = !key;
}
return super.onTouchEvent(event);
}
完整代码如下:
package org.ourunix.android.opengltest;
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.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class OpenGLTestActivity extends Activity {
private boolean key = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView glView = new GLSurfaceView(this);
glView.setRenderer(new GLRender());
setContentView(glView);
}
public class GLRender implements Renderer{
private int texture = -1;
private int one = 0x10000;
private int[] quarter = {-one,-one,one,
one,-one,one,
one,one,one,
-one,one,one,
-one,-one,-one,
-one,one,-one,
one,one,-one,
one,-one,-one,
-one,one,-one,
-one,one,one,
one,one,one,
one,one,-one,
-one,-one,-one,
one,-one,-one,
one,-one,one,
-one,-one,one,
one,-one,-one,
one,one,-one,
one,one,one,
one,-one,one,
-one,-one,-one,
-one,-one,one,
-one,one,one,
-one,one,-one,};
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,};
//准备正方体顶点
private IntBuffer quarterBuffer = BufferUtil.iBuffer(quarter);
//纹理映射数据
private IntBuffer texCoordsBuffer = BufferUtil.iBuffer(texCoords);
ByteBuffer indicesBuffer = ByteBuffer.wrap(new byte[]{
0,1,3,2,
4,5,7,6,
8,9,11,10,
12,13,15,14,
16,17,19,18,
20,21,23,22,
});
private float rotateX; //用于正方体x轴的旋转;
private float rotateY; //用于正方体y轴的旋转;
private float rotateZ; //用于正方体z轴的旋转;
//定义环境光
private FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f, 0.5f, 0.5f, 1.0f });
//定义漫射光
private FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f, 1.0f, 1.0f, 1.0f });
//定义光源的位置
private FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f, 0.0f, 2.0f, 1.0f });
//咳,咳现在开始画图了
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
//清楚屏幕和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//重置当前的观察模型矩阵
gl.glLoadIdentity();
//开启光源
gl.glEnable(GL10.GL_LIGHTING);
//现将屏幕向里移动,用来画正方体
gl.glTranslatef(0.0f, 0.0f, -6.0f);
//设置3个方向的旋转
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);
//通知opnegl将文理名字texture绑定到指定的纹理目标上GL10.GL_TEXTURE_2D
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//纹理的使用与开启颜色渲染一样,需要开启纹理功能
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//设置正方体 各顶点
gl.glVertexPointer(3, GL10.GL_FIXED, 0, quarterBuffer);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoordsBuffer);
//绘制
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_BYTE, indicesBuffer);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
rotateX += 0.5f;
rotateY += 0.6f;
rotateZ += 0.3f;
//混合开关
if (key)
{
gl.glEnable(GL10.GL_BLEND); // 打开混合
gl.glDisable(GL10.GL_DEPTH_TEST); // 关闭深度测试
}
else
{
gl.glDisable(GL10.GL_BLEND); // 关闭混合
gl.glEnable(GL10.GL_DEPTH_TEST); // 打开深度测试
}
}
//当窗口改变时,调用,至少在创建窗口时调用一次,这边设置下场景大小
@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 onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
//设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值
gl.glClearColor(0, 0, 0, 0);
gl.glEnable(GL10.GL_CULL_FACE);
//启用阴影平滑
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);
IntBuffer intBuffer = IntBuffer.allocate(1);
//创建纹理
gl.glGenTextures(1, intBuffer);
texture = intBuffer.get();
//设置需要使用的纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test);
//生成纹理
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);
//设置光线,,1.0f为全光线,a=50%
gl.glColor4f(1.0f,1.0f,1.0f,0.5f);
// 基于源象素alpha通道值的半透明混合函数
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);
//设置环境光
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);
//开启ID号为GL_LIGHT1的光源
gl.glEnable(GL10.GL_LIGHT1);
}
}
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;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_DOWN){
key = !key;
}
return super.onTouchEvent(event);
}
}