Page 1 of 2

GLFW integration problem

Posted: Fri Jan 19, 2018 4:35 pm
by madga
Hi everyone.

I'm trying to use both Irrlicht and GLFW in my game. I create a Window with GLFW like this:

Code: Select all

glfwInit();
 
    glfwSetTime(0);
 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 
 
    glfwWindowHint(GLFW_SAMPLES, 0);
    glfwWindowHint(GLFW_RED_BITS, 4);
    glfwWindowHint(GLFW_GREEN_BITS, 4);
    glfwWindowHint(GLFW_BLUE_BITS, 4);
    glfwWindowHint(GLFW_ALPHA_BITS, 1);
    glfwWindowHint(GLFW_DEPTH_BITS, 24);
    glfwWindowHint(GLFW_STENCIL_BITS, 1);
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
 
    // Create a GLFWwindow object
    GLFWwindow* window = glfwCreateWindow(800, 800, "example3", nullptr, nullptr);
    if (window == nullptr) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    
    glfwMakeContextCurrent(window);
 
And then i initialize Irrlicht like this:

Code: Select all

// Initialize irrlicht
    SIrrlichtCreationParameters param;
    param.DeviceType = E_DEVICE_TYPE::EIDT_X11;
    param.DriverType = video::E_DRIVER_TYPE::EDT_OPENGL;
    param.WindowId = reinterpret_cast<void*>(glfwGetX11Window(window));
    param.IgnoreInput = true;
IrrlichtDevice* device = createDeviceEx(param);
 
But when i execute i get this errors:
Creating X window...
X Error: BadMatch (invalid parameter attributes)
From call : unknown
X Error: GLXBadDrawable
From call : unknown
Context activation failed.
It seems the error came from this function:
glXCreateNewContext in CIrrDeviceLinux or in CGLXManager depending on the version of irrlicht

There is any way to fix it?

Thank you!

Re: GLFW integration problem

Posted: Sun Jan 21, 2018 2:42 pm
by CuteAlien
"BadMatch is generated if the context to be created would not share the address space or the screen of the context specified by render_type." Unfortuntely I'm not that familiar with X11, so no idea right now what that really means. I guess I have to plan for learning more about X11 at some point.

Re: GLFW integration problem

Posted: Sun Jan 21, 2018 10:12 pm
by devsh
From CIrrDeviceLinux.cpp (may differ from vanilla Irrlicht)

Code: Select all

 
    if (!CreationParams.WindowId)
    {
        // create new Window
        // Remove window manager decoration in fullscreen
        attributes.override_redirect = CreationParams.Fullscreen;
        window = XCreateWindow(display,
                RootWindow(display, visual->screen),
                0, 0, Width, Height, 0, visual->depth,
                InputOutput, visual->visual,
                CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
                &attributes);
        XMapRaised(display, window);
        CreationParams.WindowId = (void*)window;
        Atom wmDelete;
        wmDelete = XInternAtom(display, wmDeleteWindow, True);
        XSetWMProtocols(display, window, &wmDelete, 1);
        if (CreationParams.Fullscreen)
        {
            XSetInputFocus(display, window, RevertToParent, CurrentTime);
            int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
                GrabModeAsync, CurrentTime);
            IrrPrintXGrabError(grabKb, "XGrabKeyboard");
            int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
                GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
            IrrPrintXGrabError(grabPointer, "XGrabPointer");
            XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
        }
    }
    else
    {
        // attach external window
        window = (Window)CreationParams.WindowId;
        if (!CreationParams.IgnoreInput)
        {
            XCreateWindow(display,
                    window,
                    0, 0, Width, Height, 0, visual->depth,
                    InputOutput, visual->visual,
                    CWBorderPixel | CWColormap | CWEventMask,
                    &attributes);
        }
        XWindowAttributes wa;
        XGetWindowAttributes(display, window, &wa);
        CreationParams.WindowSize.Width = wa.width;
        CreationParams.WindowSize.Height = wa.height;
        CreationParams.Fullscreen = false;
        ExternalWindow = true;
    }
There's some code before that and it looks like:
A) if you have fullscreen enabled it will gently caress with your window
B) it creates an OpenGL context for your anyway, and makes it current so you will loose your glfw created one (hence the error from glXCreateNewContext)

This part is irrelevant for you since you ignore input.
On top of the evil of B, to create a context Irrlicht must choose a visual (query OpenGL framebuffer formats) and if you dont ignore inputs

Code: Select all

 
        if (!CreationParams.IgnoreInput)
        {
            XCreateWindow(display,
                    window,
                    0, 0, Width, Height, 0, visual->depth,
                    InputOutput, visual->visual,
                    CWBorderPixel | CWColormap | CWEventMask,
                    &attributes);
        }
it will create another X11 window on top to get them with the queried visual (for the Irrlicht OpenGL context).


Another thing is that with GLFW you're creating a forward compatible context (bad idea) and a core profile context (good idea, but more on that).

Vanilla Irrlicht CANNOT USE A CORE CONTEXT WINDOW, because IT STILL RUNS ON COMPATIBILITY PROFILE OPENGL.
Nothing will draw and you will get OpenGL errors left and right.


P.S. GLFW resizable is not going to work with irrlicht.

P.P.S. there are no 4bit color formats so set all window hints to at least 8.

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 12:35 am
by madga
devsh wrote:From CIrrDeviceLinux.cpp (may differ from vanilla Irrlicht)

Code: Select all

 
    if (!CreationParams.WindowId)
    {
        // create new Window
        // Remove window manager decoration in fullscreen
        attributes.override_redirect = CreationParams.Fullscreen;
        window = XCreateWindow(display,
                RootWindow(display, visual->screen),
                0, 0, Width, Height, 0, visual->depth,
                InputOutput, visual->visual,
                CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
                &attributes);
        XMapRaised(display, window);
        CreationParams.WindowId = (void*)window;
        Atom wmDelete;
        wmDelete = XInternAtom(display, wmDeleteWindow, True);
        XSetWMProtocols(display, window, &wmDelete, 1);
        if (CreationParams.Fullscreen)
        {
            XSetInputFocus(display, window, RevertToParent, CurrentTime);
            int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
                GrabModeAsync, CurrentTime);
            IrrPrintXGrabError(grabKb, "XGrabKeyboard");
            int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
                GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
            IrrPrintXGrabError(grabPointer, "XGrabPointer");
            XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
        }
    }
    else
    {
        // attach external window
        window = (Window)CreationParams.WindowId;
        if (!CreationParams.IgnoreInput)
        {
            XCreateWindow(display,
                    window,
                    0, 0, Width, Height, 0, visual->depth,
                    InputOutput, visual->visual,
                    CWBorderPixel | CWColormap | CWEventMask,
                    &attributes);
        }
        XWindowAttributes wa;
        XGetWindowAttributes(display, window, &wa);
        CreationParams.WindowSize.Width = wa.width;
        CreationParams.WindowSize.Height = wa.height;
        CreationParams.Fullscreen = false;
        ExternalWindow = true;
    }
There's some code before that and it looks like:
A) if you have fullscreen enabled it will gently caress with your window
B) it creates an OpenGL context for your anyway, and makes it current so you will loose your glfw created one (hence the error from glXCreateNewContext)

This part is irrelevant for you since you ignore input.
On top of the evil of B, to create a context Irrlicht must choose a visual (query OpenGL framebuffer formats) and if you dont ignore inputs

Code: Select all

 
        if (!CreationParams.IgnoreInput)
        {
            XCreateWindow(display,
                    window,
                    0, 0, Width, Height, 0, visual->depth,
                    InputOutput, visual->visual,
                    CWBorderPixel | CWColormap | CWEventMask,
                    &attributes);
        }
it will create another X11 window on top to get them with the queried visual (for the Irrlicht OpenGL context).


Another thing is that with GLFW you're creating a forward compatible context (bad idea) and a core profile context (good idea, but more on that).

Vanilla Irrlicht CANNOT USE A CORE CONTEXT WINDOW, because IT STILL RUNS ON COMPATIBILITY PROFILE OPENGL.
Nothing will draw and you will get OpenGL errors left and right.


P.S. GLFW resizable is not going to work with irrlicht.

P.P.S. there are no 4bit color formats so set all window hints to at least 8.
Thank you. I'll try that. Also, do you think it would be easier (or better) to create a GLFW driver instead of using CIrrDeviceLinux?

I have created an SDL2 driver (modifying current SDL driver) so i know how it works more or less.

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 5:42 pm
by madga
It didn't work well, so I created a GLFW3 driver and now i have it working.

GLFW patch for Irrlicht (rev5600): https://pastebin.com/yxXgjFCX (link updated, input was broken)
(Without joysticks for the moment)

Also I have updated the SDL driver for using SDL2 (based on the patch released by Octodad team in this forum).

SDL2 patch for Irrlicht (rev5600): https://pastebin.com/Ws7SQUTQ

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 7:13 pm
by kas1e
@madga
SDL2 patch for Irrlicht (rev5600): https://pastebin.com/Ws7SQUTQ
I assume that patch can be applied on ogl-es r5600 branch as well ?

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 7:53 pm
by madga
kas1e wrote:@madga
SDL2 patch for Irrlicht (rev5600): https://pastebin.com/Ws7SQUTQ
I assume that patch can be applied on ogl-es r5600 branch as well ?
I think so, i don't know the differences between both branches. Although I think I have created it over ogl-es branch, i don't know how to use SVN well, I usually work with git.

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 9:15 pm
by kas1e
@Madga
I manually apply this sdl2 patch over 1.8.4 release, and while it all builds and co, i have black window only :) Allthrough changed files in diff really the same on 99%, strange ..

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 9:51 pm
by madga
kas1e wrote:@Madga
I manually apply this sdl2 patch over 1.8.4 release, and while it all builds and co, i have black window only :) Allthrough changed files in diff really the same on 99%, strange ..
Do you have SDL_CreateWindow or SDL_SetVideoMode in CIrrDeviceSDL.cpp? (In the method createWindow())

Re: GLFW integration problem

Posted: Mon Jan 22, 2018 10:00 pm
by kas1e
@madga
Do you have SDL_CreateWindow or SDL_SetVideoMode in CIrrDeviceSDL.cpp? (In the method createWindow())
Yeah of course. Windows creates, its just everything black inside. I just apply patch's code via ifdefs manually as it not 100% the same by lines in 1.8.4 version , but code the same of course. Check this out plz, maybe i sucked a bit somewhere : https://pastebin.com/jYevSv9q

I also replace part with SDL_GetWMInfo on SDL_GetWindowWMInfo, check this out aswell, but that part surely works, as on 01.helloworld example i have sdl2 window opens, info in shell that i use sdl2.0.5, then window opens with IrrLicht title, and its fully black.

ps. And i trying software renderer , btw, to be sure that SDL2 replacement works at all, before start tests with ogl/ogles
ps2. And for sake of tests trying to apply your patch on pure r6000, and on ogl-es r6000, last one full of errors, first one more or less ok:

Code: Select all

 
$ patch --binary -p1 < sdl2_patch_for_5600rev.txt
patching file include/IrrCompileConfig.h
patching file include/SIrrCreationParameters.h
patching file source/Irrlicht/CIrrDeviceSDL.cpp
patching file source/Irrlicht/CIrrDeviceSDL.h
patching file source/Irrlicht/COpenGLDriver.cpp
patch unexpectedly ends in middle of line
Hunk #4 succeeded at 323 with fuzz 1.
 
Can't test at moment if r6000 also will give black window with sdl2..

Re: GLFW integration problem

Posted: Tue Jan 23, 2018 12:14 am
by madga
kas1e wrote:@madga
Do you have SDL_CreateWindow or SDL_SetVideoMode in CIrrDeviceSDL.cpp? (In the method createWindow())
Yeah of course. Windows creates, its just everything black inside. I just apply patch's code via ifdefs manually as it not 100% the same by lines in 1.8.4 version , but code the same of course. Check this out plz, maybe i sucked a bit somewhere : https://pastebin.com/jYevSv9q

I also replace part with SDL_GetWMInfo on SDL_GetWindowWMInfo, check this out aswell, but that part surely works, as on 01.helloworld example i have sdl2 window opens, info in shell that i use sdl2.0.5, then window opens with IrrLicht title, and its fully black.

ps. And i trying software renderer , btw, to be sure that SDL2 replacement works at all, before start tests with ogl/ogles
ps2. And for sake of tests trying to apply your patch on pure r6000, and on ogl-es r6000, last one full of errors, first one more or less ok:

Code: Select all

 
$ patch --binary -p1 < sdl2_patch_for_5600rev.txt
patching file include/IrrCompileConfig.h
patching file include/SIrrCreationParameters.h
patching file source/Irrlicht/CIrrDeviceSDL.cpp
patching file source/Irrlicht/CIrrDeviceSDL.h
patching file source/Irrlicht/COpenGLDriver.cpp
patch unexpectedly ends in middle of line
Hunk #4 succeeded at 323 with fuzz 1.
 
Can't test at moment if r6000 also will give black window with sdl2..
It seems it fails patching COpenGLDriver.cpp.
You have to patch it to add the buffer swap

Re: GLFW integration problem

Posted: Tue Jan 23, 2018 7:01 am
by kas1e
Yeah, doing so from begining when apply patch by hands line by line, and still black window.. But ogl file should'n have impact on software rendering ?

Re: GLFW integration problem

Posted: Tue Jan 23, 2018 12:00 pm
by madga
kas1e wrote:Yeah, doing so from begining when apply patch by hands line by line, and still black window.. But ogl file should'n have impact on software rendering ?
Mmm idk, I used OpenGL rendering.

params.DeviceType = E_DEVICE_TYPE::EIDT_SDL;
params.DriverType = video::E_DRIVER_TYPE::EDT_OPENGL;

Re: GLFW integration problem

Posted: Tue Jan 23, 2018 1:32 pm
by kas1e
@madga
Rereading again code of your patch, it seems too much hardcoded to opengl only, so no gles, no software, no burningvideo will works with your patch, sadly :(

I can be wrong of course, as not expert, but for example in that decsrutctor: CIrrDeviceSDL::~CIrrDeviceSDL()
You do SDL_GL_DeleteContext( gContext ); , which mean OpenGL in any case, while probably it should be like this:

Code: Select all

 
#ifdef _IRR_COMPILE_WITH_OPENGL_
        SDL_GL_DeleteContext( gContext );
#endif
        gContext = NULL;
        SDL_DestroyWindow( gWindow );
        gWindow = NULL;
 
Also at end of CIrrDeviceSDL::createWindow(), we do in your patch:

Code: Select all

 
    if (!gContext)
        gContext = SDL_GL_CreateContext(gWindow);
 
Which is also mean that we create opengl context in any case, even, if we in software, or in burning rendering.

In other words, to make patch be all-renderers-friendly, there needs some ifdefs and stuff, imho..

Re: GLFW integration problem

Posted: Tue Jan 23, 2018 4:54 pm
by madga
kas1e wrote:@madga
Rereading again code of your patch, it seems too much hardcoded to opengl only, so no gles, no software, no burningvideo will works with your patch, sadly :(

I can be wrong of course, as not expert, but for example in that decsrutctor: CIrrDeviceSDL::~CIrrDeviceSDL()
You do SDL_GL_DeleteContext( gContext ); , which mean OpenGL in any case, while probably it should be like this:

Code: Select all

 
#ifdef _IRR_COMPILE_WITH_OPENGL_
        SDL_GL_DeleteContext( gContext );
#endif
        gContext = NULL;
        SDL_DestroyWindow( gWindow );
        gWindow = NULL;
 
Also at end of CIrrDeviceSDL::createWindow(), we do in your patch:

Code: Select all

 
    if (!gContext)
        gContext = SDL_GL_CreateContext(gWindow);
 
Which is also mean that we create opengl context in any case, even, if we in software, or in burning rendering.

In other words, to make patch be all-renderers-friendly, there needs some ifdefs and stuff, imho..
I used the SDL2 patch only for two days before switching to GLFW3 because I had a problem with the events when I added nanogui-sdl. I made a few tests and everything worked (except the problem mentioned before) but I only tried with OpenGL. Feel free to add the ifdefs and try it again. Also my patch is based in this one http://octodadgame.com/SDL2OpenGL.patch (from this topic http://irrlicht.sourceforge.net/forum/v ... =2&t=50698) so maybe they skipped it too (or maybe i skipped it, i'm in a hurry because this is for a college work).