Android OpenGL ES 光照glDrawArrays

一、基础知识:

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】

[html]

<?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】

[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. */

@Override

public 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() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

setContentView(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】

[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();

}

@Override

public 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);

}

}

@Override

public 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();

}

@Override

public 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 OpenGL ES 光照glDrawArrays

分类:默认分类 时间:2014-07-06 人气:300
本文关键词:
分享到:

相关文章

Copyright (C) quwantang.com, All Rights Reserved.

趣玩堂 版权所有 京ICP备15002868号

processed in 0.320 (s). 10 q(s)