- 浏览: 64184 次
-
文章分类
最新评论
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);
}
}
三、效果:

相关推荐
OpenGL ES 2.0是Android平台上用于2D和3D图形渲染的重要库,它是OpenGL针对嵌入式设备的精简版本。JNI(Java Native Interface)则允许Java代码调用C/C++原生代码,为高性能计算和图形处理提供可能。在Android应用...
在Android系统中,OpenGLES 2.0是用于图形渲染的重要框架,支持3D图形和复杂的视觉效果。本教程旨在帮助开发者从零基础开始掌握OpenGLES 2.0,并通过实例Demo加深理解。 入门篇: 1. **环境配置**:首先,你需要...
在Android平台上,OpenGL ES是一种广泛使用的图形库,用于在移动设备上进行2D和3D图形渲染。OpenGL ES(Embedded Systems)是OpenGL的轻量级版本,特别为嵌入式设备设计,如智能手机和平板电脑。这个“Android ...
"opengles绘制球体增加光照效果"这个主题旨在讨论如何在OpenGL ES环境下为3D球体添加真实的光照效果,使渲染出的模型更具有立体感和生动性。 光照模型在OpenGL ES中主要通过两种方式实现:固定管线(Fixed Pipeline...
OpenGL ES 是一种在嵌入式设备上广泛使用的图形库,特别是在Android系统中,它用于创建高性能的2D和3D图形。本教程旨在帮助开发者掌握Android平台上的OpenGL ES编程技术,实现复杂的视觉效果。 首先,我们要理解...
在Android平台上,OpenGL ES 2.0是一个重要的图形库,它提供了丰富的图形渲染功能,包括顶点、着色器、纹理映射等,广泛应用于游戏开发、图像处理和增强现实应用。 在"android opengl es 2.0官方demo"中,我们可以...
在Android平台上,OpenGL ES是图形编程的核心,提供了丰富的图形处理能力,使得开发者能够创建出具有高度交互性和视觉吸引力的应用。 Android中的OpenGL ES分为多个版本,包括OpenGL ES 1.x、2.0、3.0及以上。每个...
这个"Android OpenGL的一个简单的例子.zip"文件包含了一个基本的Android OpenGL应用实例,帮助开发者了解如何在Android设备上使用OpenGL ES。 首先,我们需要了解OpenGL ES的基本概念。OpenGL ES是OpenGL的精简版,...
在Android平台上,OpenGL ES(OpenGL for Embedded Systems)被广泛使用,这是OpenGL的一个子集,专门针对移动设备等嵌入式系统优化。 #### Android与OpenGL的关系 Android系统为开发者提供了一个OpenGL ES的API库...
使用`glDrawArrays()`或`glDrawElements()`绘制物体,OpenGL ES会根据设置的光照和材质属性计算每个顶点的最终颜色。 7. **清理与关闭**: 绘制完成后,记得禁用不再需要的光源和光照计算,以优化性能。使用`...
在Android平台上,OpenGL ES(Embedded Systems的缩写)被广泛使用,它是OpenGL的一个精简版本,专为嵌入式设备如智能手机和平板电脑设计。Android OpenGL ES提供了丰富的接口,让开发者能够创建复杂的图形应用程序...
在Android开发中,OpenGL ES(OpenGL for Embedded Systems)是一个广泛使用的图形库,用于在移动设备上绘制复杂的2D和3D图形。本教程将详细讲解如何在Android Studio中利用OpenGL ES绘制一个三棱锥,并对其表面进行...
**Android OpenGLES详解** OpenGLES,全称为OpenGL for Embedded Systems,是针对嵌入式设备,特别是移动设备(如Android智能手机和平板电脑)而设计的一种图形处理接口。它是OpenGL标准的一个子集,专为资源有限但...
在Android平台上,NDK(Native Development Kit)允许开发者使用C和C++编写底层代码,而OpenGL ES则是一种用于渲染2D、3D图形的应用程序编程接口。本篇将详细讲解如何在Android NDK环境中利用C语言调用OpenGL ES来...
OpenGL ES 2.0是Android平台上用于图形渲染的重要框架,主要应用于移动设备和嵌入式系统,它基于OpenGL标准,但针对资源有限的环境进行了优化。在Android中,OpenGL ES 2.0提供了低级别的图形编程接口,允许开发者...
在Android平台上,OpenGL ES是一个广泛使用的图形库,用于在移动设备上实现高性能的3D图形渲染。本篇将深入探讨如何使用OpenGL ES绘制一个球体。球体在计算机图形学中是一个基本的几何形状,通常通过一系列三角形来...
在Android系统中,OpenGL ES(OpenGL for Embedded Systems)是其子集,专为移动设备如智能手机和平板电脑设计,它提供了丰富的图形渲染功能。Android OpenGL ES允许开发者创建复杂的视觉效果和交互式应用。 在...
5. **着色器编程**:OpenGL ES使用着色器语言(GLSL)来控制图形的外观,包括颜色、光照等。在这个基础范例中,可能会有一个简单的顶点着色器来定位顶点,以及一个片段着色器来确定像素颜色。 6. **帧缓冲对象...
在Android平台上进行移动应用开发时,常常会遇到需要创建3D图形的需求,这通常涉及到OpenGL ES(OpenGL for Embedded Systems)的使用。OpenGL ES是OpenGL的一个轻量级版本,专为嵌入式设备如手机和平板电脑设计,...
OpenGL Dice Game是一款基于Android平台,利用OpenGL ES技术开发的简单骰子游戏。OpenGL ES是OpenGL的一个轻量级版本,专为嵌入式设备如智能手机和平板电脑设计,用于处理2D和3D图形渲染。本游戏的核心就是通过...