Shaders on Android

Hi there,
I’m new to Of and Android NDK.
I’ve strugled to make the Shader Example run on my Nexus 4 and I finnaly made it work.
I thought I would post what solved my probleme
first of all.
if you changed the name of your application you need to change the name of the zip file “MyOfApp/res/raw/androidshaderexampleresources.zip” to “MyOfApp/res/raw/myofappresources.zip”
if you do not, you wont be able to load the shaders

then,
in this zip file, in the noise.frag file
change line 18 from
    if( mod(xVal, 2.0) == 0.5 && mod(yVal, 4.0) == 0.5 ){
to
    if( mod(xVal, 2.0) == 0.0 && mod(yVal, 4.0) == 0.0 ){

(found this here https://github.com/openframeworks/openFrameworks/issues/2825)

this worked for me
(I’m new to this forum, therefor if somthing wrong with my post, please notify me)

Hi Anton,

Was there anything else you needed to do to get shaders working on Android? I fixed that line of code but they are still not working for me. I have quite a few questions about getting shaders working so bear with me!

Do I need to add this line into the manifest?

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

Also, do they need the

#version 120 

that precedes the meat of the shader?

How exactly are you supposed to edit and update your shaders? If I create a data folder within the bin and then run my app, it seems like it zips up, renames to myappresources.zip, deletes the original, and then moves to myApp/res/raw. Should I be re-zipping my shaders into the raw folder after each edit, or should I be making new data folders and letting the app move it around at compile time?

When I try to run the shader example or another app I made with shaders, I get an error from libEGL saying

called unimplemented OpenGL ES API

as well as one from ofShader saying

setupShaderFromSource(): GL_VERTEX_SHADER shader failed to compile.

I’m using
OSX v. 10.8.5
NDK r9b
SDK 22.6.2
oF 0.8.1
Tried on both a Galaxy SIII and a S5 with same results.

I was also getting errors in my source when I try to load a shader or set any uniforms.

Invalid arguments '

I’m not sure what the one apostrophe is about. These prevent me from building, and the only way I’ve found around it is to delete the errors close out those source files, close ADT and then reopen. If I open the source I get the errors again. I can edit the source in xcode and then refresh the project to update. This can’t really be the right way to building android with oF…

Thanks for the help!

to my knowledge thoses aren’t mandatory to work ( at least, I didn’t used them).

to edit your shader. I edit the shaders that are located in /res/raw/xxx.zip then I update the zipfile. I don’t think editing a file in the bin is the proper way.

I can’t edit the code directly in eclipse(ADT) because opening the source files make the same error as you. however. if you edit your source with an other program it work fine.

My guess on your problem would be an error in your shader. bear in mind that you are working with glsl ES and therefor a lot of functions aren’t available.

Sorry for not having a definitive answer. I’m also a beginner both in OpenGl and OpenFramework. I went through a lot of trial and error befor making things work.
(also, I’m not a native english speaker so sorry if my wording isn’t correct).

Are you using the programmable renderer? in main.cpp before ofSetupOpenGL:

ofSetCurrentRenderer(ofGLProgrammbleRenderer::TYPE);

Thanks for the suggestions. I tried including the programmable renderer line as you suggested Arturo but it doesn’t seem to make a difference.

My main:

#include "ofMain.h"
#include "ofApp.h"
#include "ofGLProgrammableRenderer.h"

int main(){
	ofSetCurrentRenderer(ofGLProgrammableRenderer::TYPE);
	ofSetupOpenGL(1024,768, OF_WINDOW);			// <-------- setup the GL context

	// this kicks off the running of my app
	// can be OF_WINDOW or OF_FULLSCREEN
	// pass in width and height too:
	ofRunApp( new ofApp() );
	return 0;
}


#ifdef TARGET_ANDROID
#include <jni.h>

//========================================================================
extern "C"{
	void Java_cc_openframeworks_OFAndroid_init( JNIEnv*  env, jobject  thiz ){
		main();
	}
}
#endif

I don’t think I’m using any unusual shader functions. My shaders are actually very simple.
base.vert

void main() {
    gl_Position	= gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
}

combine.frag

uniform sampler2DRect tex0;
uniform sampler2DRect tex1;
uniform sampler2DRect tex2;

    void main() {
        vec3 red = vec3(texture2DRect(tex0, gl_TexCoord[0].st));
        vec3 green = vec3(texture2DRect(tex1, gl_TexCoord[0].st));
        vec3 blue = vec3(texture2DRect(tex2, gl_TexCoord[0].st));
        
        gl_FragColor = vec4(red.r,green.g,blue.b,1.0);
    }

Here’s the error log I’ve got.

Below that it just starts to say: couldn’t begin, shader not loaded.

Including the #version 120 gives me an extra error in the logcat that says:

OpenGL ES #version <number> is not supported

But I also get all the same stuff as in the ss above.
FWIW the log is telling me that I’m using OpenGL ES Shader Compiler Version: 17.01.10.SPL

It’s sort of strange, I was able to get the shader example to build compile and run on my work computer, but not on my laptop at home. In addition to the shaders not compiling, I also get an error when running the shader example that says

drawStringAsShapes(): font not allocated: line 1146 in ../../../libs/openFrameworks/graphics/ofTrueTypeFont.cpp

those shaders have the syntax of openGL 2.x not openGL ES, take a look at the shader example to check the correct syntax

1 Like

Hi Arturo,

Yes I just realized that too. I changed everything over and now it’s working as expected! I also had to include the uses-feature line in the manifest and couldn’t get it to compile the shaders with anything higher than #version 100.

My working shaders look like

vert

#version 100

attribute vec4 position;
attribute vec2 texcoord;
varying vec2 tc;
uniform mat4 modelViewProjectionMatrix;

void main() {
    gl_Position = modelViewProjectionMatrix * position;
    tc = texcoord;
}

frag

#version 100
precision mediump float;
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;

varying vec2 tc;

void main() {
    vec3 red = vec3(texture2D(tex0, tc));
    vec3 green = vec3(texture2D(tex1, tc));
    vec3 blue = vec3(texture2D(tex2, tc));

    gl_FragColor = vec4(red.r,green.g,blue.b,1.0);
}

Thanks for the help!