[SOLVED]Drawing to the window buffer

Started by aeonios, December 17, 2015, 21:48:58

Previous topic - Next topic

aeonios

I've recently started working on a simple 2d graphics library using lwjgl/GL11. I finally got enough basic stuff implemented that I could write up a test program, but so far I can't get it to work. No exceptions are thrown even when I try to blanket try/catch/print everything that might possibly throw one, but all I get is a black or gray display area in the window (as in "there's no content here" gray) and the test program consistently times out. Labeling shows that the main loop is indeed running, just that it isn't drawing properly.

The test program is very simple and can be found here: https://www.dropbox.com/s/u5doxoaf9as419g/ShineTest.7z?dl=1

Pretty much all it does is pop up a window and draw a semi-animated line to it until the close button is clicked. It seems like my attempts to enable/bind to the window's buffer are not working properly. I'm not really sure how to get the window's buffer (there's no function for it in glfw) or what kind of buffer it is or what I need to glEnable in order to draw to it. The code also creates an image buffer which I was using to test copying the buffer to the window buffer, but that's been disabled in order to test directly drawing to the window.

So far I've tried:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // same result

glfwMakeContextCurrent(windowID); // seems to be related to contexts not binding a draw target, same result.

glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK); // same result

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, GL_BACK); // same result

The source of the library is here: https://github.com/mtroyka/Shine2D/

The library is also pretty simple. The Window class wraps glfw's window interface and initializes everything as necessary. The Window and Image classes generate a Graphics instance when instantiated, and the Graphics class generates an FBO (for images, not for windows) and manages most of the drawing related code and immediate setup for that. The render classes are not used (not to mention empty) at least atm. When I learn shaders I may or may not keep them.

EDIT: Derp. Well part of the problem was a build error that overwrote any changes I made to the library with an old version. I got the hang to go away but now all I get is a black screen. :( Using the latest nightly of lwjgl doesn't seem to help either.

EDIT EDIT: Well, I got it to work on lwjgl 2.x but not on 3.0.0. On 2.x the following works:

GL11.glEnable(EXTFramebufferObject.GL_FRAMEBUFFER_EXT);
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
GL11.glReadBuffer(EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT);

which is horribly unintuitive since it mixes GL11 and EXTFramebufferObject constants. On v3 all I get is a black screen and nothing has yet worked.

aeonios

I hate to double post but I think editing again would be worse at this point. :P

I got it to draw to the windowbuffer using:

glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);

and in LWJGL2.9 I got it to draw a line properly. In 3.x I got it to color the background properly but so far no line. I seem to be down to projection issues but I'm not sure why it works in 2.9 and not in 3. My projection looks exactly like this:

////////////////////////////////////////
// -- bind the framebuffer --
// configure perspective settings for flat 2d drawing to the given canvas.
        glMatrixMode(GL_PROJECTION); // set projection first
        glLoadIdentity(); // and reset it

        // then set viewport second
        if (window != null) {
            glViewport(0, 0, window.getWidth(), window.getHeight());
        }else{
            glViewport(0, 0, image.width, image.height);
        }

        // then set ortho third
        if (window != null) {
            glOrtho(0, window.getWidth(), 0, window.getHeight(), -1.0, 1.0);
        }else{
            glOrtho(0, image.width, 0, image.height, -1.0, 1.0);
        }

        // finally switch to modelview
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
///////////////////////////////////////////

window.getWidth/Height returns the results of glfwGetFramebufferSize in 3.x and of Display.getWidth/Height in 2.9. I did a test to ensure that the values it was returning were the same, and they were (640x480 in my test). The 2.9 version uses a borderless window although that shouldn't make any difference given the fact that the framebuffers had identical size. I had issues where the graphics object would pick up an erroneous size (such as zero) for the window which stopped it from drawing properly, but even after fixing that I still got no line in 3.x. Is this possibly a bug?

Test source with 2.9 libs, showing line: https://www.dropbox.com/s/wjrnykoqapzlg2d/ShineTest-LWJGL2.9.7z?dl=1
Test source with 3.x libs, showing green background but no line: https://www.dropbox.com/s/0e72n4tb8m9olzb/ShineTest-LWJGL3.7z?dl=1

The only difference in the library used was the window class which had to wrap the different APIs. Everything else is identical.

Also, should I feel stupid that it took me nearly two weeks to get this far? :P

spasi

A framebuffer object is different from the default framebuffer (with ID = 0) associated with the window OpenGL context. It seems to me like you render to a framebuffer object, then call glfwSwapBuffers and expect to see the result in the default framebuffer. This won't work without an explicit copy between the two framebuffers.

Also make sure you're not getting any OpenGL errors. The easiest way to do that is with debug output:

// Before glfwCreateWindow:
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);

// After GL.createCapabilities():
Closure debugProc = GLUtil.setupDebugMessageCallback(); // store a reference to this somewhere, until the context is destroyed

aeonios

I figured that out, and somehow magically got it working under LWJGL3, so I'm calling this solved. :P

Now FBOs aren't working. :D Or texture2D, one or both I'm not sure.