提交 b7a19da2 编写于 作者: 杨时权

【需求】提交opengl es教程代码。

上级 66bc260e
......@@ -17,6 +17,7 @@ import androidx.fragment.app.FragmentActivity;
import com.ly.avfoundation.fragment.CaptureFragment;
import com.ly.avfoundation.fragment.HomeFragment;
import com.ly.avfoundation.fragment.OpenGLESFragment;
public class MainActivity extends FragmentActivity implements View.OnClickListener {
private static final String TAG = "[MainActivity]";
......@@ -26,10 +27,11 @@ public class MainActivity extends FragmentActivity implements View.OnClickListen
private RelativeLayout mPlayerBtn;
private RelativeLayout mEditorBtn;
private final static int FRAGMENT_TYPE_HOME = 1;
private final static int FRAGMENT_TYPE_CAPTURE = 2;
private final static int FRAGMENT_TYPE_PLAYER = 3;
private final static int FRAGMENT_TYPE_EDITOR = 4;
private final static int FRAGMENT_TYPE_HOME = 1;
private final static int FRAGMENT_TYPE_CAPTURE = 2;
private final static int FRAGMENT_TYPE_PLAYER = 3;
private final static int FRAGMENT_TYPE_EDITOR = 4;
private final static int FRAGMENT_TYPE_OPENGLES = 5;
private int mFragmentType;
@Override
......@@ -76,6 +78,7 @@ public class MainActivity extends FragmentActivity implements View.OnClickListen
this.handleToCaptureFragment();
break;
case R.id.buttom_bar_btn_player:
this.handleToOpenGLESFragment();
break;
case R.id.buttom_bar_btn_editor:
break;
......@@ -112,6 +115,20 @@ public class MainActivity extends FragmentActivity implements View.OnClickListen
mFragmentType = FRAGMENT_TYPE_CAPTURE;
}
private void handleToOpenGLESFragment() {
if (mFragmentType == FRAGMENT_TYPE_OPENGLES) {
return;
}
Bundle saveInstanceState = new Bundle();
OpenGLESFragment fragment = OpenGLESFragment.newInstance(saveInstanceState);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.buttom_bar_main, fragment)
.commit();
mFragmentType = FRAGMENT_TYPE_OPENGLES;
}
@SuppressLint("WrongConstant")
public static boolean hasPermission(Context context, String permission) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED ||
......
package com.ly.avfoundation.avfoundation.gles;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class ESTransform {
public ESTransform() {
mMatrixFloatBuffer = ByteBuffer.allocateDirect(16 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
}
public void scale ( float sx, float sy, float sz ) {
mMatrix[0 * 4 + 0] *= sx;
mMatrix[0 * 4 + 1] *= sx;
mMatrix[0 * 4 + 2] *= sx;
mMatrix[0 * 4 + 3] *= sx;
mMatrix[1 * 4 + 0] *= sy;
mMatrix[1 * 4 + 1] *= sy;
mMatrix[1 * 4 + 2] *= sy;
mMatrix[1 * 4 + 3] *= sy;
mMatrix[2 * 4 + 0] *= sz;
mMatrix[2 * 4 + 1] *= sz;
mMatrix[2 * 4 + 2] *= sz;
mMatrix[2 * 4 + 3] *= sz;
}
public void translate(float tx, float ty, float tz) {
mMatrix[3 * 4 + 0] += ( mMatrix[0 * 4 + 0] * tx + mMatrix[1 * 4 + 0]
* ty + mMatrix[2 * 4 + 0] * tz );
mMatrix[3 * 4 + 1] += ( mMatrix[0 * 4 + 1] * tx + mMatrix[1 * 4 + 1]
* ty + mMatrix[2 * 4 + 1] * tz );
mMatrix[3 * 4 + 2] += ( mMatrix[0 * 4 + 2] * tx + mMatrix[1 * 4 + 2]
* ty + mMatrix[2 * 4 + 2] * tz );
mMatrix[3 * 4 + 3] += ( mMatrix[0 * 4 + 3] * tx + mMatrix[1 * 4 + 3]
* ty + mMatrix[2 * 4 + 3] * tz );
}
public void rotate (float angle, float x, float y, float z) {
float sinAngle, cosAngle;
float mag = (float) Math.sqrt ((double)(x * x + y * y + z * z));
sinAngle = (float) Math.sin ((double)(angle * Math.PI / 180.0));
cosAngle = (float) Math.cos ((double)(angle * Math.PI / 180.0));
if ( mag > 0.0f ) {
float xx, yy, zz, xy, yz, zx, xs, ys, zs;
float oneMinusCos;
float[] rotMat = new float[16];
x /= mag;
y /= mag;
z /= mag;
xx = x * x;
yy = y * y;
zz = z * z;
xy = x * y;
yz = y * z;
zx = z * x;
xs = x * sinAngle;
ys = y * sinAngle;
zs = z * sinAngle;
oneMinusCos = 1.0f - cosAngle;
rotMat[0 * 4 + 0] = ( oneMinusCos * xx ) + cosAngle;
rotMat[0 * 4 + 1] = ( oneMinusCos * xy ) - zs;
rotMat[0 * 4 + 2] = ( oneMinusCos * zx ) + ys;
rotMat[0 * 4 + 3] = 0.0F;
rotMat[1 * 4 + 0] = ( oneMinusCos * xy ) + zs;
rotMat[1 * 4 + 1] = ( oneMinusCos * yy ) + cosAngle;
rotMat[1 * 4 + 2] = ( oneMinusCos * yz ) - xs;
rotMat[1 * 4 + 3] = 0.0F;
rotMat[2 * 4 + 0] = ( oneMinusCos * zx ) - ys;
rotMat[2 * 4 + 1] = ( oneMinusCos * yz ) + xs;
rotMat[2 * 4 + 2] = ( oneMinusCos * zz ) + cosAngle;
rotMat[2 * 4 + 3] = 0.0F;
rotMat[3 * 4 + 0] = 0.0F;
rotMat[3 * 4 + 1] = 0.0F;
rotMat[3 * 4 + 2] = 0.0F;
rotMat[3 * 4 + 3] = 1.0F;
matrixMultiply ( rotMat, mMatrix );
}
}
public void frustum (float left, float right, float bottom, float top,
float nearZ, float farZ) {
float deltaX = right - left;
float deltaY = top - bottom;
float deltaZ = farZ - nearZ;
float[] frust = new float[16];
if ((nearZ <= 0.0f) || (farZ <= 0.0f) ||
(deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f)) {
return;
}
frust[0 * 4 + 0] = 2.0f * nearZ / deltaX;
frust[0 * 4 + 1] = frust[0 * 4 + 2] = frust[0 * 4 + 3] = 0.0f;
frust[1 * 4 + 1] = 2.0f * nearZ / deltaY;
frust[1 * 4 + 0] = frust[1 * 4 + 2] = frust[1 * 4 + 3] = 0.0f;
frust[2 * 4 + 0] = ( right + left ) / deltaX;
frust[2 * 4 + 1] = ( top + bottom ) / deltaY;
frust[2 * 4 + 2] = - ( nearZ + farZ ) / deltaZ;
frust[2 * 4 + 3] = -1.0f;
frust[3 * 4 + 2] = -2.0f * nearZ * farZ / deltaZ;
frust[3 * 4 + 0] = frust[3 * 4 + 1] = frust[3 * 4 + 3] = 0.0f;
matrixMultiply ( frust, mMatrix );
}
public void perspective (float fovy, float aspect, float nearZ, float farZ) {
float frustumW, frustumH;
frustumH = (float)Math.tan(fovy / 360.0 * Math.PI) * nearZ;
frustumW = frustumH * aspect;
frustum (-frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
}
public void ortho (float left, float right, float bottom, float top,
float nearZ, float farZ) {
float deltaX = right - left;
float deltaY = top - bottom;
float deltaZ = farZ - nearZ;
float[] orthoMat = makeIdentityMatrix();
if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f)) {
return;
}
orthoMat[0 * 4 + 0] = 2.0f / deltaX;
orthoMat[3 * 4 + 0] = - ( right + left ) / deltaX;
orthoMat[1 * 4 + 1] = 2.0f / deltaY;
orthoMat[3 * 4 + 1] = - ( top + bottom ) / deltaY;
orthoMat[2 * 4 + 2] = -2.0f / deltaZ;
orthoMat[3 * 4 + 2] = - ( nearZ + farZ ) / deltaZ;
matrixMultiply (orthoMat, mMatrix);
}
public void matrixMultiply (float[] srcA, float[] srcB) {
float[] tmp = new float[16];
int i;
for (i = 0; i < 4; i++) {
tmp[i * 4 + 0] = ( srcA[i * 4 + 0] * srcB[0 * 4 + 0] )
+ ( srcA[i * 4 + 1] * srcB[1 * 4 + 0] )
+ ( srcA[i * 4 + 2] * srcB[2 * 4 + 0] )
+ ( srcA[i * 4 + 3] * srcB[3 * 4 + 0] );
tmp[i * 4 + 1] = ( srcA[i * 4 + 0] * srcB[0 * 4 + 1] )
+ ( srcA[i * 4 + 1] * srcB[1 * 4 + 1] )
+ ( srcA[i * 4 + 2] * srcB[2 * 4 + 1] )
+ ( srcA[i * 4 + 3] * srcB[3 * 4 + 1] );
tmp[i * 4 + 2] = ( srcA[i * 4 + 0] * srcB[0 * 4 + 2] )
+ ( srcA[i * 4 + 1] * srcB[1 * 4 + 2] )
+ ( srcA[i * 4 + 2] * srcB[2 * 4 + 2] )
+ ( srcA[i * 4 + 3] * srcB[3 * 4 + 2] );
tmp[i * 4 + 3] = ( srcA[i * 4 + 0] * srcB[0 * 4 + 3] )
+ ( srcA[i * 4 + 1] * srcB[1 * 4 + 3] )
+ ( srcA[i * 4 + 2] * srcB[2 * 4 + 3] )
+ ( srcA[i * 4 + 3] * srcB[3 * 4 + 3] );
}
mMatrix = tmp;
}
public void matrixLoadIdentity() {
for ( int i = 0; i < 16; i++ ) {
mMatrix[i] = 0.0f;
}
mMatrix[0 * 4 + 0] = 1.0f;
mMatrix[1 * 4 + 1] = 1.0f;
mMatrix[2 * 4 + 2] = 1.0f;
mMatrix[3 * 4 + 3] = 1.0f;
}
private float[] makeIdentityMatrix() {
float[] result = new float[16];
for ( int i = 0; i < 16; i++ ) {
result[i] = 0.0f;
}
result[0 * 4 + 0] = 1.0f;
result[1 * 4 + 1] = 1.0f;
result[2 * 4 + 2] = 1.0f;
result[3 * 4 + 3] = 1.0f;
return result;
}
public FloatBuffer getAsFloatBuffer() {
mMatrixFloatBuffer.put ( mMatrix ).position ( 0 );
return mMatrixFloatBuffer;
}
public float[] get() {
return mMatrix;
}
private float[] mMatrix = new float[16];
private FloatBuffer mMatrixFloatBuffer;
}
package com.ly.avfoundation.avfoundation.gles;
import android.opengl.GLES20;
import android.opengl.GLES30;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
public class TextureWrapRenderer {
private static final String TAG = "[TextureWrapRenderer]";
private static final String vShaderStr =
"#version 300 es \n" +
"uniform float u_offset; \n" +
"layout(location = 0) in vec4 a_position; \n" +
"layout(location = 1) in vec2 a_texCoord; \n" +
"out vec2 v_texCoord; \n" +
"void main() \n" +
"{ \n" +
" gl_Position = a_position; \n" +
" gl_Position.x += u_offset; \n" +
" v_texCoord = a_texCoord; \n" +
"} \n";
private static final String fShaderStr =
"#version 300 es \n" +
"precision mediump float; \n" +
"in vec2 v_texCoord; \n" +
"layout(location = 0) out vec4 outColor; \n" +
"uniform sampler2D s_texture; \n" +
"void main() \n" +
"{ \n" +
" outColor = texture( s_texture, v_texCoord ); \n" +
"} \n";
public TextureWrapRenderer() {
mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
mVertices.put(mVerticesData).position(0);
mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
mIndices.put(mIndicesData).position(0);
mProgranObject = GLUtil.createProgram(vShaderStr, fShaderStr);
mSamplerLoc = GLES20.glGetUniformLocation(mProgranObject, "s_texture");
mOffsetLoc = GLES20.glGetUniformLocation(mProgranObject, "u_offset");
mTextureID = createTexture2D();
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
}
public void setScreenBounds(int x, int y, int width, int height) {
mWidth = width;
mHeight = height;
mOriginX = x;
mOriginY = y;
}
public void draw() {
GLES20.glViewport(mOriginX, mOriginY, mWidth, mHeight);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(mProgranObject);
mVertices.position(0);
GLES20.glVertexAttribPointer(0, 4, GLES20.GL_FLOAT, false, 6 * 4, mVertices);
mVertices.position(4);
GLES20.glVertexAttribPointer(1, 2, GLES20.GL_FLOAT, false, 6 * 4, mVertices);
GLES20.glEnableVertexAttribArray(0);
GLES20.glEnableVertexAttribArray(1);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
GLES20.glUniform1i(mSamplerLoc, 0);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
GLES20.glUniform1f(mOffsetLoc, -0.7f);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glUniform1f(mOffsetLoc, 0.0f);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_MIRRORED_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_MIRRORED_REPEAT);
GLES20.glUniform1f(mOffsetLoc, 0.7f);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices);
GLES20.glDisableVertexAttribArray(1);
GLES20.glDisableVertexAttribArray(0);
}
///
// Generate an RGB8 checkerboard image
//
private ByteBuffer genCheckImage ( int width, int height, int checkSize )
{
int x,
y;
byte[] pixels = new byte[width * height * 3];
for ( y = 0; y < height; y++ )
for ( x = 0; x < width; x++ )
{
byte rColor = 0;
byte bColor = 0;
if ( ( x / checkSize ) % 2 == 0 )
{
rColor = ( byte ) ( 127 * ( ( y / checkSize ) % 2 ) );
bColor = ( byte ) ( 127 * ( 1 - ( ( y / checkSize ) % 2 ) ) );
}
else
{
bColor = ( byte ) ( 127 * ( ( y / checkSize ) % 2 ) );
rColor = ( byte ) ( 127 * ( 1 - ( ( y / checkSize ) % 2 ) ) );
}
pixels[ ( y * width + x ) * 3] = rColor;
pixels[ ( y * width + x ) * 3 + 1] = 0;
pixels[ ( y * width + x ) * 3 + 2] = bColor;
}
ByteBuffer result = ByteBuffer.allocateDirect ( width * height * 3 );
result.put ( pixels ).position ( 0 );
return result;
}
///
// Create a 2D texture image
//
private int createTexture2D( )
{
// Texture object handle
int[] textureId = new int[1];
int width = 128, height = 128;
ByteBuffer pixels;
pixels = genCheckImage ( width, height, 64 );
// Generate a texture object
GLES20.glGenTextures ( 1, textureId, 0 );
// Bind the texture object
GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );
// Load mipmap level 0
GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, width, height,
0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, pixels );
// Set the filtering mode
GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
return textureId[0];
}
private int mProgranObject;
private int mSamplerLoc;
private int mOffsetLoc;
private int mTextureID;
private int mWidth;
private int mHeight;
private int mOriginX;
private int mOriginY;
private FloatBuffer mVertices;
private ShortBuffer mIndices;
private final float[] mVerticesData = {
-0.3f, 0.3f, 0.0f, 1.0f, // Position 0
-1.0f, -1.0f, // TexCoord 0
-0.3f, -0.3f, 0.0f, 1.0f, // Position 1
-1.0f, 2.0f, // TexCoord 1
0.3f, -0.3f, 0.0f, 1.0f, // Position 2
2.0f, 2.0f, // TexCoord 2
0.3f, 0.3f, 0.0f, 1.0f, // Position 3
2.0f, -1.0f // TexCoord 3
};
private final short[] mIndicesData = {
0, 1, 2, 0, 2, 3
};
}
package com.ly.avfoundation.avfoundation.gles;
import android.opengl.GLES20;
import android.os.SystemClock;
import android.util.Log;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
public class TriangleProgram {
private String TAG = GLUtil.TAG;
private static final String kVertexShaderSource =
"#version 300 es \n"
+ "uniform mat4 u_mvpMatrix; \n"
+ "layout(location = 0) in vec4 a_position; \n"
+ "layout(location = 1) in vec4 a_color; \n"
+ "out vec4 v_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = u_mvpMatrix * a_position; \n"
+ " v_color = a_color; \n"
+ "} \n";
private static final String kFragmentShaderSource =
"#version 300 es \n"
+ "precision mediump float; \n"
+ "in vec4 v_color; \n"
+ "out vec4 o_fragColor; \n"
+ "void main() \n"
+ "{ \n"
+ " o_fragColor = v_color; \n"
+ "} \n";
private static final byte[] kPixels = {
(byte)255, 0, 0,
0, (byte)255, 0,
0, 0, (byte)255,
(byte)255, (byte)255, 0,
};
private FloatBuffer mVertices;
private FloatBuffer mColor;
private ByteBuffer mIndexs;
private ByteBuffer mPixels;
private int mProgramHandler;
private int mPosition_X;
private int mPosition_Y;
private int mPosition_W;
private int mPosition_H;
private int mLocationPosition;
private int mLocationColor;
private int mLocationMVPMatrix;
private int mTextureID = -1;
public TriangleProgram() {
mProgramHandler = GLUtil.createProgram(kVertexShaderSource, kFragmentShaderSource);
mVertices = null;
mLocationPosition = GLES20.glGetAttribLocation(mProgramHandler, "a_position");
mLocationColor = GLES20.glGetAttribLocation(mProgramHandler, "a_color");
mLocationMVPMatrix = GLES20.glGetUniformLocation(mProgramHandler, "u_mvpMatrix");
mPixels = ByteBuffer.allocateDirect(kPixels.length).order(ByteOrder.nativeOrder()).put(kPixels);
mPixels.position(0);
int textures[] = new int[1];
GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1);
GLES20.glGenTextures(1, textures, 0);
mTextureID = textures[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 2, 2, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, mPixels);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
Log.i(TAG, "TriangleProgram color:" + mLocationColor + " position:" + mLocationPosition);
}
public void release() {
Log.d(TAG, "Triangle program release!!!");
GLES20.glDeleteProgram(mProgramHandler);
mProgramHandler = -1;
}
public void setScreenBounds(int x, int y, int w, int h) {
mPosition_X = x;
mPosition_Y = y;
mPosition_W = w;
mPosition_H = h;
}
public void draw() {
float color[] = { 1.0f, 0.0f, 0.0f, 1.0f};
byte indes[] = {
0, 1, 3, 0, 2, 3,
0, 1, 5, 0, 5, 4,
0, 2, 6, 0, 6, 4,
7, 5, 4, 7, 4, 6,
7, 5, 1, 7, 1, 3,
7, 3, 2, 7, 2, 6};
float vertexPos[] = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
};
this.update();
mColor = this.arrayToFloatBuffer(color);
mVertices = this.arrayToFloatBuffer(vertexPos);
mIndexs = ByteBuffer.allocateDirect(indes.length).order(ByteOrder.nativeOrder()).put(indes);
mIndexs.position(0);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glViewport(mPosition_X, mPosition_Y, mPosition_W, mPosition_H);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(mProgramHandler);
// GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
GLES20.glVertexAttrib4fv(mLocationColor, mColor);
GLES20.glVertexAttribPointer(mLocationPosition, 3, GLES20.GL_FLOAT, false, 0, mVertices);
GLES20.glEnableVertexAttribArray(mLocationPosition);
GLES20.glUniformMatrix4fv(mLocationMVPMatrix, 1, false, mMVPMatrix.getAsFloatBuffer());
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indes.length, GLES20.GL_UNSIGNED_BYTE, mIndexs);
GLES20.glDisableVertexAttribArray(mLocationPosition);
}
private FloatBuffer arrayToFloatBuffer(float vertex[]) {
ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer floatBuffer = bb.asFloatBuffer();
floatBuffer.put(vertex);
floatBuffer.position(0);
return floatBuffer;
}
private ShortBuffer arrayToShortBuffer(short array[]) {
ByteBuffer bb = ByteBuffer.allocateDirect(array.length * 2);
bb.order(ByteOrder.nativeOrder());
ShortBuffer shortBuffer = bb.asShortBuffer();
shortBuffer.put(array);
shortBuffer.position(0);
return shortBuffer;
}
private void update() {
if (mLastTime == 0)
mLastTime = SystemClock.uptimeMillis();
long curTime = SystemClock.uptimeMillis();
long elapsedTime = curTime - mLastTime;
double deltaTime = elapsedTime / 1000.0;
mLastTime = curTime;
ESTransform perspective = new ESTransform();
ESTransform modelView = new ESTransform();
float aspect;
mAngle += (deltaTime * 40.0f);
if (mAngle >= 360.0f)
mAngle -= 360.0f;
aspect = (float) mPosition_W / (float) mPosition_H;
perspective.matrixLoadIdentity();
perspective.perspective(60.0f, aspect, 0.1f, 20.0f);
modelView.matrixLoadIdentity();
modelView.translate(0.0f, 0.0f, -2.0f);
modelView.rotate(mAngle, 1.0f, 0.0f, 1.0f);
mMVPMatrix.matrixMultiply(modelView.get(), perspective.get());
}
private int [] mVBOIds = new int[2];
private final int VERTEX_POS_SIZE = 3;
private final int VERTEX_COLOR_SIZE = 4;
private final int VERTEX_POS_INDX = 0;
private final int VERTEX_COLOR_INDX = 1;
private final int VERTEX_STRIDE = ( 4 * ( VERTEX_POS_SIZE + VERTEX_COLOR_SIZE ) );
private ESTransform mMVPMatrix = new ESTransform();
private long mLastTime = 0;
private float mAngle = 90.0f;
}
package com.ly.avfoundation.avfoundation.render;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.ly.avfoundation.avfoundation.gles.TextureWrapRenderer;
import com.ly.avfoundation.avfoundation.gles.TriangleProgram;
import java.lang.ref.WeakReference;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class TriangleRender implements GLSurfaceView.Renderer {
private final static String TAG = "[TriangleRender]";
private TextureWrapRenderer mProgramHandler;
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
mProgramHandler = new TextureWrapRenderer();
Log.i(TAG, "onSurfaceCreated: " + eglConfig);
}
@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
Log.i(TAG, "onSurfaceChanged (" + width + "," + height + ");");
mProgramHandler.setScreenBounds(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl10) {
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
mProgramHandler.draw();
}
}
package com.ly.avfoundation.avfoundation.render;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import androidx.annotation.NonNull;
import com.ly.avfoundation.avfoundation.gles.EglCore;
import com.ly.avfoundation.avfoundation.gles.TextureWrapRenderer;
import com.ly.avfoundation.avfoundation.gles.TriangleProgram;
import com.ly.avfoundation.avfoundation.gles.WindowSurface;
import java.lang.ref.WeakReference;
public class TriangleRender2 implements SurfaceHolder.Callback, Runnable {
public static final String TAG = "[TriangleRender2]";
private EglCore mEGLCore;
private WindowSurface mWindowSurface;
private TriangleProgram mProgram;
private Handler mHandler = null;
private Thread mThread = null;
private boolean mInitialized = false;
private boolean mQuit;
public static final int MSG_SURFACE_CREATE = 0;
public static final int MSG_SURFACE_CHANGE = 1;
public static final int MSG_SURFACE_RENDER = 2;
public static final int MSG_SURFACE_DESTROY = 3;
public static class Bounds {
public int format;
public int width;
public int height;
public Bounds(int f, int w, int h) {
format = f;
width = w;
height = h;
}
@NonNull
@Override
public String toString() {
return "Bounds:{width:" + width + " height:" + height + " format:" + format + "};";
}
}
public TriangleRender2() {
mThread = new Thread(this);
mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SURFACE_CREATE:
handleSurfaceCreate((SurfaceHolder)msg.obj);
break;
case MSG_SURFACE_CHANGE:
handleSurfaceChange((Bounds)msg.obj);
break;
case MSG_SURFACE_RENDER:
handleSurfaceRende();
break;
case MSG_SURFACE_DESTROY:
handleSurfaceDestroy();
break;
}
return;
}
};
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
mQuit = false;
mThread.start();
mHandler.sendMessage(mHandler.obtainMessage(MSG_SURFACE_CREATE, surfaceHolder));
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int format, int width, int height) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_SURFACE_CHANGE, new Bounds(format, width, height)));
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
mQuit = true;
mHandler.sendMessage(mHandler.obtainMessage(MSG_SURFACE_DESTROY));
try {
mThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
// onDrawFrame
while (!mQuit) {
Log.i(TAG, "run: " + mQuit);
mHandler.sendMessage(mHandler.obtainMessage(MSG_SURFACE_RENDER));
}
}
public void handleSurfaceCreate(SurfaceHolder surfaceHolder) {
mEGLCore = new EglCore();
mWindowSurface = new WindowSurface(mEGLCore, surfaceHolder.getSurface(), false);
mWindowSurface.makeCurrent();
mProgram = new TriangleProgram();
Log.i(TAG, "handleSurfaceCreate " + mWindowSurface);
}
public void handleSurfaceChange(Bounds bounds) {
if (mProgram != null) {
mProgram.setScreenBounds(0, 0, bounds.width, bounds.height);
}
Log.i(TAG, "handleSurfaceChange " + bounds);
}
public void handleSurfaceRende() {
mWindowSurface.makeCurrent();
if (mProgram != null) {
mProgram.draw();
}
mWindowSurface.swapBuffers();
}
public void handleSurfaceDestroy() {
mProgram = null;
if (mWindowSurface != null) {
mWindowSurface.release();
}
if (mEGLCore != null) {
mEGLCore.release();
}
Log.i(TAG, "handleSurfaceDestroy");
}
}
package com.ly.avfoundation.fragment;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import com.ly.avfoundation.R;
import com.ly.avfoundation.avfoundation.render.TriangleRender;
import com.ly.avfoundation.avfoundation.render.TriangleRender2;
public class OpenGLESFragment extends Fragment {
private TriangleRender mRender;
private TriangleRender2 mRender2;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.opengles_fragment, group, false);
SurfaceView surfaceView = view.findViewById(R.id.surfaceView2);
mRender2 = new TriangleRender2();
surfaceView.getHolder().addCallback(mRender2);
surfaceView.setZOrderOnTop(true);
surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
return view;
}
public static OpenGLESFragment newInstance(Bundle saveInstanceState) {
OpenGLESFragment fragment = new OpenGLESFragment();
Bundle bundle = new Bundle();
fragment.setArguments(bundle);
return fragment;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surfaceView2"
android:layout_width="match_parent"
android:layout_height="357dp" />
</LinearLayout>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册