Last active
February 21, 2023 12:29
-
-
Save DastanIqbal/12a05f12b21b29d26455a1226ae7d6a3 to your computer and use it in GitHub Desktop.
Simple example of Frame Buffer Object in OpenglES
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<android.opengl.GLSurfaceView | |
android:id="@+id/glsurfaceview" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<android.support.v7.widget.RecyclerView | |
android:id="@+id/rv" | |
android:layout_width="match_parent" | |
android:layout_height="150dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintStart_toStartOf="parent" /> | |
</android.support.constraint.ConstraintLayout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.iaandroid.tutsopengles.fbo | |
import android.graphics.BitmapFactory | |
import android.opengl.GLSurfaceView | |
import com.iaandroid.tutsopengles.R | |
import javax.microedition.khronos.egl.EGLConfig | |
import javax.microedition.khronos.opengles.GL10 | |
/** | |
* Created by dastan on 11/09/2018. | |
* [email protected] | |
* 11/09/2018 10:06 | |
*/ | |
class EZRenderer(val glSurfaceView: GLSurfaceView) : GLSurfaceView.Renderer { | |
private val glRender = SimpleFBORender() | |
override fun onDrawFrame(gl: GL10?) { | |
glRender.onDrawFrame() | |
} | |
override fun onSurfaceChanged(gl: GL10?, w: Int, h: Int) { | |
glRender.setRenderSize(w, h) | |
} | |
override fun onSurfaceCreated(gl: GL10?, p1: EGLConfig?) { | |
glRender.initHandlers(BitmapFactory.decodeResource(glSurfaceView.resources, R.mipmap.ic_launcher)) | |
glRender.initFBO() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.iaandroid.tutsopengles.frames | |
import android.app.Activity | |
import android.content.Context | |
import android.opengl.GLSurfaceView | |
import android.os.Bundle | |
import android.support.v7.widget.LinearLayoutManager | |
import android.support.v7.widget.RecyclerView | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.view.Window | |
import android.widget.TextView | |
import com.dastanapps.mediasdk.opengles.gpu.FBORender | |
import com.dastanapps.mediasdk.opengles.gpu.ImageRenderer | |
import com.dastanapps.mediasdk.opengles.gpu.fbo.RTTRenderer | |
import com.dastanapps.mediasdk.opengles.gpu.filter.ImageFilter | |
import com.dastanapps.mediasdk.opengles.gpu.filter.InvertColorFilter | |
import com.dastanapps.mediasdk.opengles.gpu.filter.NoneFilter | |
import com.dastanapps.mediasdk.opengles.gpu.filter.SharpenFilter | |
import com.iaandroid.tutsopengles.R | |
import com.iaandroid.tutsopengles.fbo.EZRenderer | |
import kotlinx.android.synthetic.main.activity_frames.* | |
/** | |
* Created by dastan on 05/09/2018. | |
* [email protected] | |
* 05/09/2018 11:23 | |
*/ | |
class FramesActivity : Activity() { | |
private val glSurfaceView: GLSurfaceView by lazy { | |
findViewById<GLSurfaceView>(R.id.glsurfaceview) | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
requestWindowFeature(Window.FEATURE_NO_TITLE) | |
setContentView(R.layout.activity_frames) | |
glSurfaceView.setEGLContextClientVersion(2) | |
glSurfaceView.setRenderer(EZRenderer(glSurfaceView)) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.iaandroid.tutsopengles.fbo | |
import android.graphics.Bitmap | |
import android.opengl.GLES20 | |
import com.dastanapps.mediasdk.opengles.gpu.OpenGlUtils | |
import java.nio.ByteBuffer | |
import java.nio.ByteOrder | |
import java.nio.FloatBuffer | |
/** | |
* Reference : http://opengles2learning.blogspot.com/2014/02/render-to-texture-rtt.html?m=1 | |
*/ | |
class SimpleFBORender { | |
protected var mVertexShader = DEFAULT_VERTEX_SHADER | |
protected var mFragmentShader = DEFAULT_FRAGMENT_SHADER | |
protected lateinit var mWorldVertices: FloatBuffer | |
protected lateinit var mTextureVertices: FloatBuffer | |
@JvmField | |
protected var mProgramHandle: Int = 0 | |
protected var mVertexShaderHandle: Int = 0 | |
protected var mFragmentShaderHandle: Int = 0 | |
protected var mTextureHandle: Int = 0 | |
protected var mPositionHandle: Int = 0 | |
protected var mTextureCoordHandle: Int = 0 | |
protected var mTextureIn: Int = 0 | |
init { | |
val vertices = floatArrayOf(-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f) | |
mWorldVertices = ByteBuffer.allocateDirect(vertices.size * 4) | |
.order(ByteOrder.nativeOrder()).asFloatBuffer() | |
mWorldVertices.put(vertices).position(0) | |
val texData0 = floatArrayOf(0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f) | |
mTextureVertices = ByteBuffer.allocateDirect(texData0.size * 4) | |
.order(ByteOrder.nativeOrder()).asFloatBuffer() | |
mTextureVertices.put(texData0)?.position(0) | |
} | |
fun initHandlers(bitmap: Bitmap) { | |
mProgramHandle = com.raywenderlich.GLUtils.loadProgram(mVertexShader, mFragmentShader) | |
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, ATTRIBUTE_POSITION) | |
mTextureCoordHandle = GLES20.glGetAttribLocation(mProgramHandle, ATTRIBUTE_TEXTURE_COORD) | |
mTextureHandle = GLES20.glGetUniformLocation(mProgramHandle, UNIFORM_TEXTURE_0) | |
mTextureIn = OpenGlUtils.loadTexture(bitmap, mTextureIn, true) | |
} | |
private val mRenderToTextureFBO = IntArray(1) | |
val mFBOTextureR = IntArray(1) | |
val mRenderBufferFBO = IntArray(1) | |
fun initFBO() { | |
GLES20.glGenTextures(1, mFBOTextureR, 0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFBOTextureR[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.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR) | |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST) | |
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 256, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null) | |
GLES20.glGenFramebuffers(1, mRenderToTextureFBO, 0) | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mRenderToTextureFBO[0]) | |
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFBOTextureR[0], 0) | |
GLES20.glGenRenderbuffers(1, mRenderBufferFBO, 0) | |
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, mRenderBufferFBO[0]) | |
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, 256, 256) | |
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, mRenderBufferFBO[0]) | |
/** Check FBO is complete and OK */ | |
val iResult = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER) | |
if (iResult != GLES20.GL_FRAMEBUFFER_COMPLETE) { | |
throw RuntimeException("Error: Frame Buffer Status is not complete. Terminated.") | |
} | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) | |
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0) | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0) | |
} | |
private var mWidth: Int = 0 | |
private var mHeight: Int = 0 | |
fun setRenderSize(width: Int, height: Int) { | |
mWidth = width | |
mHeight = height | |
GLES20.glViewport(0, 0, width, height) | |
} | |
fun onDrawFrame() { | |
prepareFBOTexture() | |
/**=========================================**/ | |
useFBOTexture() | |
} | |
fun useFBOTexture() { | |
/** Use blue background color */ | |
GLES20.glClearColor(0.0f, 0.2f, 0.3f, 1.0f) | |
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT) | |
GLES20.glViewport(0, 0, mWidth, mHeight) | |
GLES20.glUseProgram(mProgramHandle) | |
mWorldVertices.position(0) | |
GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false, 8, mWorldVertices) | |
GLES20.glEnableVertexAttribArray(mPositionHandle) | |
mTextureVertices.position(0) | |
GLES20.glVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GL_FLOAT, false, 8, mTextureVertices) | |
GLES20.glEnableVertexAttribArray(mTextureCoordHandle) | |
GLES20.glActiveTexture(GLES20.GL_TEXTURE0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFBOTextureR[0]) | |
GLES20.glUniform1i(mTextureHandle, 0) | |
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) | |
} | |
fun prepareFBOTexture() { | |
/** Enable frame buffer to start rendering into it */ | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mRenderToTextureFBO[0]) | |
/** Create an Orange back ground */ | |
GLES20.glClearColor(1.0f, 0.5f, 0.0f, 1.0f) | |
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT) | |
GLES20.glViewport(0, 0, 256, 256) | |
GLES20.glUseProgram(mProgramHandle) | |
mWorldVertices.position(0) | |
GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false, 8, mWorldVertices) | |
GLES20.glEnableVertexAttribArray(mPositionHandle) | |
mTextureVertices.position(0) | |
GLES20.glVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GL_FLOAT, false, 8, mTextureVertices) | |
GLES20.glEnableVertexAttribArray(mTextureCoordHandle) | |
/** set the Texture unit 0 active and bind the texture to it */ | |
GLES20.glActiveTexture(GLES20.GL_TEXTURE0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIn) | |
GLES20.glUniform1i(mTextureHandle, 0) | |
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); | |
} | |
companion object { | |
val ATTRIBUTE_POSITION = "position" | |
val ATTRIBUTE_TEXTURE_COORD = "inputTextureCoordinate" | |
val VARYING_TEXTURE_COORD = "textureCoordinate" | |
val UNIFORM_TEXTURE = "inputImageTexture" | |
val UNIFORM_TEXTURE_0 = UNIFORM_TEXTURE | |
@JvmField | |
var DEFAULT_VERTEX_SHADER = ("attribute vec4 " + ATTRIBUTE_POSITION + ";\n" | |
+ "attribute vec2 " + ATTRIBUTE_TEXTURE_COORD + ";\n" | |
+ "varying vec2 " + VARYING_TEXTURE_COORD + ";\n" | |
+ "void main() {\n" | |
+ " " + VARYING_TEXTURE_COORD + " = " + ATTRIBUTE_TEXTURE_COORD + ";\n" | |
+ " gl_Position = " + ATTRIBUTE_POSITION + ";\n" | |
+ "}\n") | |
var DEFAULT_FRAGMENT_SHADER = ("precision mediump float;\n" | |
+ "uniform sampler2D " + UNIFORM_TEXTURE_0 + ";\n" | |
+ "varying vec2 " + VARYING_TEXTURE_COORD + ";\n" | |
+ "void main(){\n" | |
+ " gl_FragColor = texture2D(" + UNIFORM_TEXTURE_0 + "," + VARYING_TEXTURE_COORD + ")" + ";\n" | |
+ "}\n") | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.iaandroid.tutsopengles.fbo | |
import android.content.Context | |
import android.graphics.Bitmap | |
import android.graphics.BitmapFactory | |
import android.opengl.GLES20 | |
import android.opengl.GLUtils | |
import android.text.TextUtils | |
import com.dastanapps.mediasdk.opengles.gpu.fbo.LruBitmapCache | |
import java.io.IOException | |
import java.io.InputStream | |
import java.nio.ByteBuffer | |
import java.nio.ByteOrder | |
import java.nio.FloatBuffer | |
import java.util.* | |
/** | |
* References : | |
* http://opengles2learning.blogspot.com/2014/02/render-to-texture-rtt.html?m=1 | |
* https://github.com/uestccokey/EZFilter | |
*/ | |
class SimpleFBORender2(val context: Context) { | |
protected var mVertexShader = DEFAULT_VERTEX_SHADER | |
protected var mFragmentShader = DEFAULT_FRAGMENT_SHADER | |
protected var mWorldVertices: FloatBuffer | |
protected var mTextureVertices: FloatBuffer | |
@JvmField | |
protected var mProgramHandle: Int = 0 | |
protected var mVertexShaderHandle: Int = 0 | |
protected var mFragmentShaderHandle: Int = 0 | |
protected var mTextureHandle: Int = 0 | |
protected var mPositionHandle: Int = 0 | |
protected var mTextureCoordHandle: Int = 0 | |
protected var mTextureIn: Int = 0 | |
internal var paths: MutableList<String> = ArrayList() | |
init { | |
val vertices = floatArrayOf(-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f) | |
mWorldVertices = ByteBuffer.allocateDirect(vertices.size * 4) | |
.order(ByteOrder.nativeOrder()).asFloatBuffer() | |
mWorldVertices.put(vertices).position(0) | |
val texData0 = floatArrayOf(0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f) | |
mTextureVertices = ByteBuffer.allocateDirect(texData0.size * 4) | |
.order(ByteOrder.nativeOrder()).asFloatBuffer() | |
mTextureVertices.put(texData0)?.position(0) | |
paths.addAll(convert(context, "lear")) | |
} | |
fun initHandlers(bitmap: Bitmap) { | |
mProgramHandle = com.raywenderlich.GLUtils.loadProgram(mVertexShader, mFragmentShader) | |
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, ATTRIBUTE_POSITION) | |
mTextureCoordHandle = GLES20.glGetAttribLocation(mProgramHandle, ATTRIBUTE_TEXTURE_COORD) | |
mTextureHandle = GLES20.glGetUniformLocation(mProgramHandle, UNIFORM_TEXTURE_0) | |
//mTextureIn = OpenGlUtils.loadTexture(bitmap, mTextureIn, true) | |
} | |
private val mRenderToTextureFBO = IntArray(1) | |
val mFBOTextureR = IntArray(1) | |
val mRenderBufferFBO = IntArray(1) | |
fun initFBO() { | |
GLES20.glGenTextures(1, mFBOTextureR, 0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFBOTextureR[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.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR) | |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST) | |
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 256, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null) | |
GLES20.glGenFramebuffers(1, mRenderToTextureFBO, 0) | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mRenderToTextureFBO[0]) | |
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFBOTextureR[0], 0) | |
GLES20.glGenRenderbuffers(1, mRenderBufferFBO, 0) | |
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, mRenderBufferFBO[0]) | |
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, 256, 256) | |
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, mRenderBufferFBO[0]) | |
/** Check FBO is complete and OK */ | |
val iResult = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER) | |
if (iResult != GLES20.GL_FRAMEBUFFER_COMPLETE) { | |
throw RuntimeException("Error: Frame Buffer Status is not complete. Terminated.") | |
} | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) | |
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0) | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0) | |
} | |
private var mWidth: Int = 0 | |
private var mHeight: Int = 0 | |
fun setRenderSize(width: Int, height: Int) { | |
mWidth = width | |
mHeight = height | |
GLES20.glViewport(0, 0, width, height) | |
} | |
fun onDrawFrame() { | |
prepareFBOTexture() | |
/**=========================================**/ | |
useFBOTexture() | |
} | |
private var mStartTime: Long = -1L | |
private val mBitmapCache = LruBitmapCache.getSingleInstance() | |
fun useFBOTexture() { | |
/** Use blue background color */ | |
GLES20.glClearColor(0.0f, 0.2f, 0.3f, 1.0f) | |
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT) | |
GLES20.glViewport(0, 0, mWidth, mHeight) | |
GLES20.glUseProgram(mProgramHandle) | |
// mWorldVertices.position(0) | |
// GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false, 8, mWorldVertices) | |
// GLES20.glEnableVertexAttribArray(mPositionHandle) | |
// | |
// mTextureVertices.position(0) | |
// GLES20.glVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GL_FLOAT, false, 8, mTextureVertices) | |
// GLES20.glEnableVertexAttribArray(mTextureCoordHandle) | |
GLES20.glActiveTexture(GLES20.GL_TEXTURE0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFBOTextureR[0]) | |
GLES20.glUniform1i(mTextureHandle, 0) | |
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) | |
} | |
fun prepareFBOTexture() { | |
/** Enable frame buffer to start rendering into it */ | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mRenderToTextureFBO[0]) | |
/** Create an Orange back ground */ | |
GLES20.glClearColor(1.0f, 0.5f, 0.0f, 1.0f) | |
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT) | |
GLES20.glViewport(0, 0, 256, 256) | |
GLES20.glUseProgram(mProgramHandle) | |
mWorldVertices.position(0) | |
GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false, 8, mWorldVertices) | |
GLES20.glEnableVertexAttribArray(mPositionHandle) | |
mTextureVertices.position(0) | |
GLES20.glVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GL_FLOAT, false, 8, mTextureVertices) | |
GLES20.glEnableVertexAttribArray(mTextureCoordHandle) | |
if (mStartTime == -1L) { | |
mStartTime = System.currentTimeMillis() | |
} | |
val currentTime = System.currentTimeMillis() | |
val position = (currentTime - mStartTime) % 2000 | |
val i = Math.round((paths.size - 1) * 1.0f / 2000 * position) | |
val path = paths[i] | |
var bitmap: Bitmap? = mBitmapCache.get(path) | |
if (bitmap == null || bitmap.isRecycled) { | |
bitmap = GetFromAssets(context, path) | |
if (bitmap != null && !bitmap.isRecycled) { | |
mBitmapCache.put(path, bitmap) | |
} else { | |
return | |
} | |
} | |
mTextureIn = loadTexture(bitmap, mTextureIn, true) | |
/** set the Texture unit 0 active and bind the texture to it */ | |
GLES20.glActiveTexture(GLES20.GL_TEXTURE0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIn) | |
GLES20.glUniform1i(mTextureHandle, 0) | |
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) | |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); | |
} | |
private val NO_TEXTURE = 0 | |
private fun loadTexture(img: Bitmap, usedTexId: Int, recycle: Boolean): Int { | |
val textures = IntArray(1) | |
if (usedTexId == NO_TEXTURE) { | |
GLES20.glGenTextures(1, textures, 0) | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]) | |
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) | |
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) | |
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT.toFloat()) | |
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT.toFloat()) | |
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0) | |
} else { | |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, usedTexId) | |
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, img) | |
textures[0] = usedTexId | |
} | |
if (recycle) { | |
img.recycle() | |
} | |
return textures[0] | |
} | |
private fun convert(context: Context, dir: String): List<String> { | |
var names: Array<String>? = null | |
try { | |
names = context.assets.list(dir) | |
} catch (e: IOException) { | |
e.printStackTrace() | |
} | |
val paths = ArrayList<String>() | |
if (names != null) { | |
for (name in names) { | |
paths.add("$dir/$name") | |
} | |
} | |
paths.sortWith(Comparator { o1, o2 -> | |
val sp1 = o1.split("_".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() | |
val sp2 = o2.split("_".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() | |
var num1 = sp1[sp1.size - 1] | |
if (num1.contains(".")) { | |
num1 = num1.substring(0, num1.indexOf(".")) | |
} | |
if (!TextUtils.isDigitsOnly(num1)) { | |
num1 = num1.substring(num1.length - 2) | |
} | |
var num2 = sp2[sp2.size - 1] | |
if (num2.contains(".")) { | |
num2 = num2.substring(0, num2.indexOf(".")) | |
} | |
if (!TextUtils.isDigitsOnly(num2)) { | |
num2 = num2.substring(num2.length - 2) | |
} | |
parseInt(num1) - parseInt(num2) | |
}) | |
return paths | |
} | |
private fun parseInt(`val`: String): Int { | |
if (TextUtils.isEmpty(`val`)) return 0 | |
try { | |
return Integer.parseInt(`val`) | |
} catch (e: NumberFormatException) { | |
e.printStackTrace() | |
} | |
return 0 | |
} | |
fun GetFromAssets(context: Context, name: String): Bitmap? { | |
var img: Bitmap? = null | |
//get asset manager | |
val assetManager = context.assets | |
val istr: InputStream | |
try { | |
//open image to input stream | |
istr = assetManager.open(name) | |
//decode input stream | |
img = BitmapFactory.decodeStream(istr) | |
} catch (e: IOException) { | |
e.printStackTrace() | |
} | |
return img | |
} | |
companion object { | |
val ATTRIBUTE_POSITION = "position" | |
val ATTRIBUTE_TEXTURE_COORD = "inputTextureCoordinate" | |
val VARYING_TEXTURE_COORD = "textureCoordinate" | |
val UNIFORM_TEXTURE = "inputImageTexture" | |
val UNIFORM_TEXTURE_0 = UNIFORM_TEXTURE | |
@JvmField | |
var DEFAULT_VERTEX_SHADER = ("attribute vec4 " + ATTRIBUTE_POSITION + ";\n" | |
+ "attribute vec2 " + ATTRIBUTE_TEXTURE_COORD + ";\n" | |
+ "varying vec2 " + VARYING_TEXTURE_COORD + ";\n" | |
+ "void main() {\n" | |
+ " " + VARYING_TEXTURE_COORD + " = " + ATTRIBUTE_TEXTURE_COORD + ";\n" | |
+ " gl_Position = " + ATTRIBUTE_POSITION + ";\n" | |
+ "}\n") | |
var DEFAULT_FRAGMENT_SHADER = ("precision mediump float;\n" | |
+ "uniform sampler2D " + UNIFORM_TEXTURE_0 + ";\n" | |
+ "varying vec2 " + VARYING_TEXTURE_COORD + ";\n" | |
+ "void main(){\n" | |
+ " gl_FragColor = texture2D(" + UNIFORM_TEXTURE_0 + "," + VARYING_TEXTURE_COORD + ")" + ";\n" | |
+ "}\n") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment