一、提要
偶然在Android developers看到这篇教程,遍一步步做了下来,下面是一点记录。
二、在Android中绘制OpenGL es的方法
为了在Android应用中使用OpenGL绘制图形,我们必须创建一个View容器。一个最直接的方法就是implementGLSurfaceView
和aGLSurfaceView.Renderer。前者就是容器,后者控制View中渲染的内容。
还有两种方法是SurfaceView和TextureView,但有点小复杂。
最终效果:
三、必要的声明
在manifest文件中添加下面的代码:
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
前面是声明OpenGL的版本,后两行是声明贴图的类型。
四、主Activity类
package com.example.opengles;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
public class OpenGLActivity extends Activity {
private GLSurfaceView mGLView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new MyGLSurfaceView(this);
setContentView(mGLView);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_open_gl, menu);
return true;
}
@Override
protected void onPause() {
super.onPause();
// The following call pauses the rendering thread.
// If your OpenGL application is memory intensive,
// you should consider de-allocating objects that
// consume significant memory here.
mGLView.onPause();
}
@Override
protected void onResume() {
super.onResume();
// The following call resumes a paused rendering thread.
// If you de-allocated graphic objects for onPause()
// this is a good place to re-allocate them.
mGLView.onResume();
}
}
class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context){
super(context);
// Create an OpenGL ES 2.0 context.
setEGLContextClientVersion(2);
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(new MyRender());
// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
四、渲染器类
package com.example.opengles;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
public class MyRender implements GLSurfaceView.Renderer {
private Triangle mTriangle;
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Draw triangle
mTriangle.draw();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
// Adjust the viewport based on geometry changes,
// such as screen rotation
GLES20.glViewport(0, 0, width, height);
}
public static int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
// Set the background frame color
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mTriangle = new Triangle();
}
}
class Triangle {
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;" +
"}";
private final FloatBuffer vertexBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = { // in counterclockwise order:
0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right
};
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex
// Set color with red, green, blue and alpha (opacity) values
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
public Triangle() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
// use the device hardware's native byte order
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate
vertexBuffer.position(0);
// prepare shaders and OpenGL program
int vertexShader = MyRender.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyRender.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
}
public void draw() {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
这个类中最重要的三个函数是
onSurfaceCreated()
-
初始化OpenGL环境
onDrawFrame()
-
绘制View
onSurfaceChanged()
-
当View发生改变的时候掉用是不是很熟悉,就是Qt的OpenGL中的paintGL()
,resizeGL() ,initializeGL() 。
最后运行的时候会在屏幕上绘制一个三角形,用的是ShaderLanguage,这个就直接copy了,当然也可以用那种比较原始的一个个定义点定义颜色来绘图。
注意:OpenGL的程序在模拟器中没办法跑起来,需要真机调试。
五、参考资料
android develop:http://developer.android.com/training/graphics/opengl/environment.html
分享到:
相关推荐
OPENGL ES 3.0编程指南
Android开发之OpenGL ES教程,Android开发之OpenGL ES教程,Android开发之OpenGL ES教程,Android开发之OpenGL ES教程,Android开发之OpenGL ES教程,Android开发之OpenGL ES教程,Android开发之OpenGL ES教程,...
Android平台采集Camera的YUV原始数据后使用OpenGLES2.0显示,内置YV12格式的YUV分量分离。 附件为完整例子,感谢“李狗蛋52635”提供的GLProgram类。
由资深Android开发专家根据OpenGLES2.0版本撰写,不仅系统地讲解了OpenGLES的核心概念、技术,以及Android的图形机制,还通过大量案例讲解了在Android上进行OpenGLES开发的方法和技巧。 《OpenGL ES应用开发实践...
OpenGL ES 2.0编程的入门基础书籍。适合初学者。
《OpenGL ES 2.0 编程指南 中文版》
该案例代码为Android 平台OpenGL ES实现举例,有两个作用: ...2、使用 OpenGLES 生成与使用Mipmap纹理,构建远处模糊,近处清晰的效果。 具体案例文章讲解请见: https://xiaxl.blog.csdn.net/article/details/8873106
Android OpenGL ES 2.0 开发教程 从入门到精通和Demo(内容详细、简单,易学)
OpenGL ES编程指南pdf+源代码OpenGL ES编程指南pdf+源代码OpenGL ES编程指南pdf+源代码OpenGL ES编程指南pdf+源代码
这儿是有关OpenGL ES 2.0的编程指南,是中文版哦!欢迎下载
在Android平台,使用OpenGLES3.0实现纹理纹理、颜色混合代码实现举例。 具体案例文章讲解请见: https://xiaxl.blog.csdn.net/article/details/121634894
OPENGL ES 3.0编程指南 原书第2版 清晰中文版.pdf openGL学习最佳文档,适合初学者
Android平台,OpenGL ES3.0 点、线、三角形绘制方式源码实现举例。 相关绘制方式文章讲解请参考: https://xiaxl.blog.csdn.net/article/details/8873002
超棒的Android的OpenGL ES入门教程!由 Per-Erik Bergman写的6个教程,并附带一份OpenGL ES 1.1 Reference Pages。 内容介绍: OpenGL ES Tutorial for Android – Part I – Setting up the view OpenGL ES ...
opengl es 未来不仅仅会用于游戏,也是总的确实,3D UI 提供更好的体验。
如何使用Android中的OpenGL ES媒体效果,应用Android的media effect framework到OpenGL中
《OpenGL ES 《OpenGL ES 2.0 编程指南 中文版》2.0 编程指南 中文版》
OpenGL ES 2.0 编程指南 中文版, 留个备份,好东西。
OpenGL ES 2.0编程指南,是官方正式文档。详细讲述了OpenGL ES 2.0版本中所有API的细节和使用描述,另外还有一些简单的sample.