[OpenGL]从零开始写一个Android平台下的全景视频播放器——2.2 使用GLSurfaceView和MediaPlayer播放一个平面视频(中)
来源:互联网 发布:网络棋牌赚钱 编辑:程序博客网 时间:2024/06/14 06:44
回到目录
更新着色器代码
因为使用了,需要更新着色器代码 fragment_shader.glsl
#extension GL_OES_EGL_image_external : requireprecision mediump float;varying vec2 vTexCoord;uniform samplerExternalOES sTexture;void main() { gl_FragColor=texture2D(sTexture, vTexCoord);}
在这里,我们使用samplerExternalOES代替之前的sampler2D,需要注意的是第一行的注解是必须加上的
这个samplerExternalOES有什么用呢? 其实就是之前说的和surfaceTexture配合进行纹理更新和格式转换,具体的可以直接看OpenGL ES的官方文档,我截了一段供大家参考(估计也没什么人看。。):
vertex_shader.glsl
attribute vec4 aPosition;attribute vec4 aTexCoord;varying vec2 vTexCoord;uniform mat4 uMatrix;uniform mat4 uSTMatrix;void main() { vTexCoord = (uSTMatrix * aTexCoord).xy; gl_Position = uMatrix*aPosition;}
在顶点着色器中,需要加入对应的uSTMatrix,并且aTexCoord要改成长度为4的向量,以便于做乘法操作。
更新GLRenderer
在GLRenderer中,用类似的方法获取uSTMMatrixHandle
uSTMMatrixHandle = GLES20.glGetUniformLocation(programId, "uSTMatrix");
每次绘制的时候,将mSTMatrix用类似的方法传给OpenGL:
GLES20.glUniformMatrix4fv(uSTMMatrixHandle, 1, false, mSTMatrix, 0);
因为用了扩展纹理,所以我们绑定的纹理类型也要做修改:
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,textureId);
我们刚才只是设定了一个boolean来表示可以更新纹理了,却没有具体操作,所以在onDrawFrame最开始加入如下代码
synchronized (this){ if (updateSurface){ surfaceTexture.updateTexImage(); surfaceTexture.getTransformMatrix(mSTMatrix); updateSurface = false; }}
为了后续操作方便,我将绘制三角形的方式换成了绘制三角形带。
因为目前写的代码已经比较长了,我会在最后直接贴出GLRenderer的代码,如果遇到了什么问题,可以对照着看一下。
那我们来试一下吧,直接指定一个视频源,看看能不能正常显示(别忘了声明权限哦):
glSurfaceView.setRenderer(new GLRenderer(this, Environment.getExternalStorageDirectory().getPath()+"/360Video/video.mp4"));
这是一个2:1的全景视频,可以看到全景视频被压扁了,而且画面也是倒过来的,如果按一下HOME键,会发现视频并不会自己停止播放,我们会在下一节来解决屏幕尺寸适应和播放器生命周期的问题。
GLRenderer.java
package com.martin.ads.panoramaopengltutorial;import android.content.Context;import android.graphics.SurfaceTexture;import android.media.AudioManager;import android.media.MediaPlayer;import android.net.Uri;import android.opengl.GLES11Ext;import android.opengl.GLES20;import android.opengl.GLSurfaceView;import android.opengl.Matrix;import android.util.Log;import android.view.Surface;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.ShortBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;/** * Created by Ads on 2016/11/13. */public class GLRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener { private static final String TAG = "GLRenderer"; private Context context; private int aPositionHandle; private int programId; private FloatBuffer vertexBuffer; private final float[] vertexData = { 1f,1f,0f, -1f,1f,0f, 1f,-1f,0f, -1f,-1f,0f }; private final float[] projectionMatrix=new float[16]; private int uMatrixHandle; private final float[] textureVertexData = { 1f,0f, 0f,0f, 1f,1f, 0f,1f }; private FloatBuffer textureVertexBuffer; private int uTextureSamplerHandle; private int aTextureCoordHandle; private int textureId; private SurfaceTexture surfaceTexture; private MediaPlayer mediaPlayer; private float[] mSTMatrix = new float[16]; private int uSTMMatrixHandle; private boolean updateSurface; private boolean playerPrepared; private int screenWidth,screenHeight; public GLRenderer(Context context,String videoPath) { this.context = context; playerPrepared=false; synchronized(this) { updateSurface = false; } vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer() .put(vertexData); vertexBuffer.position(0); textureVertexBuffer = ByteBuffer.allocateDirect(textureVertexData.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer() .put(textureVertexData); textureVertexBuffer.position(0); mediaPlayer=new MediaPlayer(); try{ mediaPlayer.setDataSource(context, Uri.parse(videoPath)); }catch (IOException e){ e.printStackTrace(); } mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setLooping(true); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { String vertexShader = ShaderUtils.readRawTextFile(context, R.raw.vertex_shader); String fragmentShader= ShaderUtils.readRawTextFile(context, R.raw.fragment_shader); programId=ShaderUtils.createProgram(vertexShader,fragmentShader); aPositionHandle= GLES20.glGetAttribLocation(programId,"aPosition"); uMatrixHandle=GLES20.glGetUniformLocation(programId,"uMatrix"); uSTMMatrixHandle = GLES20.glGetUniformLocation(programId, "uSTMatrix"); uTextureSamplerHandle=GLES20.glGetUniformLocation(programId,"sTexture"); aTextureCoordHandle=GLES20.glGetAttribLocation(programId,"aTexCoord"); int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); textureId = textures[0]; GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); ShaderUtils.checkGlError("glBindTexture mTextureID"); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); surfaceTexture = new SurfaceTexture(textureId); surfaceTexture.setOnFrameAvailableListener(this); Surface surface = new Surface(surfaceTexture); mediaPlayer.setSurface(surface); surface.release(); if (!playerPrepared){ try { mediaPlayer.prepare(); playerPrepared=true; } catch (IOException t) { Log.e(TAG, "media player prepare failed"); } mediaPlayer.start(); playerPrepared=true; } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { screenWidth=width; screenHeight=height; float ratio=width>height? (float)width/height: (float)height/width; if (width>height){ Matrix.orthoM(projectionMatrix,0,-ratio,ratio,-1f,1f,-1f,1f); }else Matrix.orthoM(projectionMatrix,0,-1f,1f,-ratio,ratio,-1f,1f); } @Override public void onDrawFrame(GL10 gl) { GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); synchronized (this){ if (updateSurface){ surfaceTexture.updateTexImage(); surfaceTexture.getTransformMatrix(mSTMatrix); updateSurface = false; } } GLES20.glUseProgram(programId); GLES20.glUniformMatrix4fv(uMatrixHandle,1,false,projectionMatrix,0); GLES20.glUniformMatrix4fv(uSTMMatrixHandle, 1, false, mSTMatrix, 0); vertexBuffer.position(0); GLES20.glEnableVertexAttribArray(aPositionHandle); GLES20.glVertexAttribPointer(aPositionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer); textureVertexBuffer.position(0); GLES20.glEnableVertexAttribArray(aTextureCoordHandle); GLES20.glVertexAttribPointer(aTextureCoordHandle,2,GLES20.GL_FLOAT,false,8,textureVertexBuffer); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,textureId); GLES20.glUniform1i(uTextureSamplerHandle,0); GLES20.glViewport(0,0,screenWidth,screenHeight); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); } @Override synchronized public void onFrameAvailable(SurfaceTexture surface) { updateSurface = true; }}
阅读全文
0 0
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.2 使用GLSurfaceView和MediaPlayer播放一个平面视频(中)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.2 使用GLSurfaceView和MediaPlayer播放一个平面视频(中)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.3 使用GLSurfaceView和MediaPlayer播放一个平面视频(下)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.3 使用GLSurfaceView和MediaPlayer播放一个平面视频(下)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.1 使用GLSurfaceView和MediaPlayer播放一个平面视频(上)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.1 使用GLSurfaceView和MediaPlayer播放一个平面视频(上)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——5.8 使用MediaPlayer播放在线视频
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——目录
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——目录
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——5.1 使用OpenGL把全景视频贴到球上
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——5.6 播放器的UI制作
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.1 OpenGL ES 2.0基础知识
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——5.3 如何实现分屏效果
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——3.2 使用OpenGL ES 2.0绘制一个球
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——3.1 全景视频是如何实现的
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——5.7 使用OpenGL ES接口保存屏幕截图
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.4 用OpenGL ES 2.0显示一张图片(下)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.3 用OpenGL ES 2.0显示一张图片(上)
- 程序员终极Fish控制台
- Maven自动部署war到Tomcat8
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.1 使用GLSurfaceView和MediaPlayer播放一个平面视频(上)
- https认证
- Java mail
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.2 使用GLSurfaceView和MediaPlayer播放一个平面视频(中)
- 一个content-type引发的问题
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——2.3 使用GLSurfaceView和MediaPlayer播放一个平面视频(下)
- JavaScript DOM 编程艺术一书综合示例
- SerializeField和Serializable
- dp总结
- 设计模式之构造器模式(Builder)
- 用JS完成对表格的隔行换色
- vuejs 2.0