[SOLVED] GL11 Window Buffer Drawing and Render-to-Texture Broken

Started by aeonios, December 19, 2015, 14:38:25

Previous topic - Next topic

aeonios

It took me a while to track it down, but I found out that while GL11 functions work fine for drawing directly to the window's backbuffer in LWJGL2.9.3, render to texture does not work in general. glClear works properly and copying the texture to the window buffer works properly, but nothing drawn shows up on the FBO-bound texture (aside from the clear color). In LWJGL3 drawing to the window buffer also does not work, probably for related reasons. The clear color also shows up in 3.x, but nothing else drawn does.

All the functions I tested work properly when drawing to the window buffer in 2.9.3, even with different window sizes. I ensured that my projection was correct, and am using the power-of-two texture size for aligning that (and even if I weren't I should just be getting a skewed image rather than nothing).

Example Code (only the LWJGL2 version is current): https://github.com/mtroyka/Shine2D

Kai

You are very likely calling OpenGL functions somehow wrongly or using invalid arguments/state.
Also did you use a debug context and a debug callback with LWJGL 3, or used GL11.glGetError() to get notified about GL errors?
In case you used an OpenGL >=3.2 core context, make sure you adhere to all the "new" rules in the core profile (most notably: having to use a VAO).
It is a bit too much asked to plow through your engine code to find the error.
Preferably provide a self-contained single-file Minimal Working Example only depending on LWJGL.
Though, to help you a bit, and to assure you that render-to-texture works just fine with LWJGL :) you can have a look at the lwjgl3-demos repository and its FBO examples.

aeonios

I didn't know VAO was required, although that explains why it isn't working. My vertices are being ignored. :(

Kai

Yes. Please use a debug context and a debug callback like so:
// At GLFW window initialization:
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);

// As field in your class:
Closure debugProc;

// Then after you called glfwMakeContextCurrent, do this:
debugProc = GLUtil.setupDebugMessageCallback();

Running your code then should fire GL_INVALID_OPERATION errors either at vertex specification (glVertexAttribPointer or equivalent) or at least at the draw call when not having a VAO bound.

aeonios

Hmm, after adding that stuff and porting over all the fixes from the 2.x version suddenly my test works in 3.x. The errors I got were different than I expected though.

[LWJGL] OpenGL debug message
	ID: 0x500
	Source: API
	Type: ERROR
	Severity: HIGH
	Message: GL_INVALID_ENUM error generated. <cap> enum is invalid; expected GL_ALPHA_TEST, GL_BLEND, GL_COLOR_MATERIAL, GL_CULL_FACE, GL_DEPTH_TEST, GL_DITHER, GL_FOG, etc. (136 others).


I learned that GL_FRAMEBUFFER_EXT is not a valid argument to glEnable. :P

FBO drawing still doesn't work, nor does it throw any errors. In LWJGL3 now even glClear doesn't work on an FBO (although I don't know that it ever was working).

EDIT: Hmm.. weird.

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);


Throws a GL_INVALID_OPERATION error, saying the required buffer is missing, even though buffer completeness checks out. I ensured that those weren't being called until after the texture was attached to the FBO as well, but it didn't change anything.

EDIT EDIT: nvm the windowbuffer throws the exact same error even though drawing works just fine, and removing that code stops the errors. I have no idea why FBO drawing isn't working now.

Kai

Note that glDrawBuffer/glReadBuffer affects the currently bound FBO, so it is a per-FBO state and not a global state, such as glEnable.
Calling those functions with GL_COLOR_ATTACHMENT0 when the default window framebuffer = 0 is bound is indeed an GL_INVALID_OPERATION.
To change the draw/read buffer of your FBO you have to bind your FBO first.
The following will work:
int fbo = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT0);

Although this is redundant, since GL_COLOR_ATTACHMENT0 is the default draw and read buffer for custom framebuffers.

aeonios

QuoteAlthough this is redundant, since GL_COLOR_ATTACHMENT0 is the default draw and read buffer for custom framebuffers.

I figured as much. :P

A bit of testing reveals that drawing the texture I created onto the window buffer isn't working either, although it was working in 2.9.x. I tried a few obvious things that came to mind but still no result (and no errors). I expected it to at least draw a black rectangle where the texture should have been, but I didn't get even that.