Dynamic_cast class ofShader load

Hi,

I’m trying to get a collection of ofShader working.

I have created a ShaderManager class, and ShaderHandler class, and I’m trying to do a dynamic_cast on class, but it throw an error: when loading a shader file, the app crashes:

ofApp.h :

#pragma once

#include "ofMain.h"

class ShaderManager{
    public :
    ShaderManager(){
        
    }
    void setup(){
        cout << "setup Manager" << endl;
    }
    virtual ~ShaderManager(){};
};

class ShaderHandler : ShaderManager {
    public :
    ShaderHandler(){
        
    }
    
    ofShader shader;
    
    void setup(){
        
        cout << "setup Handler" << endl;
        
        shader.load("shader.vert", "shader.frag");
    }
    ~ShaderHandler(){};
};


class ofApp : public ofBaseApp{
	public:
		void setup();
		void update();
		void draw();
    
    
    
    ShaderManager* sManager1;
    ShaderHandler* sManager2;
    
};

ofApp.cpp :


#include "ofApp.h"

void ofApp::setup(){
    sManager1->setup();
    
    ShaderHandler* sManager3 = dynamic_cast<ShaderHandler*>(sManager1);
    sManager3->setup();
};

void ofApp::update(){
};

void ofApp::draw(){
};

Log :

2019-03-18 14:31:57.479119+0000 dynamicCastingDebug[85706:15317883] [default] Unable to load Info.plist exceptions (eGPUOverrides)
2019-03-18 14:31:57.864544+0000 dynamicCastingDebug[85706:15317882] MessageTracer: Falling back to default whitelist
setup Manager
setup Handler
dynamicCastingDebug was compiled with optimization - stepping may behave oddly; variables may not be available.
(lldb) 

How can I get the cast from ShaderManager to ShaderHandler and load my shaders?

I’m on 10.0.0-patch, OSX 10.14.3.

Thks,

P

I think thats because you inherit privately from your ShaderManager. Could you try adding the public keyword: class ShaderHandler : public ShaderManager?

Hi T,

I just tried, no luck.
I’m not sure I’m doing dynamic casting right…

Thanks though,

++
P

another try:
i should have studied c++ and pointers more carefully.
I am not quite sure what you are trying to do. But i think if you are casting it to a derived class then it needs to be initialised as such, e.g. ofApp() : sManager1(new ShaderHandler){}

1 Like

thanks Thomas,

I kind of drop the dynamic casting as it seems to not be the best option really…

it seems like the right way was to declare it in the ofApp.h like this :

ShaderManager* sManager1 = new ShaderHandler();
ShaderHandler* sManager2;

then in ofApp.cpp :

    sManager2 = dynamic_cast < ShaderHandler* > (sManager1);

I went for an array of ShaderManager and an array of ShaderHandler…

Thanks for your help though.

Best,

P

Hi @pierre_tardif00 I think that you were not creating the object, thus the objects were null.
Also, the point of the dynamic_cast is that it will check if the casting is done properly so you should add an if statement after it.
Then, you are trying to cast base class object into a derived one but you have not created it.
You might want to read this

include "ofApp.h"

void ofApp::setup(){

//   sManager1 = new ShaderManager(); //this will create a new ShaderManager but not a ShaderHandler, thus it will not be able to cast into it.

  sManager1 = new ShaderHandler(); //this will create a new ShaderHandler, which will be stored in the ShaderManager pointer and the dynamic cast should work.

    sManager1->setup();
    
    ShaderHandler* sManager3 = dynamic_cast<ShaderHandler*>(sManager1);
    if(sManager3){ // this will check if the dynamic_cast was valid. 
        sManager3->setup();
    }
}

Last but not least you should use virtual functions when dealing with inheritance, which becomes specially useful when doing this kind of casting stuff.

So, I would write it like this:

class ShaderManager{
    public :
    ShaderManager(){
        
    }
    virtual void setup(){
        cout << "setup Manager" << endl;
    }
    virtual ~ShaderManager(){};
};

class ShaderHandler : ShaderManager {
    public :
    ShaderHandler(){
        
    }
    
    ofShader shader;
    
    virtual void setup() override{ // the override keyword is just for safe checking that you are 
//overriding an existing function and not declaring a new one, which can save you lots of headaches 
//if you've  misspelled the function's name 
        
        cout << "setup Handler" << endl;
        
        shader.load("shader.vert", "shader.frag");
    }
//    ~ShaderHandler(){}; //if you are not doing anything on the destructor just dont declare it. if you do, make sure it is virtual too.
};

Hi @roymacdonald,

Ok thank you, this worked, :slight_smile: .

++

1 Like