一、基础知识:


1..光照介绍:

环境光:
来自四面八方,所有场景中的对象都处于环境光的照射中。

漫射光:
由特定的光源产生,并在场景中的对象表面产生反射。
处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显示得要暗一些。

2.光照使用:
①设定光源参数:

//环境光
private float[] lightAmbient;
private FloatBuffer AmbientBuffer;
//漫射光
private float[] lightDiffuse;
private FloatBuffer diffuseBuffer;
//光源位置
private float[] lightPosition;
private FloatBuffer positionBuffer;

//灯光
lightAmbient = new float[]{0.5f,0.5f,0.5f,1.0f};
lightDiffuse = new float[]{1.0f,1.0f,1.0f,1.0f};
lightPosition = new float[]{0.0f,0.0f,2.0f,1.0f};

//环境光
ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4 * 6);
ambientbb.order(ByteOrder.nativeOrder());
AmbientBuffer = ambientbb.asFloatBuffer();
AmbientBuffer.put(lightAmbient);
AmbientBuffer.position(0);

//漫射光
ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4 * 6);
diffusebb.order(ByteOrder.nativeOrder());
diffuseBuffer = diffusebb.asFloatBuffer();
diffuseBuffer.put(lightDiffuse);
diffuseBuffer.position(0);

//灯光位置
ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4 * 6);
positionbb.order(ByteOrder.nativeOrder());
positionBuffer = positionbb.asFloatBuffer();
positionBuffer.put(lightPosition);
positionBuffer.position(0);

②设置光源:
glLightfv (
int light,// 光源的ID
int pname, // 光源的类型
FloatBuffer params// 光源的数组
)
设定的属性,主要由第二个参数决定:
GL_AMBIENT环境光(光源泛光强度的RGBA值)
GL_DIFFUSE漫射光(光源漫反射强度的RGBA值)
GL_SPECULAR高光(光源镜面反射强度的RGBA值)
GL_POSITION位置(光源的位置)
GL_SPOT_DIRECTION方向(聚光灯的方向)
GL_SPOT_CUTOFF光的角度(聚光灯的截止角度)

// 设置环境光
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, AmbientBuffer);
// 设置漫射光
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer);
// 设置灯光位置
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer);

③启用光源:
//启用一号光源
gl.glEnable(GL10.GL_LIGHT1);

二、实现:

1. 界面编辑:
res\layout\main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    ><TextView      android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:text="@string/hello"    /><Button    android:id="@+id/button1"    android:layout_width="145dp"    android:layout_height="wrap_content"    android:text="演示开始" /></LinearLayout>


2.代码编辑:
\src\com\yarin\android\Examples\Activity01.java

package com.yarin.android.Examples_12_05;import java.io.IOException;import java.io.InputStream;import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.res.Resources;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.View;import android.widget.Button;public class Activity01 extends Activity{Renderer render = new GLRender();GLSurfaceView glView;Button start;// 演示开始/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);GLImage.load(this.getResources());glView = new GLSurfaceView(this);glView.setRenderer(render);setContentView(R.layout.main);start=(Button)findViewById(R.id.button1);// "演示开始"按钮初始化start.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubsetContentView(glView);}});//setContentView(glView);}}class GLImage{public static Bitmap iBitmap;public static Bitmap jBitmap;public static Bitmap kBitmap;public static Bitmap lBitmap;public static Bitmap mBitmap;public static Bitmap nBitmap;public static Bitmap close_Bitmap;public static void load(Resources resources){iBitmap = BitmapFactory.decodeResource(resources, R.drawable.img);jBitmap = BitmapFactory.decodeResource(resources, R.drawable.jmg);kBitmap = BitmapFactory.decodeResource(resources, R.drawable.kmg);lBitmap = BitmapFactory.decodeResource(resources, R.drawable.lmg);mBitmap = BitmapFactory.decodeResource(resources, R.drawable.mmg);nBitmap = BitmapFactory.decodeResource(resources, R.drawable.nmg);close_Bitmap = BitmapFactory.decodeResource(resources, R.drawable.close);}}


\src\com\yarin\android\Examples\GLRender.java

package com.yarin.android.Examples_12_05;import java.io.IOException;import java.io.InputStream;import java.nio.ByteBuffer;import java.nio.IntBuffer;import java.nio.ByteOrder;  import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer;import android.content.Context;public class GLRender implements Renderer{/** * 渲染类 * author:pis */private int one = 0x10000;public boolean mFlag ;public boolean bLight = true;//是否开启灯光private int[] vertices;//顶点数组private int[] textCood;//纹理数组float step = 0.3f;float xrot,yrot; //旋转float xSpeed,ySpeed; //移动速度private int[] textures = new int[1];private IntBuffer vertexBuffer; //顶点缓冲private IntBuffer textCoodBuffer; //纹理缓冲/** * 设置灯光 * @param context *///环境光private float[] lightAmbient;private FloatBuffer AmbientBuffer;//漫射光private float[] lightDiffuse;private FloatBuffer diffuseBuffer;//光源位置private float[] lightPosition;private FloatBuffer positionBuffer;/** * 初始化缓冲数据 */private void initBuffer(){//顶点ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);vbb.order(ByteOrder.nativeOrder());vertexBuffer = vbb.asIntBuffer();vertexBuffer.put(vertices);vertexBuffer.position(0);//纹理ByteBuffer tbb = ByteBuffer.allocateDirect(textCood.length * 4 * 6);tbb.order(ByteOrder.nativeOrder());textCoodBuffer = tbb.asIntBuffer();for (int i = 0; i < 6; i++) {textCoodBuffer.put(textCood);}textCoodBuffer.position(0);//环境光ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4 * 6);ambientbb.order(ByteOrder.nativeOrder());AmbientBuffer = ambientbb.asFloatBuffer();AmbientBuffer.put(lightAmbient);AmbientBuffer.position(0);//漫射光ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4 * 6);diffusebb.order(ByteOrder.nativeOrder());diffuseBuffer = diffusebb.asFloatBuffer();diffuseBuffer.put(lightDiffuse);diffuseBuffer.position(0);//灯光位置ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4 * 6);positionbb.order(ByteOrder.nativeOrder());positionBuffer = positionbb.asFloatBuffer();positionBuffer.put(lightPosition);positionBuffer.position(0);}/** * 初始化顶点、纹理、灯光数据 */private void initData(){//顶点数组vertices = new int[] { -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 };//纹理数组,贴图时注意android中坐标与OpengGL 中定义的不同,android,y轴是向下的textCood = new int[] { 0, 0, one, 0, 0, one, one, one };//灯光lightAmbient = new float[]{0.5f,0.5f,0.5f,1.0f};lightDiffuse = new float[]{1.0f,1.0f,1.0f,1.0f};lightPosition = new float[]{0.0f,0.0f,2.0f,1.0f};}public GLRender() {mFlag=true;initData();initBuffer();}@Overridepublic void onDrawFrame(GL10 gl) {//清除颜色和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);gl.glLoadIdentity();//启用灯光gl.glEnable(GL10.GL_LIGHTING);//启用顶点和纹理缓存gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//移动和旋转设置gl.glTranslatef(0.0f, 0.0f, -6.0f);gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);//设置顶点和纹理,经常忘记设置,唉!gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);gl.glTexCoordPointer(2,GL10.GL_FIXED,0,textCoodBuffer);//绘制六个面,贴图for (int i = 0; i < 6; i++) {      switch(i)        {        case 0:            // 8.生成纹理            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);            break;        case 1:            // 生成纹理            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.jBitmap, 0);            break;        case 2:            // 生成纹理            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 0);            break;        case 3:            // 生成纹理            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.lBitmap, 0);            break;        case 4:            // 生成纹理            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);            break;        case 5:            // 生成纹理            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.nBitmap, 0);            break;                            }gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);}//取消缓存,需我们自己手动gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);gl.glLoadIdentity();if (mFlag) {xrot += 0.5f;yrot += 0.5f;}if (!bLight) {gl.glDisable(GL10.GL_LIGHT1);} else {gl.glEnable(GL10.GL_LIGHT1);}}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {//场景大小gl.glViewport(0, 0, width, height);float ratio = (float) width / height;//投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);//重置下gl.glLoadIdentity();//视图大小设置gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//观察模型gl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity();}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {//透视效果gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);//清屏gl.glClearColor(0, 0, 0, 0);//启用阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);//清除深度缓存gl.glClearDepthf(one);//启用深度缓存gl.glEnable(GL10.GL_DEPTH_TEST);//深度缓存模式gl.glDepthFunc(GL10.GL_LEQUAL);/** * 设置纹理 *///启用纹理gl.glEnable(GL10.GL_TEXTURE_2D);//创建纹理gl.glGenTextures(1, textures, 0);//绑定纹理gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);//生成纹理GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 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, AmbientBuffer);//设置漫射光gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer);//设置灯光位置gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer);//启用1号灯光gl.glEnable(GL10.GL_LIGHT1);}}


三、效果:

【Android开发学习18】Android OpenGL ES 光照glDrawArrays_第1张图片

本文博客源地址:http://blog.csdn.net/ypist

更多相关文章

  1. android纹理
  2. android切换到后台,返回后图片纹理丢失
  3. Android OpenGL添加纹理
  4. android切换到后台图片纹理丢失的解决方案
  5. Android下基于OpenGL的程序会发生纹理丢失的原因
  6. OpenGL ES 纹理过滤模式-glTexParameteri
  7. android samplerExternalOES 纹理
  8. Unity3D for Android 纹理压缩支持
  9. Android OpenGLES2.0(八)——纹理贴图之显示图片

随机推荐

  1. PHP 枚举类型的管理与设计
  2. PHP中mysqli_get_server_version()的用法
  3. Centos下PHP5升级为PHP7的方法
  4. PHP脚本实现Markdown文章上传到七牛图床
  5. linux下 php 安装xml扩展的方法
  6. 关于PHP框架中日志系统的详解
  7. PHP函数库之类与对象详解
  8. php如何按需加载方式来增加程序的灵活度
  9. linux下php安装php-kafka和php-rdkafka扩
  10. PHP脚本导出MySQL数据字典(代码示例)