当前位置:网站首页>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
边栏推荐
- Setting and using richview trvstyle template style
- win10 64位装三菱PLC软件出现oleaut32.dll拒绝访问
- 作者已死?AI正用艺术征服人类
- Depth residual network
- Visitor tweets about how you can layout the metauniverse
- LeetCode 78:子集
- UniPro甘特图“初体验”:关注细节背后的多场景探索
- Is it difficult for girls to learn software testing? The threshold for entry is low, and learning is relatively simple
- Proteus -- Serial Communication parity flag mode
- UDP攻击是什么意思?UDP攻击防范措施
猜你喜欢
UWA pipeline version 2.2.1 update instructions
A method to measure the similarity of time series: from Euclidean distance to DTW and its variants
Windows Server 2016 standard installing Oracle
The first Baidu push plug-in of dream weaving fully automatic collection Optimization SEO collection module
Huawei equipment configuration ospf-bgp linkage
C语言_双创建、前插,尾插,遍历,删除
雲上有AI,讓地球科學研究更省力
L'Ia dans les nuages rend la recherche géoscientifique plus facile
Misc of BUU (update from time to time)
leetcode704. Binary search (find an element, simple, different writing)
随机推荐
A brief introduction of reverseme in misc in the world of attack and defense
When my colleague went to the bathroom, I helped my product sister easily complete the BI data product and got a milk tea reward
leetcode1020. Number of enclaves (medium)
Simple use of JWT
librosa音频处理教程
漏了监控:Zabbix对Eureka instance状态监控
18.多级页表与快表
Brief introduction to the curriculum differences of colleges and universities at different levels of machine human major -ros1/ros2-
BUU的MISC(不定时更新)
Explain in detail the functions and underlying implementation logic of the groups sets statement in SQL
AI on the cloud makes earth science research easier
leetcode841. Keys and rooms (medium)
ROS学习_基础
Bitcoinwin (BCW): the lending platform Celsius conceals losses of 35000 eth or insolvency
Apache dolphin scheduler source code analysis (super detailed)
A method to measure the similarity of time series: from Euclidean distance to DTW and its variants
Attributeerror: can 't get attribute' sppf 'on < module' models. Common 'from' / home / yolov5 / Models / comm
win10 64位装三菱PLC软件出现oleaut32.dll拒绝访问
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
Bio model realizes multi person chat