public static int loadShader(int type, string shaderCode) { int shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, shaderCode); GLES20.glCompileShader(shader); return(shader); }
public override void onDrawFrame(GL10 gl) { mFrameLock.@lock(); if (mCurrentFrame != null && !mVideoDisabled) { GLES20.glUseProgram(mProgram); if (mTextureWidth != mCurrentFrame.Width || mTextureHeight != mCurrentFrame.Height) { setupTextures(mCurrentFrame); } updateTextures(mCurrentFrame); Matrix.setIdentityM(mScaleMatrix, 0); float scaleX = 1.0f, scaleY = 1.0f; float ratio = (float)mCurrentFrame.Width / mCurrentFrame.Height; float vratio = (float)mViewportWidth / mViewportHeight; if (mVideoFitEnabled) { if (ratio > vratio) { scaleY = vratio / ratio; } else { scaleX = ratio / vratio; } } else { if (ratio < vratio) { scaleY = vratio / ratio; } else { scaleX = ratio / vratio; } } Matrix.scaleM(mScaleMatrix, 0, scaleX * (mCurrentFrame.MirroredX ? -1.0f : 1.0f), scaleY, 1); int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mScaleMatrix, 0); GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.Length, GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer); } else { //black frame when video is disabled gl.glClearColor(0, 0, 0, 1); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } mFrameLock.unlock(); }
internal static void initializeTexture(int name, int id, int width, int height) { GLES20.glActiveTexture(name); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, width, height, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, null); }
public override void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glClearColor(0, 0, 0, 1); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES // Program GLES20.glAttachShader(mProgram, vertexShader); // add the vertex // shader to program GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment // shader to // program GLES20.glLinkProgram(mProgram); int positionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); int textureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord"); GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, mVertexBuffer); GLES20.glEnableVertexAttribArray(positionHandle); GLES20.glVertexAttribPointer(textureHandle, TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer); GLES20.glEnableVertexAttribArray(textureHandle); GLES20.glUseProgram(mProgram); int i = GLES20.glGetUniformLocation(mProgram, "Ytex"); GLES20.glUniform1i(i, 0); // Bind Ytex to texture unit 0 i = GLES20.glGetUniformLocation(mProgram, "Utex"); GLES20.glUniform1i(i, 1); // Bind Utex to texture unit 1 i = GLES20.glGetUniformLocation(mProgram, "Vtex"); GLES20.glUniform1i(i, 2); // Bind Vtex to texture unit 2 mTextureWidth = 0; mTextureHeight = 0; }
internal virtual void updateTextures(Frame frame) { int width = frame.Width; int height = frame.Height; int half_width = (width + 1) >> 1; int half_height = (height + 1) >> 1; int y_size = width * height; int uv_size = half_width * half_height; ByteBuffer bb = frame.Buffer; // If we are reusing this frame, make sure we reset position and // limit bb.clear(); if (bb.remaining() == y_size + uv_size * 2) { bb.position(0); GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]); GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, bb); bb.position(y_size); GLES20.glActiveTexture(GLES20.GL_TEXTURE1); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]); GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, half_width, half_height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, bb); bb.position(y_size + uv_size); GLES20.glActiveTexture(GLES20.GL_TEXTURE2); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]); GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, half_width, half_height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, bb); } else { mTextureWidth = 0; mTextureHeight = 0; } }
internal virtual void setupTextures(Frame frame) { if (mTextureIds[0] != 0) { GLES20.glDeleteTextures(3, mTextureIds, 0); } GLES20.glGenTextures(3, mTextureIds, 0); int w = frame.Width; int h = frame.Height; int hw = (w + 1) >> 1; int hh = (h + 1) >> 1; initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h); initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh); initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh); mTextureWidth = frame.Width; mTextureHeight = frame.Height; }
public override void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0, 0, width, height); mViewportWidth = width; mViewportHeight = height; }