Hello everyone,
I’m building OF as dll and everything works great until I use a shader. I could use ofFBO and send images from the host application to the dll which creates a window and displays it. Everything is good until I try to load a shader.
The same code running in a single executable works well. Therefore there must be some problem either in my dll main, which handles the window creation, loop and glRenderer, etc, or some settings in GLEW or GLFW must be changed in order to make things work.
To me it seems that GLEW is not initialized, but I can see OF going through the ofAppGLFWWindow::setup() call and loading GLEW as usual.
Any idea what I could be missing?
Here are some details on the modifications I have gone through to reach the current point and the crash.
//------------------------------------
ofShader.h requires a modification in order to point at the current rendrer (similar to ofFBO):
public:
void setRenderer(std::shared_ptr<ofBaseGLRenderer> GLrenderer) {
gl = GLrenderer;
}
private:
std::shared_ptr<ofBaseGLRenderer> gl;
then before loading any shader I pass the renderer used:
blendShader.setRenderer(gl);
then I get a crash when loading the shader like:
blendShader.setupShaderFromSource(GL_FRAGMENT_SHADER, myshader);
crashes at: ofShader.cpp
//--------------------------------------------------------------
void ofShader::checkAndCreateProgram() {
#ifndef TARGET_OPENGLES
if(GL_ARB_shader_objects) {
#else
if(ofIsGLProgrammableRenderer()){
#endif
if(program == 0) {
ofLogVerbose("ofShader") << "checkAndCreateProgram(): creating GLSL program";
--> program = glCreateProgram();
retainProgram(program);
}
} else {
ofLogError("ofShader") << "sorry, it looks like you can't run 'ARB_shader_objects'";
ofLogError("ofShader") << "please check the capabilites of your graphics card: http://www.ozone3d.net/gpu_caps_viewer";
}
}
Exception thrown at 0x0000000000000000 in explicitRendererExample_mine_debug.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
//------------------------------------
Things I’ve tried:
use ofGLProgrammableRenderer by setting:
ofGLFWWindowSettings settings;
settings.setGLVersion(3, 2);
then changing ofAppGLFWWindow.cpp:
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
by
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
as suggested in:
in ofConstants change:
#define GLEW_STATIC
by
#define GLEW_BUILD
as suggested in :
Followed this thread to expose C calls from the dll:
I’m using the explicit renderer described in:
My dll main.cpp:
#define DLLEXPORT __declspec(dllexport)
extern "C"
{
DLLEXPORT void createWindow(std::shared_ptr<ofMainLoop>& mainLoop, std::shared_ptr<GuiApp>& mainApp)
{
ofSetLogLevel(OF_LOG_VERBOSE);
ofLogToConsole();
std::cout << "Creating output window" << std::endl;
// ofInit();
// create output window
ofGLFWWindowSettings settings;
settings.setSize(screenW*2, screenH);
settings.setPosition(ofVec2f(1920, 0));
settings.resizable = false;
settings.decorated = false;
settings.windowMode = OF_WINDOW;
// settings.setGLVersion(3, 2); // set programmable renderer
mainLoop = make_shared<ofMainLoop>();
auto& mainWindow = mainLoop->createWindow(settings);
// auto& mainWindow = ofCreateWindow(settings);
// create output app
mainApp = make_shared<GuiApp>();
mainApp->window = mainWindow;
mainApp->gl = static_pointer_cast<ofBaseGLRenderer>(mainWindow->renderer());
mainLoop->run(mainWindow, mainApp);
std::cout << "Output window created" << std::endl;
}
DLLEXPORT void loop(std::shared_ptr<ofMainLoop>& mainLoop)
{
// mainLoop->loopOnce();
mainLoop->getCurrentWindow()->makeCurrent();
mainLoop->getCurrentWindow()->update();
mainLoop->getCurrentWindow()->draw();
ofAppGLFWWindow::pollEvents();
}
}