内容简介:OpenGl入门什么是OpenGLOpen Graphics Library,图形领域的工业标准,是一套跨平台的、专业的、图形变成软件接口。它用于二维、三维图像,是一个功能强大的调用方便的底层图形库。
OpenGl入门
什么是OpenGL
Open Graphics Library,图形领域的工业标准,是一套跨平台的、专业的、图形变成软件接口。它用于二维、三维图像,是一个功能强大的调用方便的底层图形库。
OpenGL与硬件无关,可以在不同的平台比如Windows、 Linux 、Mac、Andorid、IOS之间进行移植,因此也得到了广泛的应用。
Android 中使用OpenGl ES
GLSurfaceView,它继承自SurfaceView,它内嵌的sufface专门负责OpenGl渲染,管理Surface与EGL,允许自定义渲染器,让渲染器在独立的线程中运作,和UI线程分离,并且支持按需渲染(on-demand)和连续渲染(continuous)。
OpenGL是一个跨平台操作GUP的API,但是OpenGL需要本地视窗系统进行交互,这几需要一个中间层,EGL就是连接OpenGL ES和本地窗口的接口,引入EGL就是为了屏蔽不同平台上的区别。
CPU和GPU的区别
- CPU是机器的大脑,中央处理器,用来发号施令
- GPU的结构主要包括运算器(ALU),控制单元(CU),寄存器(Register),高速缓存器(Cache)和他们之间通讯的数据,控制及状态的总线
计算单元主要执行算数运算,位移和转换
存储单元主要用来保存运算中产生的数据以及指令等
控制单元则对指令译码,发出要完成每条指令要执行的各个操作的控制信号。
CPU中控制器和缓存器比较多,GPU中计算单元比较多。GPU无法单独工作,必须由CPU进行控制调用才能工作,CPU可以单独作用。
Android中渲染步骤
UI对象–>CPU处理为纹理–>通过OpenGLES接口调用GPU
–>GPU对图像进行栅格化–>硬件时钟–>垂直同步–>投射到屏幕
一维 点 顶点
二维 线 2个顶点
三维 面 3个顶点
在OpenGl的世界中中是又很多的3个顶点组成。
- 一个3D图片根据像素可以形成无数个顶点,顶点的连线叫做纹理(顶点着色器)
- 根据纹理形成一个一个像素(就像PS中对文字进行像素处理)(光栅化)
- 对像素进行着色(片元着色器)
- 上色之后交给GPU渲染(OpenGl渲染)
在使用OpenGl的时候,第二个和第四个是由系统完成的,我们需要手动写第一个和第三个,告诉系统有多少顶点和怎么着色
练习:
使用OpenGl绘制一个三角形
新建一个项目,Andorid系统中已经有OpenGl,不用导入第三方库,不过需要在AndroidManifest.xml中声明需要使用OpenGl
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
OpenGl 使用套路
- 创建顶点数组
- 使用gl语言写顶点着色器和片元着色器
- 将 java 声明是顶点数组,颜色数组,传给gl语言中的变量
- GPU开始渲染
自定义一个View继承自GLSurfaceView
public class GLView extends GLSurfaceView { public GLView(Context context) { super(context); } public GLView(Context context, AttributeSet attrs) { super(context, attrs); setEGLContextClientVersion(2); setRenderer(new GLRander(this)); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); } }
定义一个渲染器,定义一个三角形的类Triangle,绘制的方法交给它自己来做,因为还可能绘制别的图形。
public class GLRander implements GLSurfaceView.Renderer { protected View mView; Triangle mTriangle; public GLRander(View view) { mView = view; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { GLES20.glClearColor(0, 0, 0, 0); mTriangle = new Triangle(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { mTriangle.onSurfaceChanged(gl, width, height); } /** * 该方法不断被调用 */ @Override public void onDrawFrame(GL10 gl) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT); mTriangle.onDrawFrame(gl); } }
开始绘制。
顶点着色器用来确定需要绘制的图形的顶点,片元着色器用来给它上色。
顶点着色器和片元着色器都是使用着色器语言(GLSL)语言编写,编写的程序可以直接推送给GPU执行。
public class Triangle { /** * 三个顶点 */ static float triangleCoords[] = { 0.5f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, }; /** * 管道 */ private FloatBuffer vertexBuffer; /** * 顶点着色器 */ private String vertextShaderCode = "attribute vec4 vPosition;\n" + "uniform mat4 vMatrix;\n" + "void main(){" + "gl_Position=vMatrix*vPosition;" + "}"; /** * 片元着色器 */ private final String fragmentShaderCode = "precision mediump float;\n" + "uniform vec4 vColor;\n" + "void main(){\n" + "gl_FragColor=vColor;\t\n" + "}"; int mProgram; public Triangle(){ ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4); bb.order(ByteOrder.nativeOrder()); vertexBuffer=bb.asFloatBuffer(); // 把顶点 推送 给GPU vertexBuffer.put(triangleCoords); vertexBuffer.position(0); //创建顶点着色器 并在GPU中编译 int shader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); GLES20.glShaderSource(shader,vertextShaderCode); //编译顶点着色器 GLES20.glCompileShader(shader); //创建片元着色器 并在GPU中编译 int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); GLES20.glShaderSource(fragmentShader,fragmentShaderCode); //编译片元着色器 GLES20.glCompileShader(fragmentShader); //将顶点着色器和片元着色器放到统一的管理器中进行管理 mProgram = GLES20.glCreateProgram(); GLES20.glAttachShader(mProgram,shader); GLES20.glAttachShader(mProgram,fragmentShader); //连接到着色器程序 GLES20.glLinkProgram(mProgram); } public void onSurfaceChanged(GL10 gl, int width, int height) { //计算宽高比 float ratio=(float)width/height; //投影矩阵 Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 120); //相机 Matrix.setLookAtM(mViewMatrix, ////摄像机的坐标 0, 0, 0, 7, //目标物的中心坐标 0f, 0f, 0f, //相机方向 0f, 1f, 0f); //计算变换矩阵 Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0); } /** * rgba */ float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; private float[] mViewMatrix=new float[16]; private float[] mProjectMatrix=new float[16]; private float[] mMVPMatrix=new float[16]; public void onDrawFrame(GL10 gl) { //开始渲染 //拿到总的程序 GLES20.glUseProgram(mProgram); //拿到vPosition的地址 int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); //设置缩放 int mMatrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix"); GLES20.glUniformMatrix4fv(mMatrixHandler,1,false,mMVPMatrix,0); //允许对这个地址进行读写 GLES20.glEnableVertexAttribArray(mPositionHandle); //给顶点着色器赋值 GLES20.glVertexAttribPointer(mPositionHandle,3, GLES20.GL_FLOAT,false,3*4,vertexBuffer); //给片元着色器赋值 int mColorHandle = GLES20.glGetUniformLocation(mProgram,"vColor"); GLES20.glUniform4fv(mColorHandle,1,color,0); //开始绘制 GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3); //关闭读写 GLES20.glDisableVertexAttribArray(mPositionHandle); } }
结果:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- TiDB入门(四):从入门到“跑路”
- MyBatis从入门到精通(一):MyBatis入门
- MyBatis从入门到精通(一):MyBatis入门
- Docker入门(一)用hello world入门docker
- 赵童鞋带你入门PHP(六) ThinkPHP框架入门
- 初学者入门 Golang 的学习型项目,go入门项目
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。