内容简介: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入门项目
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Building Websites with Joomla!
H Graf / Packt Publishing / 2006-01-20 / USD 44.99
This book is a fast paced tutorial to creating a website using Joomla!. If you've never used Joomla!, or even any web content management system before, then this book will walk you through each step i......一起来看看 《Building Websites with Joomla!》 这本书的介绍吧!