Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I create a screen with an existing GLFWwindow instance? #45

Closed
Krystex opened this issue Feb 13, 2016 · 11 comments
Closed

How do I create a screen with an existing GLFWwindow instance? #45

Krystex opened this issue Feb 13, 2016 · 11 comments

Comments

@Krystex
Copy link

Krystex commented Feb 13, 2016

I'm calling this code...

Screen *screen = new Screen();
screen->initialize(window /* my GLFWwindow*/, true);

and initialize throws an Exception:

Exception thrown at 0x00000000 in OpenGL-Game.exe: 0xC0000005: Access violation executing location 0x00000000.

Call-Stack:

nanogui.dll!glnvg__createShader(GLNVGshader * shader, const char * name, const char * header, const char * opts, const char * vshader, const char * fshader) Line 407 C++
nanogui.dll!glnvg__renderCreate(void * uptr) Line 649 C++
nanogui.dll!nvgCreateInternal(NVGparams * params) Line 228 C
nanogui.dll!nvgCreateGL3(int flags) Line 1480 C++
nanogui.dll!nanogui::Screen::initialize(GLFWwindow * window, bool shutdownGLFWOnDestruct) Line 207 C++
OpenGL-Game.exe!main() Line 162 C++

Am I doing it wrong, or is it a bug?

@wjakob
Copy link
Owner

wjakob commented Feb 13, 2016

maybe you didn't initialize GLFW?

@Krystex
Copy link
Author

Krystex commented Feb 13, 2016

No, I definately initialized it and worked with it.
Sample code:

#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <nanogui/nanogui.h>
static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void)
{
    GLFWwindow* window;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    // Here it begins
    int testvariable = 5;
    using namespace nanogui;
    Screen *screen = new Screen();

    screen->initialize(window, true); // <- and it crashes right here
    FormHelper *gui = new FormHelper(screen);
    ref<Window> wnd = gui->addWindow(Eigen::Vector2i(10, 10), "Form helper example");
    gui->addGroup("Basic types");
    gui->addVariable("bool", testvariable);
    screen->setVisible(true);
    screen->performLayout();
    wnd->center();

    // ---
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwSetKeyCallback(window, key_callback);
    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float)height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glRotatef((float)glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
        glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f);
        glVertex3f(-0.6f, -0.4f, 0.f);
        glColor3f(0.f, 1.f, 0.f);
        glVertex3f(0.6f, -0.4f, 0.f);
        glColor3f(0.f, 0.f, 1.f);
        glVertex3f(0.f, 0.6f, 0.f);
        glEnd();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

I also tried to put the code right before the main loop, and even there it crashes.

@wjakob
Copy link
Owner

wjakob commented Feb 13, 2016

sorry -- I meant GLEW, not GLFW. Looks like you did not initialize it -- see the code of screen.cpp to see how to do it.

@Krystex
Copy link
Author

Krystex commented Feb 13, 2016

Thank you for your fast response!
But still, after I initialized GLEW, it crashes, with the same Call Stack as seen in my first post.
My code:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <nanogui/nanogui.h>
static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void)
{
    GLFWwindow* window;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    /* Request a forward compatible OpenGL 3.3 core profile context */
    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);

    /* Request a RGBA8 buffer without MSAA */
    glfwWindowHint(GLFW_SAMPLES, 16);
    glfwWindowHint(GLFW_RED_BITS, 8);
    glfwWindowHint(GLFW_GREEN_BITS, 8);
    glfwWindowHint(GLFW_BLUE_BITS, 8);
    glfwWindowHint(GLFW_ALPHA_BITS, 8);
    glfwWindowHint(GLFW_STENCIL_BITS, 8);
    glfwWindowHint(GLFW_DEPTH_BITS, 24);
    glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);


    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glewExperimental = true; // Needed in core profile
    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW\n");
        return -1;
    }
    glViewport(0, 0, 640, 480);
    // Here it begins
    int testvariable = 5;
    using namespace nanogui;
    Screen *screen = new Screen();

    screen->initialize(window, true); // <- and it crashes right here
    FormHelper *gui = new FormHelper(screen);
    ref<Window> wnd = gui->addWindow(Eigen::Vector2i(10, 10), "Form helper example");
    gui->addGroup("Basic types");
    gui->addVariable("bool", testvariable);
    screen->setVisible(true);
    screen->performLayout();
    wnd->center();

    // ---

    glfwSetKeyCallback(window, key_callback);
    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float)height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glRotatef((float)glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
        glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f);
        glVertex3f(-0.6f, -0.4f, 0.f);
        glColor3f(0.f, 1.f, 0.f);
        glVertex3f(0.6f, -0.4f, 0.f);
        glColor3f(0.f, 0.f, 1.f);
        glVertex3f(0.f, 0.6f, 0.f);
        glEnd();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

2016-02-13 12_27_27-start

Also, Im not sure which code I should use from the screen.cpp.

Thank you for your time!

@wjakob
Copy link
Owner

wjakob commented Feb 13, 2016

Sorry, I am afraid you will have to debug this on your own (my time for supporting this project is very limited). All the initialization code is available in screen.cpp, so it's just a matter of following the approach shown there.

@wjakob wjakob closed this as completed Feb 13, 2016
@AlwaysGeeky
Copy link
Contributor

Just wondering if this issue was ever solved? I have very much the same problem...

Do you have any examples of anyone or another project that is able to get this working, by also handling GLFW and GLEW themselves?

@danielepanozzo
Copy link
Collaborator

@AlwaysGeeky
Copy link
Contributor

Thanks for the reply, do you have any easy access or examples of the actual GLFW init and creation code and how you pass this to nanogui and the root screen setup/init.

I pretty much have the exact same problem as the author of this issue. I create my own glfw window and context and init glew, etc.. but when I pass the glfwwindow pointer to a new 'screen' object to call initialize(...) I get a hard crash inside the initialize(...) function, because of an access violation. During this call:

glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER,
GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &nStencilBits);

But if I remove my own glfw init and windows creation code and call the screen constructors like in the nanogui examples, it seems to create the window/screen properly and it works.

@svenevs
Copy link
Collaborator

svenevs commented Jul 23, 2016

Given the error you are having with nStencilBits, I think this is a Screen::Screen() initialization error:

https://github.com/wjakob/nanogui/blob/master/src/screen.cpp#L73

It seems there are a couple of fields not initialized, so the values of nStencilBits and nSamples used in the initialize method haven't been set yet, so their values won't be reliable. The default values in the other constructor are int stencilBits = 8, int nSamples = 0. I don't know which is more appropriate, but two options would be

  1. Hard-set values in the Screen::Screen constructor
  2. Make stencilBits and nSamples parameters to initialize, and in the explicit Screen constructor call it with the member variables.
    • With this approach, these could also be default parameters so that other frameworks using this method will still work: void initialize(GLFWwindow *window, bool shutdownGLFWOnDestruct, int stencilBits = 8, int nSamples = 0);?

@AlwaysGeeky
Copy link
Contributor

Thanks for the additional info. I don't think that is right though, I think there is a problem generally with the pass GLFWwindow* pointer. since these two calls don't even populate the right values in the size variables:

glfwGetWindowSize(mGLFWWindow, &mSize[0], &mSize[1]);
glfwGetFramebufferSize(mGLFWWindow, &mFBSize[0], &mFBSize[1]);

It could be to do with the included version of glfw in nanogui, or some other incompatability, but its hard to say since I'm not fully familiar with how nanogui is built and having to use a dll. So far I have had little trouble getting the source of nanogui to compile natively in my engine, but will be working on that soon.

Also I'm gonna write a simple cut down sample code that easily demonstrates that the Screen functionality doesnt work properly when you switch from letting nanogui manage the glfw itself and when you create it yourself and pass it into the Initialize function.

Something fishy is going on, but I will be investigating more.

@AlwaysGeeky
Copy link
Contributor

I have a fix for this in the pull request: #91

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants