ShaderView is an Android View that makes it easy to use GLSL shaders for your app. It's the modern way to use shaders for Android instead of RenderScript.
This library is the easiest way to use OpenGL shaders as an Android View. You just simply need to add ShaderView in your layout and set up shaders. The advantage of this library that you can use ShaderView in your hierarchy as a regular View.
Gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
implementation 'com.github.appspell:ShaderView:[last-version]'
<com.appspell.shaderview.ShaderView
android:id="@+id/shaderView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:fragment_shader_raw_res_id="@raw/fragment_shader" />
app:fragment_shader_raw_res_id
- reference to the fragment shader file in RAW resource solder example
app:vertex_shader_raw_res_id
- reference to the vertex shader file in RAW resource solder example
val shaderView = ShaderView(this)
with(shaderView) {
fragmentShaderRawResId = R.raw.color_frag
shaderParams = ShaderParams.Builder()
.addColor("diffuseColor", R.color.teal_200, resources)
.build()
}
fragmentShaderRawResId
- reference to the vertex shader file in RAW resource solder [example]
vertexShaderRawResId
- reference to the fragment shader file in RAW resource solder [example]
shaderParams
- custom parameters that we're going to send to the shader (uniform)
onViewReadyListener
- called when the view is created and ready to create a shader
onDrawFrameListener
- called each frame
updateContinuously
- should we render the view each frame (default is "false")
debugMode
- enable or disable debug logs
Pass ShaderParams
to the ShaderView
if you need to set up some uniform
attributes.
shaderView.shaderParams = ShaderParamsBuilder()
.addTexture2D(
"uNormalTexture", // name of `sampler2D` in the fragment shader
R.drawable.normal_button, // drawable that we use for such texture
GLES30.GL_TEXTURE0 // texture slot
)
.addColor("uColor", R.color.grey, resources) // send color as `uniform vec4`
.addVec4f("uColor2", floatArrayOf(0.5f, 0.5f, 0.5f, 1f))
.addVec3f("uVaryingColor", floatArrayOf(0.5f, 0.5f, 0.5f))
.addFloat("uTime", 1.0f)
.build()
During execution, you may update this param:
shaderParams.updateValue("time", System.currentTimeMillis())
If you need to update uniform
each frame, you may use onDrawFrameListener
.
shaderView.onDrawFrameListener = { shaderParams ->
shaderParams.updateValue("time", System.currentTimeMillis())
}
The full list of supported uniform types: float, int, bool, vec2f, vec3f, vec4f, vec2i, vec3i, vec4i, mat3, mat4, mat3x4, sampler2D, samplerExternalOES
in vec2 textureCoord
main()
function and return the result color to fragColor
#version 300 es
precision mediump float;
in vec2 textureCoord;
out vec4 fragColor;
void main() {
fragColor = vec4(textureCoord.x, textureCoord.y, textureCoord.y, 1.0);
}
Full code of example using ExoPlayer you may find here and here
#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
uniform samplerExternalOES uVideoTexture;
shaderParams = ShaderParamsBuilder()
.addTextureOES("uVideoTexture") // video texture input/output
.build()
ShaderView
is ready, send Surface
to the video playershaderView.onViewReadyListener = { shader ->
// get surface from shader params
val surface = shader.params.getTexture2dOESSurface("uVideoTexture")
// initialize video player with this surface
initVideoPlayer(surface)
}
In Android Demo Project code you may found it in ViewHolders here
Why we use TextureView instead of SurfaceView you can read here.
To be able to use OpenGL rendering for Android TextureView, we've created GLTextureView.kt