当前位置:网站首页>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
边栏推荐
- 巴比特 | 元宇宙每日必读:中国互联网企业涌入元宇宙的群像:“只有各种求生欲,没有前瞻创新的雄心”...
- UWA Pipeline 2.2.1 版本更新说明
- What is the biggest problem that fresh e-commerce is difficult to do now
- The psychological process from autojs to ice fox intelligent assistance
- WPF之MVVM
- pymongo获取一列数据
- The difference between get and post request types
- Map of mL: Based on the adult census income two classification prediction data set (whether the predicted annual income exceeds 50K), use the map value to realize the interpretable case of xgboost mod
- win10 64位装三菱PLC软件出现oleaut32.dll拒绝访问
- 首发织梦百度推送插件全自动收录优化seo收录模块
猜你喜欢

Explain in detail the functions and underlying implementation logic of the groups sets statement in SQL

Reflex WMS medium level series 3: display shipped replaceable groups

Due to high network costs, arbitrum Odyssey activities are suspended, and nitro release is imminent

顶测分享:想转行,这些问题一定要考虑清楚!

Setting and using richview trvstyle template style

Pallet management in SAP SD delivery process

首发织梦百度推送插件全自动收录优化seo收录模块

巴比特 | 元宇宙每日必读:中国互联网企业涌入元宇宙的群像:“只有各种求生欲,没有前瞻创新的雄心”...
![[brush questions] how can we correctly meet the interview?](/img/89/a5b874ba4db97fbb3d330af59c387a.png)
[brush questions] how can we correctly meet the interview?

18. Multi level page table and fast table
随机推荐
Introduction to ros2 installation and basic knowledge
Bitcoinwin (BCW): the lending platform Celsius conceals losses of 35000 eth or insolvency
Configure raspberry pie access network
19.段页结合的实际内存管理
Fedora/rehl installation semanage
同事上了个厕所,我帮产品妹子轻松完成BI数据产品顺便得到奶茶奖励
Call, apply, bind rewrite, easy to understand with comments
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
AI on the cloud makes earth science research easier
UniPro甘特图“初体验”:关注细节背后的多场景探索
Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm
[daily question] 729 My schedule I
Setting and using richview trvstyle template style
UWA Pipeline 2.2.1 版本更新说明
Establishment and operation of cloud platform open source project environment
PCL realizes frame selection and clipping point cloud
指尖上的 NFT|在 G2 上评价 Ambire,有机会获得限量版收藏品
After working for 10 years, I changed to a programmer. Now I'm 35 + years old and I'm not anxious
SEO学习的最好方式:搜索引擎
18. Multi level page table and fast table