内存释放函数
mEgl = (EGL10)EGLContext.getEGL();
mEgl.eglDestroyContext(mEglDisplay,mEglContext);
mEgl.eglDestroySurface(mEglDisplay,mEglSurface);
坐标和纹理
gl_Position为视图显示窗口的大小位置,纹理坐标是对图片等进行放大缩小等操作的
attribute vec4 vPosition;
attribute vec2 vCoordinate;
//java层传过来的纹理坐标
varying vec2 aCoordinate;
//java层传递的矩阵坐标
uniform mat4 vMatrix;
void main() {
//对在视图窗口进行变换,使它符合图片显示的大小和比例
vec4 aPos = vMatrix*vPosition;
gl_Position=aPos;
float scaleLevel = 0.4;
//对纹理进行放大,其实是显示40%的纹理
vec2 aCoord = vCoordinate*scaleLevel;
//纹理显示的时候由于放大了图片,为了居中显示,必须将偏移出的60%(偏移出屏幕的部分)的一半
//(上下,左右各占一半)偏移量计算上,若想要平移图片也可以在此改变
aCoordinate = (1.0-scaleLevel)/2.0+aCoord;
}
纹理变换
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform samplerExternalOES sTexture;
const vec3 monoMultiplier = vec3(0.299, 0.587, 0.114);
void main() {
vec4 color = texture2D(sTexture, vTextureCoord);
//第一个常量控制灰度和字体粗细 第二个常量是对比度 第三个常量控制亮度
gl_FragColor = vec4(((color.rgb - vec3(0.4)) * 1.15 + vec3(0.4)), color.w);
}
创建GLSL所需的变量和使用
//为GLSL代码创建一个名为vChangeType的变量,hChangeType为它的ID句柄
int hChangeType=GLES20.glGetUniformLocation(mProgram,"vChangeType");
int hChangeColor=GLES20.glGetUniformLocation(mProgram,"vChangeColor");
//为刚才创建好的变量赋值,并定义变量类型
GLES20.glUniform1i(hChangeType,filter.getType());
GLES20.glUniform3fv(hChangeColor,1,filter.data(),0);
初始化OpenGL ES 并初始化shader
大概流程为,获取一个顶点句柄和一个片元句柄(因为有了这两个shader才可以Link Program),将GLSL代码读取为String字符串,然后用glShaderSource方法将Sring代码加载到对应的shader句柄,然后对加载的代码进行编译,编译后判断是否编译成功,下来创建一个Program,将Program和2个Shader绑定,最后LinkProgram即可
GLES20.glClearColor(0f,0f,0f,0f);
String vertexSource = RawHelper.readRawFile(context,R.raw.vertex_shader);
String fragSource = RawHelper.readRawFile(context, R.raw.fragment_shader);
int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
int fragShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(vertexShader,vertexSource);
GLES20.glShaderSource(fragShader,fragSource);
int[] compileStatus = new int[1];
GLES20.glCompileShader(fragShader);
GLES20.glGetShaderiv(fragShader,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0]==0){
Log.e(TAG,"compile fragment shader source code error!");
return;
}
GLES20.glCompileShader(vertexShader);
GLES20.glGetShaderiv(vertexShader,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0]==0){
Log.e(TAG,"compile vertex shader source code error!");
return;
}
glProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(glProgram,vertexShader);
GLES20.glAttachShader(glProgram,fragShader);
GLES20.glLinkProgram(glProgram);
int[] linkStates = new int[1];
GLES20.glGetProgramiv(glProgram,GLES20.GL_LINK_STATUS,linkStates,0);
if(linkStates[0] == 0){
Log.e("onSurfaceCreated","link openGL source code error!");
return;
}
纹理绘制之glDrawElements
private static float[] shapeCoords = {
-1.0f, 1.0f, 0.0f, // top left
-1.0f, -1.0f, 0.0f, // bottom left
1.0f, -1.0f, 0.0f, // bottom right
1.0f, 1.0f, 0.0f }; // top right
//由于OPENGL ES只能绘制点 线 三角形,如果你想绘制一个长方形或正方形,那你就不得不画两个三角形了,
//下面的函数就是这个意思,绘制多个图形,例如三角形,则mDrawListBuffer里面肯定是3的倍数个点(三角
//形3个点),每3个点就是一个三角形,例如(0, 1, 2, 0, 2, 3)那么,021这3个点是三角形,023这3个
//点又组成一个三角形
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT,
mDrawListBuffer);
纹理绘制之glDrawArrays
/*绘制的方式有*/
int GL_POINTS //将传入的顶点坐标作为单独的点绘制
int GL_LINES //将传入的坐标作为单独线条绘制,ABCDEFG六个顶点,绘制AB、CD、EF三条线
int GL_LINE_STRIP //将传入的顶点作为折线绘制,ABCD四个顶点,绘制AB、BC、CD三条线
int GL_LINE_LOOP //将传入的顶点作为闭合折线绘制,ABCD四个顶点,绘制AB、BC、CD、DA四条线。
int GL_TRIANGLES //将传入的顶点作为单独的三角形绘制,ABCDEF绘制ABC,DEF两个三角形
int GL_TRIANGLE_FAN //将传入的顶点作为扇面绘制,ABCDEF绘制ABC、ACD、ADE、AEF四个三角形
int GL_TRIANGLE_STRIP //将传入的顶点作为三角条带绘制,ABCDEF绘制ABC,BCD,CDE,DEF四个三角形
opengl es2.0之Matrix.setLookAtM
这张图显示了相机观察物体的范围(蓝色区域)方向(VPN)
Matrix.setLookAtM(mViewMatrix, 0,
eyeX, eyeY, eyeZ, //相机坐标
lookX, lookY, lookZ, //目标坐标,与gl中的VPN是不一样的
upX, upY, upZ); //相机正上方向量VUV
/*其中mViewMatrix就是最后保存设置参数的矩阵*/