Android openGL ES 2.0入门--画三角形、正方形
来源:互联网 发布:linux 系统文件夹 编辑:程序博客网 时间:2024/05/16 09:52
因为最近的项目需要用到openGL ES 2.0,折腾了半天,查了网上一大堆资料,都没找到系统的openGL ES 2.0的学习资料。经过这半天,总算自己写了一个可以画出三角形和正方形的代码,顺便对网上一堆的代码封装了下。嗯,开始说吧。
首先感谢这篇教程:
http://hukai.me/android-training-course-in-chinese/graphics/opengl/environment.html
以及它的android官方原文:https://developer.android.com/training/graphics/opengl/shapes.html
不想往下看的同学,源码在这里:
http://download.csdn.net/detail/code_better/9592177
其他的我就不多说了,想说的都在注释里:
项目结构图:
先在manifest.xml里加上:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
MainActivity:
/** * GLSurfaceView相当于画布 * 主要绘画工作都在Renderer里 */public class MainActivity extends AppCompatActivity { private GLSurfaceView glSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //创建一个GLSurfaceView实例 glSurfaceView = new MyGLSurfaceView(this); //将glSurfaceView设置为activity的ContentView. setContentView(glSurfaceView); } @Override protected void onPause() { super.onPause(); if (glSurfaceView != null) { glSurfaceView.onPause(); } } @Override protected void onResume() { super.onResume(); if (glSurfaceView != null) { glSurfaceView.onResume(); } }}
MyGLSurfaceView:
class MyGLSurfaceView extends GLSurfaceView { public MyGLSurfaceView(Context context) { super(context); // 创建一个OpenGL ES 2.0 context,非常重要 setEGLContextClientVersion(2); //设置Renderer到GLSurfaceView setRenderer(new MyGL20Renderer()); // 只有在绘制数据改变时才绘制view //此设置会阻止绘制GLSurfaceView的帧,直到你调用了requestRender(),这样会非常高效// setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); }}
MyGL20Renderer:
public class MyGL20Renderer implements GLSurfaceView.Renderer { //声明一个三角形对象 Triangle triangle = null; //声明一个正方形对象 Square square = null; public void onSurfaceCreated(GL10 unused, EGLConfig config) { //设置背景的颜色 GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); triangle = new Triangle(); square = new Square(); } public void onDrawFrame(GL10 unused) { // 重绘背景色 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); //绘制三角形// triangle.draw(); //绘制矩形 square.draw(); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); }}
Util:
/** * Created by 炜贤 on 2016/8/1. * <p/> * 画一个图形:需要至少一个顶点着色器来绘制一个形状,以及一个片段着色器为该形状上色。 * 这些着色器必须被编译然后添加到一个OpenGL ES Program当中,并利用它来绘制形状。 */public class Util { /** * float类型大小为4个字节 */ private static final int LENGTH = 4; 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 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; } /** * 顶点着色器(Vertex Shader):用来渲染形状顶点的OpenGL ES代码 * * @return 顶点着色器 */ public int getVertexShader() { return loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); } /** * 片段着色器(Fragment Shader):使用颜色或纹理渲染形状表面的OpenGL ES代码。 * * @return 片段着色器 */ public int getFragmentShader() { return loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); } /** * 程式(Program):一个OpenGL ES对象,包含了你希望用来绘制一个或更多图形所要用到的着色器 * 程式(program)是用来装配着色器的(个人理解) * * @return 程式 */ public int getProgram() { //获取顶点着色器 int vertexShader = getVertexShader(); //获取片段着色器 int fragmentShader = getFragmentShader(); int program = GLES20.glCreateProgram(); // 创建空的OpenGL ES Program GLES20.glAttachShader(program, vertexShader); // 将vertex shader添加到program GLES20.glAttachShader(program, fragmentShader); // 将fragment shader添加到program GLES20.glLinkProgram(program); // 创建可执行的 OpenGL ES program // 添加program到OpenGL ES环境中 GLES20.glUseProgram(program); return program; } /** * @param coords_per_vertex 每个顶点的坐标数 * @param vertexBuffer 浮点缓冲区 * @param color 颜色数组,数组的四个数分别为图形的RGB值和透明度 */ public void draw(int coords_per_vertex, FloatBuffer vertexBuffer, float color[]) { //获取程式 int program = getProgram(); //得到处理到顶点着色器的vPosition成员 int vPositionHandler = GLES20.glGetAttribLocation(program, "vPosition"); // 启用一个指向图形的顶点数组的handle GLES20.glEnableVertexAttribArray(vPositionHandler); // 准备坐标数据 GLES20.glVertexAttribPointer(vPositionHandler, coords_per_vertex, GLES20.GL_FLOAT, false, LENGTH * coords_per_vertex, vertexBuffer); // 得到处理到片段着色器的vPosition成员 int mColorHandle = GLES20.glGetUniformLocation(program, "vColor"); // 设置颜色 GLES20.glUniform4fv(mColorHandle, 1, color, 0); // 绘制三角形比较简单,这里采用glDrawArrays方法(默认是逆时针方向) GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); // 禁用指向图形的顶点数组 GLES20.glDisableVertexAttribArray(vPositionHandler); } /** * * @param coords_per_vertex 每个顶点的坐标数 * @param vertexBuffer 浮点缓冲区 * @param color 颜色数组,数组的四个数分别为图形的RGB值和透明度 * @param drawOrder 绘制顶点的顺序(按逆时针方向) * @param drawListBuffer 绘图顺序顶点的缓冲区 */ public void draw(int coords_per_vertex, FloatBuffer vertexBuffer, float color[], short drawOrder[], ShortBuffer drawListBuffer) { //获取程式 int program = getProgram(); //得到处理到顶点着色器的vPosition成员 int vPositionHandler = GLES20.glGetAttribLocation(program, "vPosition"); // 启用一个指向图形的顶点数组的handle GLES20.glEnableVertexAttribArray(vPositionHandler); // 准备坐标数据 GLES20.glVertexAttribPointer(vPositionHandler, coords_per_vertex, GLES20.GL_FLOAT, false, LENGTH * coords_per_vertex, vertexBuffer); // 得到处理到片段着色器的vPosition成员 int mColorHandle = GLES20.glGetUniformLocation(program, "vColor"); // 设置颜色 GLES20.glUniform4fv(mColorHandle, 1, color, 0); // 绘制图形 GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer); // 禁用指向图形的顶点数组 GLES20.glDisableVertexAttribArray(vPositionHandler); }}
Triangle:
/** * 三角形 */public class Triangle { private FloatBuffer vertexBuffer; // 设置每个顶点的坐标数 static final int COORDS_PER_VERTEX = 3; // 设置三角形顶点数组 static float triangleCoords[] = { // 默认按逆时针方向顺序绘制 0.0f, 0.622008459f, 0.0f, // 顶 -0.5f, -0.311004243f, 0.0f, // 左底 0.5f, -0.311004243f, 0.0f // 右底 }; // 设置图形的RGB值和透明度 float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f}; /** * 初始化 * 流程:创建一个顶点的缓冲区空间,然后将其作为一个浮点的缓冲区, * 然后将坐标加到这个缓冲区中,然后将读指针指向第一个位置 */ public Triangle() { // 初始化顶点字节缓冲区,用于存放形状的坐标, ByteBuffer bb = ByteBuffer.allocateDirect( // (每个浮点数占用4个字节) triangleCoords.length * 4); // 设置使用设备硬件的原生字节序 bb.order(ByteOrder.nativeOrder()); // 将ByteBuffer作为一个浮点缓冲区 vertexBuffer = bb.asFloatBuffer(); // 把坐标都添加到FloatBuffer中 vertexBuffer.put(triangleCoords); // 设置buffer从第一个坐标开始读 vertexBuffer.position(0); } /** * 绘图 */ public void draw(){ new Util().draw(COORDS_PER_VERTEX,vertexBuffer,color); }}
Square:
/** * 正方形 */public class Square { //顶点缓冲区 private FloatBuffer vertexBuffer; //绘图顺序顶点缓冲区 private ShortBuffer drawListBuffer; // 每个顶点的坐标数 static final int COORDS_PER_VERTEX = 3; //正方形四个顶点的坐标 static float squareCoords[] = {-0.5f, 0.5f, 0.0f, // top left -0.5f, -0.5f, 0.0f, // bottom left 0.5f, -0.5f, 0.0f, // bottom right 0.5f, 0.5f, 0.0f}; // top right private short drawOrder[] = {0, 1, 2, 0, 2, 3}; // 顶点的绘制顺序 // 设置图形的RGB值和透明度 float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f}; public Square() { // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (坐标数 * 4) squareCoords.length * 4); bb.order(ByteOrder.nativeOrder()); vertexBuffer = bb.asFloatBuffer(); vertexBuffer.put(squareCoords); vertexBuffer.position(0); // 为绘制列表初始化字节缓冲 ByteBuffer dlb = ByteBuffer.allocateDirect( // (对应顺序的坐标数 * 2)short是2字节 drawOrder.length * 2); dlb.order(ByteOrder.nativeOrder()); drawListBuffer = dlb.asShortBuffer(); drawListBuffer.put(drawOrder); drawListBuffer.position(0); } /** * 绘图 */ public void draw() { new Util().draw(COORDS_PER_VERTEX, vertexBuffer, color, drawOrder, drawListBuffer); }}
这个画出来的三角形和正方形的效果并不是我们预想的的那样,那是因为投影的问题,请看我之后的博客吧,谢谢!
1 0
- Android openGL ES 2.0入门--画三角形、正方形
- android opengl es 三角形、正方形自动旋转
- android opengl es基本操作,画线,三角形,正方形,颜色设置
- Android OpenGL ES 2.0绘制简单三角形
- android openGL ES 20 投影、相机画等边三角形和正方形
- android opengl es--三角形,四边形
- openGL ES Android 三角形绘制
- Android OpenGL ES 入门
- Android OpenGL入门示例:绘制三角形和正方形 (附完整源码)
- Android OpenGL入门示例:绘制三角形和正方形 (附完整源码)
- android opengl es实例画三角形-native C实现
- Android OpenGL ES 2.0入门学习 1
- android opengl es绘制三角形+纹理
- Android OpenGL ES 基础:绘制三角形
- Android应用 :第一个 OpenGL ES 三角形
- android opengl es入门系列
- android opengl es 入门概述
- Android OpenGL ES 开发入门
- c/c++第七天
- html实现数据的增删查改
- 剑指Offer----面试题39(1):二叉树的深度
- HDU 1878 欧拉回路
- Java中final关键字
- Android openGL ES 2.0入门--画三角形、正方形
- HDOJ-----1878并查集+欧拉回路
- Chopsticks
- HDOJ-2120 Ice_cream's world I
- datatables获取数据列表
- [1st. Aug. 16] NOIP 2011 计算系数——纠结了很久才发现原来第一次做就大体做对了
- C++基础知识汇总
- C#控制台基础 string字符串的连接
- 网络连接取数据,并加载到ListView的实现