Android GLKBaseEffect equivalent (already existing OpenGL shaders) - android

I'm learning OpenGL ES 2.0 in Android, do you know of a library providing already existing shaders?
I'm on a project with a friend who's developing on iOS, he told me that he can use GLKBaseEffect to avoid devolping custom shaders, as long as we don't need complex features. Is there an equivalent of that BaseEffect in Android?
I'm asking this because the two of us have been assigned this project by a professor, who told us that it's not important for this project to develop custom shaders, so I'm guessing there is a compilation of basical shaders that I can browse.
Is that correct?
Thank you for your help!

Android doesn't support something like the GLKBaseEffect class but I want you to know that shader is just supported for being programable so shader is not hard at all if you use simple shader codes.
If you don't want to do any post imageprocessing don't change fragment shader that is only what you should do.
Vertex shader
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main(void)
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
Fragment shader
uniform sampler2D texture0;
varying vec2 textureCoordinate;
void main()
gl_FragColor = texture2D(texture0, textureCoordinate);
}
Now you need to put only three values position, texture cordinate and texture :) as you need to do anywhere

Related

Rendering from GL_TEXTURE_EXTERNAL_OES to GL_TEXTURE_2D but only one color flashes

I'm pretty new to opengl-es and currently have a problem rendering my video output on a screen in Unity.
I was developing a video player project with Unity. I bought the EasyMovieTexture plugin and replaced the video player module with another open-source video player (Ijkplayer) years ago which worked fine all the time.
Now I want to replace it with newer VLC using libvlcjni. I compiled and just replaced the old Ijkplayer but it didn't work as I expected. The screen just started flashing one color from every video frame but the video was going and the audio track was normally playing too.
Screenshot - A test scene with a screen, sorry there's mistake with texcoord but only color flashing
I'd like to provide some further information hope that I can find some help (Sorry if I have some mistakes or misunderstandings):
As far as I know, these video player modules need a Surface (Or SurfaceTexture) in the Android layer and the video decoder will work as a data producer. The SurfaceTexture consumes data from the producer and converts it to the texture with the type of GL_TEXTURE_EXTERNAL_OES which can be directly consumed and displayed with components like TextureView. But this texture data cannot be consumed in the Unity layer unless I use a GLSL shader directly sampling my OES texture data, like this:
// Unity shader with GLSL
GLSLPROGRAM
#pragma only_renderers gles3
#include "UnityCG.glslinc"
// ...
// Ignoring vertex shader
// ...
in vec2 textureCoord;
layout(binding = 0) uniform samplerExternalOES _MainTex;
out vec4 fragColor;
void main()
{
fragColor = texture(_MainTex, textureCoord);
}
ENDGLSL
My approach was to convert the texture to GL_TEXTURE_2D with the native library which came along with the EasyMovieTexture plugin. Here I cannot provide the source code of this .so library but I've decompiled it in IDAPro and I know it can work along with GLES and render the external texture data to another 2d texture using FrameBuffer Object and external shader program.
Here is a random example to explain the procedure, it is NOT the accurate code from the binary: FilterFBOTexture.java
Though I cannot edit the .so file, luckily it was reading two external files as the shader program:
// vertex shader
attribute highp vec3 inVertex;
attribute mediump vec3 inNormal;
attribute mediump vec2 inTexCoord;
uniform highp mat4 MVPMatrix;
uniform mediump vec2 TexCoordMove;
varying mediump vec2 TexCoord;
void main()
{
highp vec4 vPos = vec4(0,0,0,1);
vPos.x = ( inTexCoord.x * 2.0 - 1.0 );
vPos.y = ( inTexCoord.y * 2.0 - 1.0 );
gl_Position = vPos;
mediump vec4 vec4Temp = vec4(inTexCoord.x - TexCoordMove.x,inTexCoord.y - TexCoordMove.y,0,1.0);
vec4Temp = MVPMatrix * vec4Temp;
vec4Temp.xyz = vec4Temp.xyz / vec4Temp.w;
TexCoord = vec4Temp.xy;
}
// fragment shader
#extension GL_OES_EGL_image_external : require
uniform samplerExternalOES sTexture;
uniform lowp float AlphaValue;
varying mediump vec2 TexCoord;
void main()
{
lowp vec4 color = texture2D(sTexture, TexCoord) ;
color = vec4(color.rgb, color.a * AlphaValue);
gl_FragColor = color;
}
I don't know whether I have to check the vertex shader or just dive into the source code of libvlcjni so that I can correctly render my video output. Any idea will be grateful, thanks.
Update 2022-11-4:
I turned around and began to use VLC for Android.
Big appreciation to #mfkl, I created an issue days ago on the VLC repo.
https://code.videolan.org/videolan/vlc-unity/-/issues/164
The problem still remains but at least I can work for something now.

OpenGL ES 2.0 SL writing out from fragment shader to texture

Hopefully this is a really simple question.
How to write out to a texture attached to framebuffer from within a fragment shader. I assume it is just gl_FragColor, am I suppose to define/use a different variable, like gl_Data[0]?
Frag Shader:
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D displayTexture;
void main() {
gl_FragColor = texture2D(displayTexture, vTextureCoord);
}
This question is not how to setup a texture for writing to, just how to write out from within the fragment shader. I just want to make sure I have this piece of the puzzle.
You seem to assume correct. All the drawing code should be the same drawing to render buffer as to an attached texture, even shaders.

OpenGL Shadar Language in Android

I'm learning OpenGL through a great book that uses OpenGL version 3.3 in the Premake 4 plataform, but I actually want to learn OpenGL for Android, which supports OpenGL version 2.0. It's pretty much the same, as the concepts are the same, but I'm having some trouble with the Shader Language code.
For example, in the book the autor implements a Vertex Shader with the code:
#version 330
layout(location = 0) in vec4 position;
void main(){
gl_Position = position;
}
After a lot of research I was able to implement this exactly Vertex Shader code in Android with the code:
String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
But I can't figure out how can I implement this Vertex Shader below:
#version 330
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
smooth out vec4 theColor;
void main() {
gl_Position = position;
theColor = color;
}
The book is http://arcsynthesis.org/gltut/Basics/Tut02%20Vertex%20Attributes.html
You cannot implement the shader as it is written in OpenGL ES 2.0. This shader is written against the OpenGL 3.3 GLSL specification, OpenGL ES 2.0 uses syntax roughly equivalent to GLSL 120 (OpenGL 2.1).
The smooth qualifier is used to control interpolation between shader stages, GLSL ES does not support this, all vertex shader outputs are smoothly interpolated in GLSL ES.
layout (...) is unsupported by GLSL ES, you must use glBindAttribLocation (...) to set the location.
in and out are not supported by GLSL ES, you must use attribute for vertex shader inputs and varying for vertex shader outputs and fragment shader inputs.
And last, #version 330 is invalid. In OpenGL ES 2.0, there is only one GLSL ES specification, version 1.0 (so a compliant OpenGL ES 2.0 shader should begin with #version 100).
To answer your question about implementing that particular vertex shader:
#version 100
attribute vec4 position;
attribute vec4 color;
varying vec4 theColor;
void main() {
gl_Position = position;
theColor = color;
}
This is of course only half of the equation, you need to pair it with a fragment shader that also uses OpenGL ES 2.0-compliant syntax.
A minimal fragment shader that would work with this vertex shader:
#version 100
varying vec4 theColor; // In GLSL 330 this would be written as: in vec4 theColor;
void main (void) {
gl_FragColor = theColor;
}

Custom Shader not working on Android Device (using LibGDX)

I've been starting out using LibGDX to develop for PC as well as Android. I'm currently working on a little project requiring me to write custom shaders in GLSL (based on full-screen quads). Coming from a HLSL environment I had a little trouble setting the whole shader system up in combination with SpriteBatch (as I want to keep the code simple where I can).
I have the following shader code working on desktop:
Vertexshader:
attribute vec4 a_position;
uniform mat4 u_projectionViewMatrix;
void main()
{
gl_Position = a_position * u_projectionViewMatrix;
}
Fragmentshader:
uniform vec2 effectOrigin;
uniform vec2 effectDir;
void main()
{
float distToOrigin = distance(effectOrigin.xy, gl_FragCoord.xy);
gl_FragColor = vec4(mod(distToOrigin+effectDir.x*30, 30)-15, 0.0, 0.0, 1.0);
}
As I said it works on desktop (Windows), and gives me a nice circle pattern. On Android however it doesn't compile and gives me just the cleared background color. I suspected it had something to do with OpenGL ES 2 permissions on Android so I added this line to the manifest:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />, but this didn't seem to make a difference.
I also thought it might have something to do with the precision of the floats and vectors, but I wasn't able to figure out how I would have to change them in order to fix it.
Is there someone who can help me on this? I haven't been able to find an answer elsewhere!
Thanks in advance,
Yuri
P.S. Is there a way to see what went wrong during compiling of the shaders? I know debugging is hard on shaders, but it would be awesome to have at least some idea of where it could've gone wrong during compilation.
Fixed it using P.T.´s suggestion on logging the compilation!
There were two problems in the fragment shader, the fixed shader looks like this:
precision mediump float;
uniform vec2 effectOrigin;
uniform vec2 effectDir;
void main()
{
float distToOrigin = distance(effectOrigin.xy, gl_FragCoord.xy);
gl_FragColor = vec4(mod(distToOrigin+effectDir.x*30.0, 30.0)-15.0, 0.0, 0.0, 1.0);
}
I added the precision definition at the top, and also changed the constant values from integers to floats (e.g. 15 to 15.0) to fix it!
Thanks P.T.!

Android GLES20.glBlendEquation not working?

Ive been trying to make a 2.5D engine with depth and normal map textures for a few weeks now, not unlike whats used here Linky. After thinking the drawing of a depth map in the fragment shader from a texture was impossible due to ES 2.0 missing the gl_fragDepth variable I found a tutorial for iOS where they used glBlendEquation with the mode GL_MIN/GL_MAX to "fake" depth buffering of the fragment to a framebuffer-texture Linky. Unfortunely GLES20.glBlendEquation makes the application crash on both my phones (SGS 1/2) with UnsupportedOperationException. So Im wondering if anyone has used this function to any success? GL_MIN/GL_MAX also seems to be missing from the Android Opengl ES 2.0 spec so Im probably out of luck here...
Any ideas?
BTW It does seem to work in GL11Ext but since Im using the fragment shader for normal mapping this wont work from me.
i was experimenting on my Vega tablet (Tegra) and this worked for me:
fragment shader:
#extension GL_NV_shader_framebuffer_fetch : require
// makes gl_LastFragColor accessible
precision highp float;
varying vec2 v_texcoord;
uniform sampler2D n_sampler;
void main()
{
vec4 v_tex = texture2D(n_sampler, v_texcoord);
gl_FragColor = min(gl_LastFragColor, v_tex); // MIN blending
}
Pretty easy, huh? But i'm afraid this will be NV-only.

Categories

Resources