- <span style=<span class="string">“font-family:Comic Sans MS;font-size:18px;”</span>><span class="keyword">package</span> org.yanzi.camera.preview;
-
- <span class="keyword">import</span> java.nio.ByteBuffer;
- <span class="keyword">import</span> java.nio.ByteOrder;
- <span class="keyword">import</span> java.nio.FloatBuffer;
- <span class="keyword">import</span> java.nio.ShortBuffer;
-
- <span class="keyword">import</span> android.opengl.GLES11Ext;
- <span class="keyword">import</span> android.opengl.GLES20;
- <span class="keyword">import</span> android.opengl.Matrix;
-
- <span class="keyword">public</span> <span class="keyword">class</span> DirectDrawer {
- <span class="keyword">private</span> <span class="keyword">final</span> String vertexShaderCode =
- <span class="string">“attribute vec4 vPosition;”</span> +
- <span class="string">“attribute vec2 inputTextureCoordinate;”</span> +
- <span class="string">“varying vec2 textureCoordinate;”</span> +
- <span class="string">“void main()”</span> +
- <span class="string">“{“</span>+
- <span class="string">“gl_Position = vPosition;”</span>+
- <span class="string">“textureCoordinate = inputTextureCoordinate;”</span> +
- <span class="string">“}”</span>;
-
- <span class="keyword">private</span> <span class="keyword">final</span> String fragmentShaderCode =
- <span class="string">“#extension GL_OES_EGL_image_external : require\n”</span>+
- <span class="string">“precision mediump float;”</span> +
- <span class="string">“varying vec2 textureCoordinate;\n”</span> +
- <span class="string">“uniform samplerExternalOES s_texture;\n”</span> +
- <span class="string">“void main() {“</span> +
- <span class="string">” gl_FragColor = texture2D( s_texture, textureCoordinate );\n”</span> +
- <span class="string">“}”</span>;
-
- <span class="keyword">private</span> FloatBuffer vertexBuffer, textureVerticesBuffer;
- <span class="keyword">private</span> ShortBuffer drawListBuffer;
- <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">int</span> mProgram;
- <span class="keyword">private</span> <span class="keyword">int</span> mPositionHandle;
- <span class="keyword">private</span> <span class="keyword">int</span> mTextureCoordHandle;
-
- <span class="keyword">private</span> <span class="keyword">short</span> drawOrder[] = { <span class="number"></span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number"></span>, <span class="number">2</span>, <span class="number">3</span> }; <span class="comment">// order to draw vertices</span>
-
- <span class="comment">// number of coordinates per vertex in this array</span>
- <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> COORDS_PER_VERTEX = <span class="number">2</span>;
-
- <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">int</span> vertexStride = COORDS_PER_VERTEX * <span class="number">4</span>; <span class="comment">// 4 bytes per vertex</span>
-
- <span class="keyword">static</span> <span class="keyword">float</span> squareCoords[] = {
- –<span class="number">1</span>.0f, <span class="number">1</span>.0f,
- –<span class="number">1</span>.0f, –<span class="number">1</span>.0f,
- <span class="number">1</span>.0f, –<span class="number">1</span>.0f,
- <span class="number">1</span>.0f, <span class="number">1</span>.0f,
- };
-
- <span class="keyword">static</span> <span class="keyword">float</span> textureVertices[] = {
- <span class="number"></span>.0f, <span class="number">1</span>.0f,
- <span class="number">1</span>.0f, <span class="number">1</span>.0f,
- <span class="number">1</span>.0f, <span class="number"></span>.0f,
- <span class="number"></span>.0f, <span class="number"></span>.0f,
- };
-
- <span class="keyword">private</span> <span class="keyword">int</span> texture;
-
- <span class="keyword">public</span> DirectDrawer(<span class="keyword">int</span> texture)
- {
- <span class="keyword">this</span>.texture = texture;
- <span class="comment">// initialize vertex byte buffer for shape coordinates</span>
- ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * <span class="number">4</span>);
- bb.order(ByteOrder.nativeOrder());
- vertexBuffer = bb.asFloatBuffer();
- vertexBuffer.put(squareCoords);
- vertexBuffer.position(<span class="number"></span>);
-
- <span class="comment">// initialize byte buffer for the draw list</span>
- ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * <span class="number">2</span>);
- dlb.order(ByteOrder.nativeOrder());
- drawListBuffer = dlb.asShortBuffer();
- drawListBuffer.put(drawOrder);
- drawListBuffer.position(<span class="number"></span>);
-
- ByteBuffer bb2 = ByteBuffer.allocateDirect(textureVertices.length * <span class="number">4</span>);
- bb2.order(ByteOrder.nativeOrder());
- textureVerticesBuffer = bb2.asFloatBuffer();
- textureVerticesBuffer.put(textureVertices);
- textureVerticesBuffer.position(<span class="number"></span>);
-
- <span class="keyword">int</span> vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
- <span class="keyword">int</span> fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
-
- mProgram = GLES20.glCreateProgram(); <span class="comment">// create empty OpenGL ES Program</span>
- GLES20.glAttachShader(mProgram, vertexShader); <span class="comment">// add the vertex shader to program</span>
- GLES20.glAttachShader(mProgram, fragmentShader); <span class="comment">// add the fragment shader to program</span>
- GLES20.glLinkProgram(mProgram); <span class="comment">// creates OpenGL ES program executables</span>
- }
-
- <span class="keyword">public</span> <span class="keyword">void</span> draw(<span class="keyword">float</span>[] mtx)
- {
- GLES20.glUseProgram(mProgram);
-
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);
-
- <span class="comment">// get handle to vertex shader’s vPosition member</span>
- mPositionHandle = GLES20.glGetAttribLocation(mProgram, <span class="string">“vPosition”</span>);
-
- <span class="comment">// Enable a handle to the triangle vertices</span>
- GLES20.glEnableVertexAttribArray(mPositionHandle);
-
- <span class="comment">// Prepare the <insert shape here> coordinate data</span>
- GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, <span class="keyword">false</span>, vertexStride, vertexBuffer);
-
- mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, <span class="string">“inputTextureCoordinate”</span>);
- GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
-
- <span class="comment">// textureVerticesBuffer.clear();</span>
- <span class="comment">// textureVerticesBuffer.put( transformTextureCoordinates( textureVertices, mtx ));</span>
- <span class="comment">// textureVerticesBuffer.position(0);</span>
- GLES20.glVertexAttribPointer(mTextureCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, <span class="keyword">false</span>, vertexStride, textureVerticesBuffer);
-
- GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
-
- <span class="comment">// Disable vertex array</span>
- GLES20.glDisableVertexAttribArray(mPositionHandle);
- GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
- }
-
- <span class="keyword">private</span> <span class="keyword">int</span> loadShader(<span class="keyword">int</span> type, String shaderCode){
-
- <span class="comment">// create a vertex shader type (GLES20.GL_VERTEX_SHADER)</span>
- <span class="comment">// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)</span>
- <span class="keyword">int</span> shader = GLES20.glCreateShader(type);
-
- <span class="comment">// add the source code to the shader and compile it</span>
- GLES20.glShaderSource(shader, shaderCode);
- GLES20.glCompileShader(shader);
-
- <span class="keyword">return</span> shader;
- }
- <span class="keyword">private</span> <span class="keyword">float</span>[] transformTextureCoordinates( <span class="keyword">float</span>[] coords, <span class="keyword">float</span>[] matrix)
- {
- <span class="keyword">float</span>[] result = <span class="keyword">new</span> <span class="keyword">float</span>[ coords.length ];
- <span class="keyword">float</span>[] vt = <span class="keyword">new</span> <span class="keyword">float</span>[<span class="number">4</span>];
-
- <span class="keyword">for</span> ( <span class="keyword">int</span> i = <span class="number"></span> ; i < coords.length ; i += <span class="number">2</span> ) {
- <span class="keyword">float</span>[] v = { coords[i], coords[i+<span class="number">1</span>], <span class="number"></span> , <span class="number">1</span> };
- Matrix.multiplyMV(vt, <span class="number"></span>, matrix, <span class="number"></span>, v, <span class="number"></span>);
- result[i] = vt[<span class="number"></span>];
- result[i+<span class="number">1</span>] = vt[<span class="number">1</span>];
- }
- <span class="keyword">return</span> result;
- }
- }
- </span>
三、有了上面两个类就完成95%的工作,可以将GLSurfaceView看成是有生命周期的。在onPause里进行关闭Camera,在Activity里复写两个方法:
- <span style=<span class="string">“font-family:Comic Sans MS;font-size:18px;”</span>> <span class="annotation">@Override</span>
- <span class="keyword">protected</span> <span class="keyword">void</span> onResume() {
- <span class="comment">// TODO Auto-generated method stub</span>
- <span class="keyword">super</span>.onResume();
- glSurfaceView.bringToFront();
- }
-
- <span class="annotation">@Override</span>
- <span class="keyword">protected</span> <span class="keyword">void</span> onPause() {
- <span class="comment">// TODO Auto-generated method stub</span>
- <span class="keyword">super</span>.onPause();
- glSurfaceView.onPause();
- }</span>
这个glSurfaceView.bringToFront();其实不写也中。在布局里写入自定义的GLSurfaceView就ok了:
- <span class="tag"><</span><span class="tag-name">span</span> <span class="attribute">style</span>=<span class="attribute-value">“font-family:Comic Sans MS;font-size:18px;”</span><span class="tag">></span> <span class="tag"><</span><span class="tag-name">FrameLayout</span>
- <span class="attribute">android:layout_width</span>=<span class="attribute-value">“wrap_content”</span>
- <span class="attribute">android:layout_height</span>=<span class="attribute-value">“wrap_content”</span> <span class="tag">></span>
- <span class="tag"><</span><span class="tag-name">org.yanzi.camera.preview.CameraGLSurfaceView</span>
- <span class="attribute">android:id</span>=<span class="attribute-value">“@+id/camera_textureview”</span>
- <span class="attribute">android:layout_width</span>=<span class="attribute-value">“0dip”</span>
- <span class="attribute">android:layout_height</span>=<span class="attribute-value">“0dip”</span> <span class="tag">/></span>
- <span class="tag"></</span><span class="tag-name">FrameLayout</span><span class="tag">></span><span class="tag"></</span><span class="tag-name">span</span><span class="tag">></span>
CameraActivity里只负责UI部分,CameraGLSurfaceView负责开Camera、预览,并调用DirectDrawer里的draw()进行绘制。其他代码就不上了。
注意事项:
1、**在onDrawFrame()里,如果不调用mDirectDrawer.draw(mtx);是啥都显示不出来的!!!**这是GLSurfaceView的特别之处。为啥呢?因为GLSurfaceView不是Android亲生的,而Surfaceview和TextureView是。所以得自己按照OpenGL ES的流程画。
2、究竟 mDirectDrawer.draw(mtx)里在哪获取的Buffer目前杂家还么看太明白,貌似么有请求buffer,而是根据 GLSurfaceView里创建的SurfaceTexture之前,生成的有个纹理ID。这个纹理ID一方面跟SurfaceTexture是绑定在 一起的,另一方面跟DirectDrawer绑定,而SurfaceTexture作渲染载体。
3、参考链接 里有,有人为了解决问题,给出了下面三段代码:
@Override
public void onDrawFrame(GL10 gl)
{
float[] mtx = new float[16];
mSurface.updateTexImage();
mSurface.getTransformMatrix(mtx);
mDirectVideo.draw(mtx);
}
private float[] transformTextureCoordinates( float[] coords, float[] matrix)
{
float[] result = new float[ coords.length ];
float[] vt = new float[4];
for ( int i = 0 ; i < coords.length ; i += 2 ) {
float[] v = { coords[i], coords[i+1], 0 , 1 };
Matrix.multiplyMV(vt, 0, matrix, 0, v, 0);
result[i] = vt[0];
result[i+1] = vt[1];
}
return result;
}
textureVerticesBuffer.clear();
textureVerticesBuffer.put( transformTextureCoordinates( textureVertices, mtx ));
textureVerticesBuffer.position(0);
我已经把代码都融入到了此demo,只不过在draw()方法里么有使用。原因是使用之后,得到的预览画面反而是变形的,而不用的话是ok的。上面的代码是得到SurfaceTexture的变换矩阵:mSurface.getTransformMatrix
然后将此矩阵传递给draw(),在draw的时候对textureVerticesBuffer作一个变化,然后再画。
下图是未加这个矩阵变换效果时:
下图为使用了变换矩阵,划片扭曲的还真说不上来咋扭曲的,但足以说明OpenGL ES在渲染效果上的强大,就是设置了个矩阵,不用一帧帧处理,就能得到不一样显示效果。
—————————–本文系原创,转载请注明作者yanzi1225627
版本号:PlayCamera_V3.0.0[2014-6-22].zip
CSDN下载链接:http://download.csdn.net/detail/yanzi1225627/7547263
百度云盘:
附个OpenGL ES简明教程:http://www.apkbus.com/android-20427-1-1.html
转自:
http://blog.csdn.net/yanzi1225627/article/details/33339965
💬 评论