最近工作要用到OpenGL的技术,现在开始学习一些OpenGL ES的基础知识,并记录。
所有参考:
Android入门(4)OpenGL ES编程环境搭建
http://blog.youkuaiyun.com/silangquan/article/details/7938332
一步一步学android OpenGL ES2.0编程(1)http://blog.youkuaiyun.com/niu_gao/article/details/8533126
1、Android Mainfest如下:
重点:<uses-feature android:glEsVersion="0x00020000" android:required="true"/>指明使用OpenGL的版本
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.opengl01"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="17" />
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.test.opengl.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>2、MainActivity里,只要定义GLSurfaceView mGLView即可,绘图用的控件
package com.test.opengl;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class MainActivity extends Activity {
private GLSurfaceView mGLView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new MyCLSurfaceView(this);
setContentView(mGLView);
}
@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}
@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
}
3、MyCLSurfaceView,继承自GLSurfaceView,只要创建OpenGL 的上下文对象,设置绘图对象,并在绘制数据改变时才重绘MyCLSurfaceView
package com.test.opengl;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class MyCLSurfaceView extends GLSurfaceView {
public MyCLSurfaceView(Context context) {
super(context);
// 创建一个OpenGL ES 2.0 context
setEGLContextClientVersion(2);
//设置Renderer到GLSurfaceView
setRenderer(new MyGL20Renderer());
//只有在绘制数据改变时才绘制view
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}4、MyGL20Renderer,Renderer,所有的绘图步骤全部在这里实现
package com.test.opengl;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
/*此类控制向GLSurfaceView的绘制工作。它有三个方法被Android系统调用来计算在
* GLSurfaceView上画什么以及如何画。
* onSurfaceCreated()- 仅调用一次,用于设置view的OpenGLES环境。
*onDrawFrame()- 每次View被重绘时被调用。
*onSurfaceChanged()- 如果view的几和形状发生变化了就调用,例如当竖屏变为横屏时。
*/
public class MyGL20Renderer implements GLSurfaceView.Renderer{
@Override
public void onDrawFrame(GL10 gl) {
//重绘背景色
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
mTriangle.draw();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
GLES20.glViewport(0, 0, width, height);
}
Triangle mTriangle = null;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//设置背景的颜色
// GLES20.glClearColor(red, green, blue, alpha)
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// 初始化一个三角形
mTriangle = new Triangle();
}
public static int loadShader(int type, String shaderCode){
// 创建一个vertex shader类型(GLES20.GL_VERTEX_SHADER)
// 或fragment shader类型(GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// 将源码添加到shader并编译之
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
5、如果要绘制某种形状。则要自定义类来实现,所有绘图的详细过程在自定义类中实现。
package com.test.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
public class Triangle {
private FloatBuffer vertexBuffer;
//数组中每个顶点的坐标数
static final int COORDS_PER_VERTEX = 3;
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex
static float triangleCoords[] = {//逆时针
0.0f, 0.6f, 0.0f,//top
-0.5f, -0.3f, 0.0f,
0.5f, -0.3f, 0.0f
};
float color[] = {0.6f,0.7f,0.2f,1.0f};
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
public Triangle(){
//为存放形状的坐标,初始化顶点字节坐标
ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length *4);
//设置设备的顶点字节序
bb.order(ByteOrder.nativeOrder());
//从ByteBuffer创建一个浮点缓冲
vertexBuffer = bb.asFloatBuffer();
//把所有坐标加入FloatBuffer中
vertexBuffer.put(triangleCoords);
//设置buffer为从第一个坐标读起
vertexBuffer.position(0);
int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // 创建一个空的OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // 将vertex shader添加到program
GLES20.glAttachShader(mProgram, fragmentShader); // 将fragment shader添加到program
GLES20.glLinkProgram(mProgram); // 创建可执行的 OpenGL ES program
}
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;//?????
public void draw() {
// 将program加入OpenGL ES环境中
GLES20.glUseProgram(mProgram);
// 获取指向vertex shader的成员vPosition的 handle
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// 启用一个指向三角形的顶点数组的handle
GLES20.glEnableVertexAttribArray(mPositionHandle);
// 准备三角形的坐标数据
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);//????
// 获取指向fragment shader的成员vColor的handle
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// 设置三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// 画三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);//??????
// 禁用指向三角形的顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
本文介绍如何在Android环境下搭建OpenGL ES2.0编程环境,包括配置AndroidManifest.xml文件以指定OpenGL版本,创建并使用GLSurfaceView及其Renderer进行绘图的基本步骤。
2046

被折叠的 条评论
为什么被折叠?



