Android OpenGL教程-第一课【转】
第一课 快速的开始一个Android OpenGL项目
首先,读懂我们的教程,需要有android的初步基础,我们这里只是通过android提供的SDK,来进行OpenGL的学习,所以你必须先学习如何建立一个android的项目,同时了解activity的生命周期和android下的屏幕或键盘响应机制。
好的,开始建立一个android的项目Lesson1,Activity的名字的名字我们叫Lesson。
Lesson类:
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager; public class Lesson extends Activity {
private OpenGLView mOpenGLView; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 去标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); mOpenGLView = new OpenGLView(this); setContentView(mOpenGLView);
}
}
我们在这里用了一个OpenGLView类,把这个类直接设为contentView。
OpenGLView类:
import android.content.Context;
import android.opengl.GLSurfaceView; /**
* OpenGLView类继承自GLSurfaceView,这个类是android提供的用opengl画图的类。
*/
public class OpenGLView extends GLSurfaceView {
private OpenGLRenderer mRenderer; public OpenGLView(Context context) { super(context); mRenderer = new OpenGLRenderer(); setRenderer(mRenderer); // TODO Auto-generated constructor stub }
}
OpenGLView类继承自GLSurfaceView,这个类是android提供的用opengl画图的类。这里用了OpenGLRenderer类,Render是渲染的意思,真正画图的操作在这个类里面。
OpenGLRenderer类:
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; /**
* 渲染器类,实现了GLSurfaceView.Renderer接口,实现这个接口,需要实现3个方法:OnSurfaceCreated(),
* OnSurfaceChanged(),OnDrawFrame()。
*/
public class OpenGLRenderer implements Renderer { /**
* 该方法是画图方法,类似于View类的OnDraw(),一般所有的画图操作都在这里实现。
*/
@Override
public void onDrawFrame(GL10 gl) {
// 清除屏幕和深度缓存。
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 重置当前的模型观察矩阵。
gl.glLoadIdentity();
} /**
* 在Surface发生改变的时候调用,例如从竖屏切换到横屏的时候
*/
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 设置输出屏幕大小
gl.glViewport(0, 0, width, height);
} /**
* 在Surface创建的时候调用,一般在这里做一个初始化openggl的操作
*/
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。
gl.glShadeModel(GL10.GL_SMOOTH); // 设置清除屏幕时所用的颜色,参数对应(红,绿,蓝,Alpha值)。色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。
gl.glClearColor(0f, 0f, 0f, 0f); // 下面三行是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。深度缓存不断的对物体进入屏幕内部有多深进行跟踪。
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL); // 这里告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点。
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
} }
这个类实现了GLSurfaceView.Renderer接口,实现这个接口,需要实现3个方法:OnSurfaceCreated(),OnSurfaceChanged(),OnDrawFrame()。第一个方法在Surface创建的时候调用,我们一般在这里做一个初始化openggl的操作,第二个方法在Surface发生改变的时候调用,例如从竖屏切换到横屏的时候;第三个方法是画图方法,类似于View类的OnDraw(),一般所有的画图操作都在这里实现。
注:现在我们大多是在JAVA层操作,后来学习深入后,这里画图的一些操作大多需要很多的计算,我们可以用NDK在C++层进行。
我们看OnSurfaceCreate里面的代码,这里都是在做对OpengGL的初始化。
gl.glShadeModel(GL10.GL_SMOOTH);
启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑,在以后的课程中会看到他的效果。
gl.glClearColor(0f, 0f, 0f, 0f);
设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话,我快速解释一下。色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。glClearColor 后的第一个参数是Red Intensity(红色分量),第二个是绿色,第三个是蓝色。最大值也是1.0f,代表特定颜色分量的最亮情况。最后一个参数是Alpha值。当它用来清除屏幕的时候,我们不用关心第四个数字。现在让它为0.0f。我会用另一个教程来解释这个参数。
通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。希望您在学校里学过这些。因此,当您使用glClearColor(0.0f,0.0f,1.0f,0.0f),您将用亮蓝色来清除屏幕。如果您用 glClearColor(0.5f,0.0f,0.0f,0.0f)的话,您将使用中红色来清除屏幕。不是最亮(1.0f),也不是最暗 (0.0f)。要得到白色背景,您应该将所有的颜色设成最亮(1.0f)。要黑色背景的话,您该将所有的颜色设为最暗(0.0f)。我们在这里设置屏幕为黑色。
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
这三行是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。深度缓存不断的对物体进入屏幕内部有多深进行跟踪。我们本节的程序其实没有真正使用深度缓存,但几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。它的排序决定那个物体先画。这样您就不会将一个圆形后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
这里告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点。
在OnDrawFrame方法中
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
清除屏幕和深度缓存。
gl.glLoadIdentity();
重置当前的模型观察矩阵。
本课的效果只是生成了一个黑色的屏幕,很多代码并没有发生应有的效果,后面的课程中,我们会使用到这些代码,到时候大家就能看到这些代码所产生的效果。
附:
1. 我们来改变背景的颜色
将gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);从SurfaceCreate放到OnDrawFrame里面,这里设置为红色了,运行下看看,是不是背景成红色了。
2. 加上点击屏幕来改变背景的颜色
第一步,在render里面加3个float(成员变量)
private float cr,cg,cb;
第二步,加个设置r,g,b的函数
// (这是附加的)设置RGB颜色的方法
public void setColor(float r, float g, float b) {
cr = r;
cg = g;
cb = b;
}
第三步,在glclearColor里面用cr,cg,cb来设置颜色。
gl.glClearColor(cr, cg, cb, 0.0f);
第四步,在view (OpenGLView类)里面override onTouchEvent函数,在这里响应点击屏幕的事件。
@Override
public boolean onTouchEvent(final MotionEvent event) {
/*
* 由于渲染对象是运行在一个独立的渲染线程中,所以需要采用跨线程的机制来进行事件的处理。
* 但是Android提供了一个简便的方法:
* 我们只需要在事件处理中使用queueEvent(Runnable)就可以了.
*/
queueEvent(new Runnable() {
@Override
public void run() {
mRenderer.setColor(event.getX() / getWidth(), event.getY()
/ getHeight(), 1.0f);
}
}); return super.onTouchEvent(event);
}
至于这里为什么用final,大家去网上查查,刚好也复习一下内部类调用参数,需要final这个知识点。
运行效果:
个人资料:http://blog.csdn.net/xiajun07061225/article/details/7455283
(注:本教程转自其他网页,并加以修改,查看原网页请点击这里)
Android OpenGL教程-第一课【转】的更多相关文章
- NeHe OpenGL教程 第一课:OpenGL窗口
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- Nehe OpenGL教程第一课-创建一个OpenGL窗口(Win32)
原文英文地址为:Creating an OpenGL Window (Win32),翻译的chm中文格式文档下载地址为:OpenGL教程电子书(chm格式)中文版,源代码在官网上也可以下载到,每 ...
- Android OpenGL教程-第二课【转】
第二课 你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形. 读完了 ...
- Android精通教程-第一节Android入门简介
前言 大家好,给大家带来Android精通教程-第一节Android入门简介的概述,希望你们喜欢 每日一句 If life were predictable it would cease to be ...
- NeHe OpenGL教程 第九课:移动图像
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- NeHe OpenGL教程 第二课:多边形
前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢 ...
- CodeIgniter框架入门教程——第一课 Hello World!
本文转载自:http://www.softeng.cn/?p=45 今天开始,我将在这里连载由我自己编写的<CodeIgniter框架入门教程>,首先,这篇教程的读着应该是有PHP基础的编 ...
- NeHe OpenGL教程 第四十一课:体积雾气
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- [原创]零基础R语言教程---第一课---认识R语言
教程的录制的确是折腾了一番,一连录了二十多遍,有时候激动的说错了字,有时候不知道下一句说啥.. 不过好在第一课已经搞定了,哈哈. 虽然内容现在看起来还有点简单, 不过牛b也是一个过程嘛. 我会坚持下去 ...
随机推荐
- typescript多维对象数组仿List泛型
定义对象: namespace entity{ export class MyClass{ public value:number; public rect:string; public constr ...
- IO模型《五》异步IO
Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入.先看一下它的流程: 用户进程发起read操作之后,立刻就可以开始去做其它的事.而另一方面,从kernel的角度,当 ...
- React Native 搭建开发环境
1.先安装node.js,https://nodejs.org/en/download/ 然后,双击下载好的.msi文件安装即可,安装完成后,打开终端,输出npm -v 即可查看我们刚才安装的node ...
- js项目
https://bbs.csdn.net/topics/320029234 文本实现悬挂缩进 牛逼牛逼 这是真的牛逼 p:first-letter { margin-left: -2e ...
- [Swift实际操作]八、实用进阶-(8)使用performSegue在故事板页面之间进行数据传递
本文将演示故事板页面之间的数据传递.首先在一个空白项目中,打开项目自带的故事板文件(Main.storyboard).故事板中已经拥有了一个视图控制器,点击选择该视图控制器.然后依此点击[Editor ...
- SAP生产订单各种日期的计算说明
生产订单各种日期的计算说明 基本日期.已计划的.确认的日期,介绍一下这些日期的作用和计算方法: 首先我们来介绍一下基本日期: 基本开始日期:表示订单的开始日期 基本完成日期:表示订单的完成日期 我们在 ...
- 863公司 linux软测题
1.浏览目录命令 2.浏览文件命令 3.目录操作命令 4.文件操作命令 5.进程管理命令
- 初识express
初识Express 1.简介: express是基于Nodejs平台的快速,开放,极简的web开发框架 2.安装 npm install express --save 3.Hello world: c ...
- bzoj 3261 最大异或和 可持久化字典树(01树)
题目传送门 思路: 由异或的性质可得,题目要求的式子可以转化成求$max(pre[n]^x^pre[i])$,$pre[i]$表示前缀异或和,那么我们现在就要求出这个东西,所以用可持久化字典树来求,每 ...
- QRegExp
这段代码会越界,百思不得七姐(过了N久时间 之后^^)原来是把i写成了1 --! //#if 0 QRegExp re1("AT+CGATT?"); QRegExp re2(&q ...