当前位置:网站首页>First knowledge of OpenGL es learning (1)
First knowledge of OpenGL es learning (1)
2022-07-06 07:05:00 【Unlimited exchange】
1. know OpenGL ES
OpenGL It's cross platform 2D/3D graphics API, and OpenGL ES It is an extended version based on the former , Suitable for embedded devices such as mobile phones . It has the following versions :
| edition | explain |
|---|---|
| OpenGL ES 1.0 | 2003 Released in |
| OpenGL ES 1.1 | Supports multiple textures , Vertex buffer object, etc |
| OpenGL ES 2.0 | 2007 Released in , be based on OpenGL 2.0, Deleted 1.x Fixed pipeline in (pipeline), Provide programmable pipelines |
| OpenGL ES 3.0 | 2012 Released in , Backward compatibility 2.x |
| OpenGL ES 3.1 | 2014 Released in |
| OpenGL ES 3.2 | 2015 Released in |
OpenGL ES 1.x and OpenGL ES2.0 Incompatible , Are two completely different implementations .
OpenGL EX 1.x Only fixed pipeline rendering is supported , It can be firmware support or software emulation , But the rendering ability is limited .
OpenGL EX 2.X Using programmable rendering pipeline , Improved rendering ability . But the difficulty of programming has also increased , And it is required that there must be corresponding GPU Hardware support .


The above figure 3-16 Sum graph 3-21 Namely OpenGL 1.x and OpenGL 2.x Rendering pipeline process diagram .“ Transform and lighting ”---->“ Vertex shader ”
“ Texture environment and color summation ”、“ Fog ”、“Alpha velocity measurement ”---->“ Chip shader ”
This series will focus on OpenGL ES2.x
2. First time to know OpenGL ES2.x Program appearance
I'm getting to know you OpenGL ES After the foundation , Here is an entry level Demo( The official website of this program also has similar learning ). Comments have been added to the code , It can better help you get started .
2.1 design sketch

2.2 Tool class ShaderUtil.java
public class ShaderUtil {
private static final String TAG = "ShaderUtil";
/**
* Load shaders encoded into GPU And compile
*
* @param shaderType Shader type
* @param source Shader script string
* @return
*/
public static int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (shader != 0) {
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "loadShader: ES20_ERROR,Could not compile shader " + shaderType + ";");
Log.e(TAG, "loadShader: ES20_ERROR,shader = " + GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
/**
* Create shader program
*
* @param vertexSource
* @param fragmentSource
* @return
*/
public static int createProgram(String vertexSource, String fragmentSource) {
// Load vertex shaders
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {
return 0;
}
// Load the slice shader
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0) {
return 0;
}
int program = GLES20.glCreateProgram();
if (program != 0) {
GLES20.glAttachShader(program, vertexShader);
checkGLError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
checkGLError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "createProgram: ES20_ERROR,Could not link program");
Log.e(TAG, "createProgram: ES20_ERROR,program = " + GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
/**
* Check whether there is a wrong method in each operation
*
* @param op
*/
public static void checkGLError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.d(TAG, ">>>>>> " + op + " :glError " + error);
throw new RuntimeException(op + ":glError " + error);
}
}
/**
* from sh Load shader contents in the script
*
* @param fname
* @param resources
* @return
*/
public static String loadFromAssetsFile(String fname, Resources resources) {
String result = null;
try {
InputStream in = resources.getAssets().open(fname);
int ch = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((ch = in.read()) != -1) {
baos.write(ch);// The obtained information is written to the stream
}
byte[] buffer = baos.toByteArray();
baos.close();
in.close();
result = new String(buffer, "UTF-8");
result = result.replaceAll("\\r\\n", "\n");
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "loadFromAssetsFile: result = " + result);
return result;
}
}
2.3 triangle Triangle
public class Triangle {
public static float[] mProjMatrix = new float[16];//4x4 Projection matrix
public static float[] mVMatrix = new float[16];// Parameter matrix of camera position orientation
public static float[] mMvPMatrix;// Total transformation matrix
private int program;// Custom render pipeline shader program id
private int muMVPMatrixHandle;// Total transformation matrix reference
private int maPositionHandle;// Vertex position attribute reference
private int maColorHandle;// Vertex color attribute reference
private String mVertexShader;// Vertex shader code script
private String mFragmentShader;// Fragment shader code script
private static float[] mMMatrix = new float[16];// Specific objects 3D Transformation matrix , Including rotation 、 translation 、 The zoom
private FloatBuffer mVertexBuffer;// Vertex coordinate data buffer
private FloatBuffer mColorBuffer;// Vertex shading data buffer
private int vCount = 0;// Number of vertices
public float xAngle = 0;// Around the X Angle of axis rotation
public Triangle(MyTDView myTDView) {
initVertexData();
initShader(myTDView);
}
/**
* Initialize shaders
* @param myTDView
*/
private void initShader(MyTDView myTDView) {
mVertexShader = ShaderUtil.loadFromAssetsFile("vertex.sh", myTDView.getResources());
mFragmentShader = ShaderUtil.loadFromAssetsFile("frag.sh", myTDView.getResources());
program = ShaderUtil.createProgram(mVertexShader, mFragmentShader);
maPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
maColorHandle = GLES20.glGetAttribLocation(program, "aColor");
muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
}
/**
* Draw triangle
*/
public void drawSelf() {
GLES20.glUseProgram(program);
Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0);// Initialize the transformation matrix
Matrix.translateM(mMMatrix, 0, 0, 0, 1);// Set along Z Positive displacement of shaft
Matrix.rotateM(mMMatrix, 0, xAngle, 1, 0, 0);// Set winding X Shaft rotation
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, Triangle.getFinalMatrix(mMMatrix), 0);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertexBuffer);
GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false, 4 * 4, mColorBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maColorHandle);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
/**
* Initialize vertex data
*/
private void initVertexData() {
vCount = 3;
final float UNIT_SIZE = 0.2f;// Set unit length
// An array of vertex coordinates
float vertices[] = new float[]{
-4 * UNIT_SIZE, 0, 0,
0, -4 * UNIT_SIZE, 0,
4 * UNIT_SIZE, 0, 0
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());// Set byte order to local operating system order
mVertexBuffer = vbb.asFloatBuffer();// Convert to floating-point buffer
mVertexBuffer.put(vertices);// Write data in the buffer
mVertexBuffer.position(0);// Set buffer start position
// Vertex color array
float colors[] = new float[]{
1, 1, 1, 0,
0, 0, 1, 0,
0, 1, 0, 0
};
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
}
/**
* The final transformation matrix
*
* @param spec
* @return
*/
public static float[] getFinalMatrix(float[] spec) {
// Initialize the total transformation matrix
mMvPMatrix = new float[16];
Matrix.multiplyMM(mMvPMatrix, 0, mVMatrix, 0, spec, 0);
Matrix.multiplyMM(mMvPMatrix, 0, mProjMatrix, 0, mMvPMatrix, 0);
return mMvPMatrix;
}
}
2.4 Rendering class MyTDView
GLSurfaceView and GLSurfaceView.Render Use
public class MyTDView extends GLSurfaceView {
private static final String TAG = "MyTDView";
// The angle of each triangle rotation
private final float ANGLE_SPAN = 0.375f;
// Threads
private RotateThread mRotateThread;
// Custom renderer
private SceneRenderer mSceneRenderer;
public MyTDView(Context context) {
super(context);
// Use OpenGLES2.0
this.setEGLContextClientVersion(2);
mSceneRenderer = new SceneRenderer();
this.setRenderer(mSceneRenderer);
this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
private class SceneRenderer implements GLSurfaceView.Renderer {
Triangle mTriangle;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0, 0, 0, 1.0f);// Set the screen background color
mTriangle = new Triangle(MyTDView.this);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
mRotateThread = new RotateThread();
mRotateThread.start();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);// Set up the viewport
float ratio = width / height;
// Set perspective projection
Matrix.frustumM(Triangle.mProjMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
// Set up the camera
Matrix.setLookAtM(Triangle.mVMatrix, 0, 0, 0, 3,
0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
mTriangle.drawSelf();
}
}
private class RotateThread extends Thread {
// Set the cycle identification bit
public boolean flag = true;
@Override
public void run() {
super.run();
while (flag) {
mSceneRenderer.mTriangle.xAngle = mSceneRenderer.mTriangle.xAngle + ANGLE_SPAN;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2.5 Vertex shader and slice shader code
Vertex shader and slice shader resources are placed in assets Under the table of contents . The following is used in this case :
2.5.1 frag.sh
precision mediump float;
varying vec4 vColor;
void main(){
gl_FragColor = vColor;
}
2.5.2 vertex.sh Vertex shader
uniform mat4 uMVPMatrix;// Total transformation matrix
attribute vec3 aPosition;// Vertex Position
attribute vec4 aColor;// Vertex color
varying vec4 vColor;// Mutable variables passed to the slice shader
void main(){
gl_Position = uMVPMatrix * vec4(aPosition,1);// Calculate the position of the vertex drawn this time according to the total transformation matrix
vColor = aColor;
}
2.6 other
public class MainActivity extends AppCompatActivity {
private MyTDView mTDView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mTDView = new MyTDView(this);
mTDView.requestFocus();
mTDView.setFocusableInTouchMode(true);
setContentView(mTDView);
}
@Override
protected void onResume() {
super.onResume();
mTDView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mTDView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
This sample program can be run directly , See the effect .
【 Reference resources 】
- https://www.khronos.org/opengles/
- 《OpenGL ES Application development practice guide Android volume Kevin Brothaler》
- https://en.wikipedia.org/wiki/OpenGL_ES
- https://developer.android.google.cn/guide/topics/graphics/opengl
- https://developer.android.google.cn/training/graphics/opengl
- Android3D Game development technology dictionary OpenGL ES 2.0
边栏推荐
- 简单描述 MySQL 中,索引,主键,唯一索引,联合索引 的区别,对数据库的性能有什么影响(从读写两方面)
- Latex文字加颜色的三种办法
- hydra常用命令
- BUU的MISC(不定时更新)
- [advanced software testing step 1] basic knowledge of automated testing
- ROS learning_ Basics
- 同事上了个厕所,我帮产品妹子轻松完成BI数据产品顺便得到奶茶奖励
- 呆错图床系统源码图片CDN加速与破解防盗链功能
- leetcode841. Keys and rooms (medium)
- Applied stochastic process 01: basic concepts of stochastic process
猜你喜欢

【每日一题】729. 我的日程安排表 I

Idea console color log

Misc of BUU (update from time to time)

Database basics exercise part 2

UWA pipeline version 2.2.1 update instructions

Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm

Thought map of data warehouse construction

树莓派串口登录与SSH登录方法

LeetCode 78:子集

leetcode704. Binary search (find an element, simple, different writing)
随机推荐
A brief introduction of reverseme in misc in the world of attack and defense
leetcode6109. 知道秘密的人数(中等,周赛)
UDP攻击是什么意思?UDP攻击防范措施
雲上有AI,讓地球科學研究更省力
Librosa audio processing tutorial
19. Actual memory management of segment page combination
微信脑力比拼答题小程序_支持流量主带最新题库文件
leetcode35. 搜索插入位置(简单,找插入位置,不同写法)
漏了监控:Zabbix对Eureka instance状态监控
指尖上的 NFT|在 G2 上评价 Ambire,有机会获得限量版收藏品
leetcode1020. 飞地的数量(中等)
idea控制台彩色日志
Depth residual network
Is it difficult for girls to learn software testing? The threshold for entry is low, and learning is relatively simple
win10 64位装三菱PLC软件出现oleaut32.dll拒绝访问
Uncaught TypeError: Cannot red propertites of undefined(reading ‘beforeEach‘)解决方案
PCL实现选框裁剪点云
Refer to how customer push e-commerce does content operation
同事上了个厕所,我帮产品妹子轻松完成BI数据产品顺便得到奶茶奖励
Fedora/rehl installation semanage