Shader setupShaderFromSource not working


#1

Hello friends I need help here.

First my shader works if I load it from file

shader.load( "shaderVert.c", "shaderFrag.c" ); //load from file

I am trying to load it from string because I dont want to load it from file.

I tried this but it doest not work.

shader.setupShaderFromSource(GL_VERTEX_SHADER, R"(
#version 120
#extension GL_ARB_texture_rectangle : enable
#extension GL_EXT_gpu_shader4 : enable

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

)");
shader.setupShaderFromSource(GL_FRAGMENT_SHADER, R"(
#version 120
#extension GL_ARB_texture_rectangle : enable
#extension GL_EXT_gpu_shader4 : enable
uniform sampler2DRect texture0;

void main(){
	vec2 pos = gl_TexCoord[0].xy;
	vec4 color = texture2DRect(texture0, pos);
	color.r = 1.0 - color.r;
	gl_FragColor = color;
}
)");

whats wrong with my code? I need to load it from string I dont want load from file.


#2

Hi! In gl/multiTextureShaderExample/src/ofApp.cpp it mentions:

// There are 3 of ways of loading a shader:
//
//  1 - Using just the name of the shader and ledding ofShader look for .frag and .vert: 
//      Ex.: shader.load( "myShader");
//
//  2 - Giving the right file names for each one: 
//      Ex.: shader.load( "myShader.vert","myShader.frag");
//
//  3 - And the third one is passing the shader programa on a single string;
//      In this particular example we are using STRINGIFY which is a handy macro

Which works like this:

#include "ofApp.h"

#define STRINGIFY(A) #A
...

    std::string myFragmentShader = STRINGIFY(
        // your shader program goes here
    );

Note that the macro can fail in some cases:


#3

R" should work as well, STRINGIFY was needed before c++11 where there were no support for multiline strings

When loading shaders from source like that you have to finally link them by calling shader.linkProgram()

If you are using 0.10 you can also use ofShaderSettings to load from source as in:

ofShaderSettings settings;
settings.shaderSources[GL_VERTEX_SHADER] = R"(...
)":

settings.shaderSources[GL_VERTEX_FRAGMENT] = R"(...
)":
shader.setup(settings);

#4

UPDATE: I’m relatively sure now that this is a bug, so I’ve file it here

Hey, I’m reawakening this thread because I think I have a very similar issue :), though specifically with #versioned shaders. (e.g. 150).

If I load the shaders from file, it works fine. If I setup from source via stringify or R", it compiles & links fine, but I see nothing. I also dump the strings to the console to compare, and they look fine. I couldn’t track down the issue. (Actually it seems to be displaying something, maybe it’s related to the default uniforms like modelViewProjectionMatrix etc not being passed correctly or something?)

I did try:

  1. manually adding shader.setUniformMatrix4f("modelViewProjectionMatrix", ofGetCurrentMatrix(OF_MATRIX_PROJECTION) * ofGetCurrentMatrix(OF_MATRIX_MODELVIEW));
    but this made no difference at all to either shader.
  2. renaming the uniform modelViewProjectionMatrix to mvp and setting it manually to ofGetCurrentMatrix(OF_MATRIX_PROJECTION) * ofGetCurrentMatrix(OF_MATRIX_MODELVIEW)). In this case shader0 (loaded from file) still showed the correct content, but was offset by half (excluding the plane’s position. is this a bug in core or user error on my side?) However shader1 is still not showing anything.

This is openFrameworks 0.10.1 on ubuntu 18.04.1 with Qt Creator 4.6.2

// vert shader
#version 150

uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
out vec2 varyingtexcoord;

void main(){
    varyingtexcoord = texcoord;
    gl_Position = modelViewProjectionMatrix * position;
}
// frag shader
#version 150

uniform sampler2DRect tex0;
in vec2 varyingtexcoord;
out vec4 outputColor;

void main()
{
    outputColor = texture(tex0, varyingtexcoord);
}
// main.cpp
#include "ofMain.h"

#define STRINGIFY(A) string("#version 150\n")+#A

class ofApp : public ofBaseApp{
public:
    ofShader shader0;   // loaded from file <-- WORKS!
    ofShader shader1;   // setup from (identical) source <-- COMPILES, BUT NO OUTPUT!
    ofVideoGrabber cam;
    ofPlanePrimitive quad;

    //--------------------------------------------------------------
    // vertex shader source
#ifdef STRINGIFY
    string vertSource = STRINGIFY(
            uniform mat4 modelViewProjectionMatrix;
            in vec4 position;
            in vec2 texcoord;
            out vec2 varyingtexcoord;

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

    //--------------------------------------------------------------
    // fragment shader source
    string fragSource = STRINGIFY(
            uniform sampler2DRect tex0;
            in vec2 varyingtexcoord;
            out vec4 outputColor;

            void main()
            {
                outputColor = texture(tex0, varyingtexcoord);
            }

     );
#else
    string vertSource = R"(
            #version 150

            uniform mat4 modelViewProjectionMatrix;
            in vec4 position;
            in vec2 texcoord;
            out vec2 varyingtexcoord;

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

      )";

    //--------------------------------------------------------------
    // fragment shader source
    string fragSource = R"(
            #version 150

            uniform sampler2DRect tex0;
            in vec2 varyingtexcoord;
            out vec4 outputColor;

            void main()
            {
                outputColor = texture(tex0, varyingtexcoord);
            }
     )";
#endif


    //--------------------------------------------------------------
    void setup(){
        ofBackground(50);
        cam.setup(320, 240);

        quad.set(cam.getWidth(), -cam.getHeight(), 2, 2); // flip vertically
        quad.setPosition(cam.getWidth()/2, cam.getHeight()/2, 0);
        quad.mapTexCoords(1, 1, cam.getWidth(), cam.getHeight());

        // setup shader0 from files
        shader0.load("pass");

        // setup shader1 from source
        ofLogNotice() << "//=== vertSource \n" << vertSource;
        ofLogNotice() << "//=== fragSource \n" << fragSource;
        shader1.setupShaderFromSource(GL_VERTEX_SHADER, vertSource);
        shader1.setupShaderFromSource(GL_FRAGMENT_SHADER, fragSource);
        shader1.linkProgram();
    }

    //--------------------------------------------------------------
    void drawShader(ofShader& s) {
        s.begin();
        s.setUniformTexture("tex0", cam.getTexture(), 0);
        quad.draw();
        s.end();
    }

    //--------------------------------------------------------------
    void draw(){
        cam.update();

        drawShader(shader0);

        ofPushMatrix();
        ofTranslate(0, cam.getHeight());
        drawShader(shader1);
        ofPopMatrix();
    }
};

int main( ){
    ofGLFWWindowSettings settings;
    settings.setGLVersion(3, 2);
    settings.setSize(1024, 768);
    ofCreateWindow(settings);
    ofRunApp(new ofApp());
}