Skip to content

Commit 4c0b6c9

Browse files
committed
add chromatic aberration and distorted tv filters
1 parent b7305ae commit 4c0b6c9

File tree

7 files changed

+350
-0
lines changed

7 files changed

+350
-0
lines changed

app/src/main/java/com/pedro/streamer/utils/FilterMenu.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ import com.pedro.encoder.input.gl.render.filters.BlurFilterRender
3636
import com.pedro.encoder.input.gl.render.filters.BrightnessFilterRender
3737
import com.pedro.encoder.input.gl.render.filters.CartoonFilterRender
3838
import com.pedro.encoder.input.gl.render.filters.ChromaFilterRender
39+
import com.pedro.encoder.input.gl.render.filters.ChromaticAberrationFilterRender
3940
import com.pedro.encoder.input.gl.render.filters.CircleFilterRender
4041
import com.pedro.encoder.input.gl.render.filters.ColorFilterRender
4142
import com.pedro.encoder.input.gl.render.filters.ContrastFilterRender
4243
import com.pedro.encoder.input.gl.render.filters.CropFilterRender
44+
import com.pedro.encoder.input.gl.render.filters.DistortedTvFilterRender
4345
import com.pedro.encoder.input.gl.render.filters.DuotoneFilterRender
4446
import com.pedro.encoder.input.gl.render.filters.EarlyBirdFilterRender
4547
import com.pedro.encoder.input.gl.render.filters.EdgeDetectionFilterRender
@@ -142,6 +144,10 @@ class FilterMenu(private val context: Context) {
142144
)
143145
return true
144146
}
147+
R.id.chromatic_aberration -> {
148+
glInterface.setFilter(ChromaticAberrationFilterRender())
149+
return true
150+
}
145151
R.id.circle -> {
146152
glInterface.setFilter(CircleFilterRender())
147153
return true
@@ -161,6 +167,10 @@ class FilterMenu(private val context: Context) {
161167
})
162168
return true
163169
}
170+
R.id.distorted_tv -> {
171+
glInterface.setFilter(DistortedTvFilterRender())
172+
return true
173+
}
164174
R.id.duotone -> {
165175
glInterface.setFilter(DuotoneFilterRender())
166176
return true

app/src/main/res/menu/rotation_menu.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@
9292
android:id="@+id/chroma"
9393
android:title="@string/chroma"
9494
/>
95+
<item
96+
android:id="@+id/chromatic_aberration"
97+
android:title="@string/chromatic_aberration"
98+
/>
9599
<item
96100
android:id="@+id/circle"
97101
android:title="@string/circle"
@@ -108,6 +112,10 @@
108112
android:id="@+id/crop"
109113
android:title="@string/crop"
110114
/>
115+
<item
116+
android:id="@+id/distorted_tv"
117+
android:title="@string/distorted_tv"
118+
/>
111119
<item
112120
android:id="@+id/duotone"
113121
android:title="@string/duotone"

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
<string name="brightness">Brightness</string>
2424
<string name="cartoon">Cartoon</string>
2525
<string name="chroma">Chroma</string>
26+
<string name="chromatic_aberration">Chromatic Aberration</string>
2627
<string name="circle">Circle</string>
2728
<string name="color">Color</string>
2829
<string name="contrast">Contrast</string>
2930
<string name="crop">Crop</string>
31+
<string name="distorted_tv">Distorted TV</string>
3032
<string name="duotone">Duotone</string>
3133
<string name="earlybird">EarlyBird</string>
3234
<string name="edge_detection">Edge detection</string>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (C) 2024 pedroSG94.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.pedro.encoder.input.gl.render.filters
17+
18+
import android.content.Context
19+
import android.opengl.GLES20
20+
import android.opengl.Matrix
21+
import android.os.Build
22+
import androidx.annotation.RequiresApi
23+
import com.pedro.common.TimeUtils.getCurrentTimeMillis
24+
import com.pedro.encoder.R
25+
import com.pedro.encoder.utils.gl.GlUtil
26+
import java.nio.ByteBuffer
27+
import java.nio.ByteOrder
28+
29+
/**
30+
* Created by pedro on 4/02/18.
31+
*/
32+
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
33+
class ChromaticAberrationFilterRender: BaseFilterRender() {
34+
//rotation matrix
35+
private val squareVertexDataFilter = floatArrayOf(
36+
// X, Y, Z, U, V
37+
-1f, -1f, 0f, 0f, 0f, //bottom left
38+
1f, -1f, 0f, 1f, 0f, //bottom right
39+
-1f, 1f, 0f, 0f, 1f, //top left
40+
1f, 1f, 0f, 1f, 1f, //top right
41+
)
42+
43+
private var program = -1
44+
private var aPositionHandle = -1
45+
private var aTextureHandle = -1
46+
private var uMVPMatrixHandle = -1
47+
private var uSTMatrixHandle = -1
48+
private var uSamplerHandle = -1
49+
private var uTimeHandle = -1
50+
51+
private var START_TIME = getCurrentTimeMillis()
52+
53+
init {
54+
squareVertex = ByteBuffer.allocateDirect(squareVertexDataFilter.size * FLOAT_SIZE_BYTES)
55+
.order(ByteOrder.nativeOrder())
56+
.asFloatBuffer()
57+
squareVertex.put(squareVertexDataFilter).position(0)
58+
Matrix.setIdentityM(MVPMatrix, 0)
59+
Matrix.setIdentityM(STMatrix, 0)
60+
}
61+
62+
override fun initGlFilter(context: Context) {
63+
val vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex)
64+
val fragmentShader = GlUtil.getStringFromRaw(context, R.raw.chromatic_aberration_fragment)
65+
66+
program = GlUtil.createProgram(vertexShader, fragmentShader)
67+
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition")
68+
aTextureHandle = GLES20.glGetAttribLocation(program, "aTextureCoord")
69+
uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix")
70+
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix")
71+
uSamplerHandle = GLES20.glGetUniformLocation(program, "uSampler")
72+
uTimeHandle = GLES20.glGetUniformLocation(program, "uTime")
73+
}
74+
75+
override fun drawFilter() {
76+
GLES20.glUseProgram(program)
77+
78+
squareVertex.position(SQUARE_VERTEX_DATA_POS_OFFSET)
79+
GLES20.glVertexAttribPointer(
80+
aPositionHandle, 3, GLES20.GL_FLOAT, false,
81+
SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex
82+
)
83+
GLES20.glEnableVertexAttribArray(aPositionHandle)
84+
85+
squareVertex.position(SQUARE_VERTEX_DATA_UV_OFFSET)
86+
GLES20.glVertexAttribPointer(
87+
aTextureHandle, 2, GLES20.GL_FLOAT, false,
88+
SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex
89+
)
90+
GLES20.glEnableVertexAttribArray(aTextureHandle)
91+
92+
GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, MVPMatrix, 0)
93+
GLES20.glUniformMatrix4fv(uSTMatrixHandle, 1, false, STMatrix, 0)
94+
val time = ((getCurrentTimeMillis() - START_TIME).toFloat()) / 1000f
95+
if (time >= 10) START_TIME += 10000
96+
GLES20.glUniform1f(uTimeHandle, time)
97+
98+
GLES20.glUniform1i(uSamplerHandle, 0)
99+
GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
100+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, previousTexId)
101+
}
102+
103+
override fun disableResources() {
104+
GlUtil.disableResources(aTextureHandle, aPositionHandle)
105+
}
106+
107+
override fun release() {
108+
GLES20.glDeleteProgram(program)
109+
}
110+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (C) 2024 pedroSG94.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.pedro.encoder.input.gl.render.filters
17+
18+
import android.content.Context
19+
import android.opengl.GLES20
20+
import android.opengl.Matrix
21+
import android.os.Build
22+
import androidx.annotation.RequiresApi
23+
import com.pedro.common.TimeUtils.getCurrentTimeMillis
24+
import com.pedro.encoder.R
25+
import com.pedro.encoder.utils.gl.GlUtil
26+
import java.nio.ByteBuffer
27+
import java.nio.ByteOrder
28+
29+
/**
30+
* Created by pedro on 4/02/18.
31+
*/
32+
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
33+
class DistortedTvFilterRender: BaseFilterRender() {
34+
//rotation matrix
35+
private val squareVertexDataFilter = floatArrayOf(
36+
// X, Y, Z, U, V
37+
-1f, -1f, 0f, 0f, 0f, //bottom left
38+
1f, -1f, 0f, 1f, 0f, //bottom right
39+
-1f, 1f, 0f, 0f, 1f, //top left
40+
1f, 1f, 0f, 1f, 1f, //top right
41+
)
42+
43+
private var program = -1
44+
private var aPositionHandle = -1
45+
private var aTextureHandle = -1
46+
private var uMVPMatrixHandle = -1
47+
private var uSTMatrixHandle = -1
48+
private var uSamplerHandle = -1
49+
private var uTimeHandle = -1
50+
51+
private var START_TIME = getCurrentTimeMillis()
52+
53+
init {
54+
squareVertex = ByteBuffer.allocateDirect(squareVertexDataFilter.size * FLOAT_SIZE_BYTES)
55+
.order(ByteOrder.nativeOrder())
56+
.asFloatBuffer()
57+
squareVertex.put(squareVertexDataFilter).position(0)
58+
Matrix.setIdentityM(MVPMatrix, 0)
59+
Matrix.setIdentityM(STMatrix, 0)
60+
}
61+
62+
override fun initGlFilter(context: Context) {
63+
val vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex)
64+
val fragmentShader = GlUtil.getStringFromRaw(context, R.raw.distorted_tv_fragment)
65+
66+
program = GlUtil.createProgram(vertexShader, fragmentShader)
67+
aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition")
68+
aTextureHandle = GLES20.glGetAttribLocation(program, "aTextureCoord")
69+
uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix")
70+
uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix")
71+
uSamplerHandle = GLES20.glGetUniformLocation(program, "uSampler")
72+
uTimeHandle = GLES20.glGetUniformLocation(program, "uTime")
73+
}
74+
75+
override fun drawFilter() {
76+
GLES20.glUseProgram(program)
77+
78+
squareVertex.position(SQUARE_VERTEX_DATA_POS_OFFSET)
79+
GLES20.glVertexAttribPointer(
80+
aPositionHandle, 3, GLES20.GL_FLOAT, false,
81+
SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex
82+
)
83+
GLES20.glEnableVertexAttribArray(aPositionHandle)
84+
85+
squareVertex.position(SQUARE_VERTEX_DATA_UV_OFFSET)
86+
GLES20.glVertexAttribPointer(
87+
aTextureHandle, 2, GLES20.GL_FLOAT, false,
88+
SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex
89+
)
90+
GLES20.glEnableVertexAttribArray(aTextureHandle)
91+
92+
GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, MVPMatrix, 0)
93+
GLES20.glUniformMatrix4fv(uSTMatrixHandle, 1, false, STMatrix, 0)
94+
val time = ((getCurrentTimeMillis() - START_TIME).toFloat()) / 1000f
95+
if (time >= 10) START_TIME += 10000
96+
GLES20.glUniform1f(uTimeHandle, time)
97+
98+
GLES20.glUniform1i(uSamplerHandle, 0)
99+
GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
100+
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, previousTexId)
101+
}
102+
103+
override fun disableResources() {
104+
GlUtil.disableResources(aTextureHandle, aPositionHandle)
105+
}
106+
107+
override fun release() {
108+
GLES20.glDeleteProgram(program)
109+
}
110+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
precision mediump float;
2+
3+
uniform sampler2D uSampler;
4+
uniform float uTime;
5+
varying vec2 vTextureCoord;
6+
7+
void main() {
8+
float amount = 0.0;
9+
amount = (1.0 + sin(uTime * 6.0)) * 0.5;
10+
amount *= 1.0 + sin(uTime * 16.0) * 0.5;
11+
amount *= 1.0 + sin(uTime * 19.0) * 0.5;
12+
amount *= 1.0 + sin(uTime * 27.0) * 0.5;
13+
amount = pow(amount, 3.0);
14+
15+
amount *= 0.05;
16+
17+
vec3 col;
18+
col.r = texture2D(uSampler, vec2(vTextureCoord.x + amount, vTextureCoord.y)).r;
19+
col.g = texture2D(uSampler, vTextureCoord).g;
20+
col.b = texture2D(uSampler, vec2(vTextureCoord.x - amount, vTextureCoord.y)).b;
21+
22+
col *= (1.0 - amount * 0.5);
23+
gl_FragColor = vec4(col, 1.0);
24+
}

0 commit comments

Comments
 (0)