GLES/Raspberry Pi shaders on desktop?


#1

I’m working on a project that would be finally deployed on a raspberry pi but I wanted to develop the shaders required for it on my Mac.

While setting up the project with GLESWindowSettings on the Mac seems to work, the shaders themselves don’t - with errors on the headers of the .frag files and even on in vs attribute and out/ouput gl_fragColor and so on and precision highp float etc.

So, is it possible to run the same shaders on the Mac with rPi shaders or do I need separate versions for each platform with targets as #ifdef statements, etc?

What’s the best way to go about this?


#2

Edit: I’m trying to run the same oF app on my Mac and rPi so the main.cpp file and shaders need to be cross platform, if possible.


#4

Ha, I was just working on this all weekend! I wanted to do projection mapping on the pi with shaders.

I was successful see here: https://www.instagram.com/p/BfXUzW8jdvm/?hl=en

I put the code in a repo here: https://github.com/mhellar/rpiOfShaders

myshader is a minimum viable shader on the pi.

ProjMapShaders is the projection mapping program, you need to add OFXQuadwarp and OFXOMXplayer into addons.

I ran this on Jessie not Stretch!

I grabbed the shaders from http://glslsandbox.com/ which work on my mac

my main.cpp looked like this

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

int main()
{
	ofGLESWindowSettings settings;
	settings.glesVersion = 2;
	settings.width = 1200;
settings.height = 800;
	settings.windowMode = OF_FULLSCREEN;
	ofCreateWindow(settings);

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

//ofRunApp(std::make_shared<ofApp>());
}

And I needed the ifdef in the shaders like this example:

#ifdef GL_ES
precision mediump float;
#endif

#5

Hi, thanks for your response.

Doing main.cpp like this…

//========================================================================
int main( ){
    ofGLESWindowSettings settings;
    settings.glesVersion = 2;
    settings.width = 1024;
    settings.height = 768;
    settings.windowMode = OF_WINDOW;
    
    ofCreateWindow(settings);
    
    // this kicks off the running of my app
    // can be OF_WINDOW or OF_FULLSCREEN
    // pass in width and height too:
    ofRunApp(new ofApp());

}

And having my .frag file as simple as,

#ifdef GL_ES
precision mediump float;
#endif

void main()
{
	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

With the minimum ofApp::draw() doing -

shader.begin();
ofDrawRectangle(0, 0, ofGetWidth(), ofGetHeight());
shader.end();

seems to compile the app fine on the Mac without any errors, but there’s nothing in the window, nothing at all. Any clue?

From experience I have a feeling this’ll run fine on the Pi (will check tomorrow, don’t have access to it right now) but I’d like to develop cross platform - that’s the main aim at the moment.


#6

I need to try this on my Mac, will check tonight.


#7

From what I can tell after fooling around a bit more with my main.cpp and vert/frag files, if I do #ifdef #else statements with openGL(3,2) if the target is not GL_ES I maybe making some progress but it feels rather convoluted at the moment, there has to be a cleaner solution - unless of course GLES is not supported on Mac for some reason?


#8

Huh, so from what I can tell, GLES windowing is not supported on the Mac (or other desktop environments too?) - so is there a cross platform main.cpp + shader files that can be developed that run on all platforms without a lot of trouble?


#9

GLES is not supported on mac you need to use GL. there’s a few things that you can ifdef to make shaders multiplatform. OF does so internally for the default shaders in gl 3:

for example a vertex shader like:

#ifdef GLES
		precision mediump float;
		#define IN attribute
		#define OUT varying
		#define TEXTURE texture2D
		#define FRAG_COLOR gl_FragColor
#else
		#version 330
		#define IN in
		#define OUT out
		#define TEXTURE texture
 		#define FRAG_COLOR fragColor
		out vec4 fragColor
#endif

	uniform mat4 projectionMatrix;
	uniform mat4 modelViewMatrix;
	uniform mat4 textureMatrix;
	uniform mat4 modelViewProjectionMatrix;

	IN vec4  position;
	IN vec2  texcoord;
	IN vec4  color;
	IN vec3  normal;

	OUT vec4 v_color;
  	OUT vec2 v_texCoord;
        OUT vec4 v_normal;

	void main()
	{
		v_color = color;
		v_texCoord = texcoord;
		gl_Position = modelViewProjectionMatrix * position;
	}

with a fragment like:

#ifdef GLES
		precision mediump float;
		#define IN attribute
		#define OUT varying
		#define TEXTURE texture2D
		#define FRAG_COLOR gl_FragColor
#else
		#version 330
		#define IN in
		#define OUT out
		#define TEXTURE texture
 		#define FRAG_COLOR fragColor
		out vec4 fragColor
#endif
	uniform sampler2D tex;
	IN vec4 v_color;
  	IN vec2 v_texCoord;
        IN vec4 v_normal;

	void main()
	{
		FRAG_COLOR = TEXTURE(tex, v_texCoord) * v_color;
	}

will work in both opengl and gl es. with a main like:

int main( ){
    #ifdef TARGET_OPENGLES
        ofGLESWindowSettings settings;
        settings.glesVersion = 2;
    #else
        ofGLWindowSettings settings;
        settings.setGLVersion(3,3);
    #endif
    settings.width = 1024;
    settings.height = 768;
    settings.windowMode = OF_WINDOW;
    
    ofCreateWindow(settings);
    
    // this kicks off the running of my app
    // can be OF_WINDOW or OF_FULLSCREEN
    // pass in width and height too:
    ofRunApp(new ofApp());

}

since i’m using sampler2D in both desktop and GL ES you will need to call ofDisableArbTex() at the beginning of your setup function.

also you can move the common header to it’s own file, for example header.glsl, and use #pragma include header.glsl to include it in every shader


#10

:heart_eyes: thanks so much, this should solve all my issues!


#11

AS of the main, maybe this help:

https://gist.github.com/thomasvanta/d05c50a24c2afe0efde1


#12

Hi @arturo, this compiles and runs fine on the Pi. On the Mac however, I’m getting the following error.

[ error ] ofShader: setupShaderFromSource(): GL_VERTEX_SHADER shader failed to compile
[ error ] ofShader: GL_VERTEX_SHADER shader reports:
ERROR: 0:1: '' :  #version required and missing.
ERROR: 0:8: '' :  #version must occur before any other statement in the program
ERROR: 0:16: 'uniform' : syntax error: syntax error

[ error ] ofShader: GL_VERTEX_SHADER, offending line 1 :
	    1	#ifdef GLES
	    2			precision mediump float;
	    3			#define IN attribute

[ error ] ofShader: setupShaderFromSource(): GL_FRAGMENT_SHADER shader failed to compile
[ error ] ofShader: GL_FRAGMENT_SHADER shader reports:
ERROR: 0:1: '' :  #version required and missing.
ERROR: 0:8: '' :  #version must occur before any other statement in the program
ERROR: 0:15: 'uniform' : syntax error: syntax error

[ error ] ofShader: GL_FRAGMENT_SHADER, offending line 1 :
	    1	#ifdef GLES
	    2			precision mediump float;
	    3			#define IN attribute

[ error ] ofShader: checkProgramLinkStatus(): program failed to link
[ error ] ofShader: ofShader: program reports:
ERROR: One or more attached shaders not successfully compiled

I have called ofDisableArbTex() in the setup, I’m wondering if I’m missing something else, like setting up the programmable renderer or something?


#13

Actually my bad, I had the old version running on the Pi - this doesn’t work on the Pi either…

[warning] ofShader: GL_VERTEX_SHADER shader reports:
Compiled
[warning] %extensions%
precision mediump float;
#define IN attribute
#define OUT varying
#define TEXTURE texture2D
#define TARGET_OPENGLES
uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 textureMatrix; uniform mat4 modelViewProjectionMatrix; uniform float usingTexture; uniform float usingColors; uniform vec4 globalColor; IN vec4 position; IN vec4 color; IN vec4 normal; IN vec2 texcoord; OUT vec4 colorVarying; OUT vec2 texCoordVarying; void main(){ gl_Position = modelViewProjectionMatrix * position; if(usingTexture>.5) texCoordVarying = (textureMatrix*vec4(texcoord.x,texcoord.y,0,1)).xy; if(usingColors>.5) colorVarying = color; else colorVarying = globalColor; }

[warning] ofShader: GL_FRAGMENT_SHADER shader reports:
Compiled
[warning] %extensions%
precision mediump float;
#define IN varying
#define OUT
#define TEXTURE texture2D
#define FRAG_COLOR gl_FragColor
#define TARGET_OPENGLES
uniform sampler2D src_tex_unit0; uniform float usingTexture; uniform float bitmapText; IN vec4 colorVarying; IN vec2 texCoordVarying; void main(){ vec4 tex; if(usingTexture>.5){ tex = TEXTURE(src_tex_unit0, texCoordVarying); if(bitmapText>.5 && tex.a < 0.5){ discard; }else{ FRAG_COLOR = colorVarying*tex; } }else{ FRAG_COLOR = colorVarying; } }

[ error ] ofShader: checkProgramLinkStatus(): program failed to link
[ error ] ofShader: ofShader: program reports:
ERROR:LEX/PARSE-1 (vertex shader, line 1) Syntax error
glGetError 0x502
[warning] ofShader: GL_VERTEX_SHADER shader reports:
Compiled
[warning] #ifdef GLES
		precision mediump float;
		#define IN attribute
		#define OUT varying
		#define TEXTURE texture2D
		#define FRAG_COLOR gl_FragColor
#else
		#version 330
		#define IN in
		#define OUT out
		#define TEXTURE texture
 		#define FRAG_COLOR fragColor
		out vec4 fragColor
#endif

	uniform mat4 projectionMatrix;
	uniform mat4 modelViewMatrix;
	uniform mat4 textureMatrix;
	uniform mat4 modelViewProjectionMatrix;

	IN vec4  position;
	IN vec2  texcoord;
	IN vec4  color;
	IN vec3  normal;

	OUT vec4 v_color;
  OUT vec2 v_texCoord;
  OUT vec4 v_normal;

	void main()
	{
		v_color = color;
		v_texCoord = texcoord;
		gl_Position = modelViewProjectionMatrix * position;
	}

[warning] ofShader: GL_FRAGMENT_SHADER shader reports:
Compiled
[warning] #ifdef GLES
		precision mediump float;
		#define IN attribute
		#define OUT varying
		#define TEXTURE texture2D
		#define FRAG_COLOR gl_FragColor
#else
		#version 330
		#define IN in
		#define OUT out
		#define TEXTURE texture
 		#define FRAG_COLOR fragColor
		out vec4 fragColor
#endif
	uniform sampler2D tex;
	IN vec4 v_color;
  IN vec2 v_texCoord;
  IN vec4 v_normal;

	void main()
	{
		FRAG_COLOR = vec4(1.0, 0.0, 0.0, 1.0);
	}

[ error ] ofShader: checkProgramLinkStatus(): program failed to link
[ error ] ofShader: ofShader: program reports:
ERROR:PREPROCESSOR-5 (vertex shader, line 8) #version must be the 1st directive/statement in a program

#14

mmh yeah you need to move the #version 330 to the first line for this to work on desktop but then it won’t work on gles.

in the core we create that header dinamically in the program and the append the source by reading it from the file then pass the whole thing to the shader to compile

but something like:

#pragma include version.glsl

where version.glsl is:

#version 330

for desktop and an empty file for GLES should work since includes is parsed before compiling


#15

Weird… still no luck on either platform.

Mac:

[ error ] ofShader: setupShaderFromSource(): GL_VERTEX_SHADER shader failed to compile
[ error ] ofShader: GL_VERTEX_SHADER shader reports:
ERROR: 0:19: 'uniform' : syntax error: syntax error

[ error ] ofShader: GL_VERTEX_SHADER, offending line 19 :
	   17	#endif
	   18	
	   19		uniform mat4 projectionMatrix;
	   20		uniform mat4 modelViewMatrix;
	   21		uniform mat4 textureMatrix;

[ error ] ofShader: setupShaderFromSource(): GL_FRAGMENT_SHADER shader failed to compile
[ error ] ofShader: GL_FRAGMENT_SHADER shader reports:
ERROR: 0:19: 'uniform' : syntax error: syntax error

[ error ] ofShader: GL_FRAGMENT_SHADER, offending line 19 :
	   17	#endif
	   18	
	   19		uniform sampler2D tex;
	   20		IN vec4 v_color;
	   21	  IN vec2 v_texCoord;

[ error ] ofShader: checkProgramLinkStatus(): program failed to link
[ error ] ofShader: ofShader: program reports:
ERROR: One or more attached shaders not successfully compiled

#16

Pi:

[warning] ofShader: GL_VERTEX_SHADER shader reports:
Compiled
[warning] %extensions%
precision mediump float;
#define IN attribute
#define OUT varying
#define TEXTURE texture2D
#define TARGET_OPENGLES
uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 textureMatrix; uniform mat4 modelViewProjectionMatrix; uniform float usingTexture; uniform float usingColors; uniform vec4 globalColor; IN vec4 position; IN vec4 color; IN vec4 normal; IN vec2 texcoord; OUT vec4 colorVarying; OUT vec2 texCoordVarying; void main(){ gl_Position = modelViewProjectionMatrix * position; if(usingTexture>.5) texCoordVarying = (textureMatrix*vec4(texcoord.x,texcoord.y,0,1)).xy; if(usingColors>.5) colorVarying = color; else colorVarying = globalColor; }

[warning] ofShader: GL_FRAGMENT_SHADER shader reports:
Compiled
[warning] %extensions%
precision mediump float;
#define IN varying
#define OUT
#define TEXTURE texture2D
#define FRAG_COLOR gl_FragColor
#define TARGET_OPENGLES
uniform sampler2D src_tex_unit0; uniform float usingTexture; uniform float bitmapText; IN vec4 colorVarying; IN vec2 texCoordVarying; void main(){ vec4 tex; if(usingTexture>.5){ tex = TEXTURE(src_tex_unit0, texCoordVarying); if(bitmapText>.5 && tex.a < 0.5){ discard; }else{ FRAG_COLOR = colorVarying*tex; } }else{ FRAG_COLOR = colorVarying; } }

[ error ] ofShader: checkProgramLinkStatus(): program failed to link
[ error ] ofShader: ofShader: program reports:
ERROR:LEX/PARSE-1 (vertex shader, line 1) Syntax error
glGetError 0x502
[warning] ofShader: GL_VERTEX_SHADER shader reports:
Compiled
[warning] //This file should be empty on the Pi


#ifdef GLES
		precision mediump float;
		#define IN attribute
		#define OUT varying
		#define TEXTURE texture2D
		#define FRAG_COLOR gl_FragColor
#else
		// #version 330
		#define IN in
		#define OUT out
		#define TEXTURE texture
 		#define FRAG_COLOR fragColor
		out vec4 fragColor
#endif

	// uniform mat4 projectionMatrix;
	uniform mat4 modelViewMatrix;
	uniform mat4 textureMatrix;
	uniform mat4 modelViewProjectionMatrix;

	IN vec4  position;
	IN vec2  texcoord;
	IN vec4  color;
	IN vec3  normal;

	OUT vec4 v_color;
  OUT vec2 v_texCoord;
  OUT vec4 v_normal;

	void main()
	{
		v_color = color;
		v_texCoord = texcoord;
		gl_Position = modelViewProjectionMatrix * position;
	}

[warning] ofShader: GL_FRAGMENT_SHADER shader reports:
Compiled
[warning] //This file should be empty on the Pi


#ifdef GLES
		precision mediump float;
		#define IN attribute
		#define OUT varying
		#define TEXTURE texture2D
		#define FRAG_COLOR gl_FragColor
#else
		// #version 330
		#define IN in
		#define OUT out
		#define TEXTURE texture
 		#define FRAG_COLOR fragColor
		out vec4 fragColor
#endif

	uniform sampler2D tex;
	IN vec4 v_color;
  IN vec2 v_texCoord;
  IN vec4 v_normal;

	void main()
	{
		FRAG_COLOR = vec4(1.0, 0.0, 0.0, 1.0);
	}

[ error ] ofShader: checkProgramLinkStatus(): program failed to link
[ error ] ofShader: ofShader: program reports:
ERROR:LEX/PARSE-1 (vertex shader, line 16) Syntax error

#17

Line 16 on the vertex shader shouldn’t even be trying to compile on the Pi as it’s part of the ifdef/else/endif part of the code… and on the Mac side of things, how is loading uniforms a problem? I’m quite confused at the moment…

The files are here if you want to check:

(the version.glsl file is unique to the platforms so it’s on gitignore, you’ll need that if you’re trying to run this)


#18

Ok I got this working on the Mac (finally!) there were some semicolon errors and I’ve put all the header code in headerVert.glsl and headerFrag.glsl and keeping it different for the different platforms and importing those in with #pragma include "headerVert.glsl" etc. Gonna try it on the rPi in a few hours let’s see how it goes!


#19

great you got it working, please post back the results so others can have them as reference, i never really tested what i posted so having a working solution would be really useful


#20

Yup, let me test it on the Pi and I shall share the files :slight_smile:


#21

Alright! Needed more fixes but it’s now fully up and running (haven’t tested textures yet - it’s only a very simple example).

I’ve uploaded a example project here with directions on how to setup the header files.

thanks a lot @arturo for pointing me in the right direction, had to look a bit more closely at the dynamic headers that are in the oF code and it’s an implementation based on that :slight_smile:

Tested with 0.9.8 on MacOS and Nightly on Raspbian Stretch - if someone can run this on Windows and confirm it runs it’ll be great!