Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (121)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Frame Buffer Object is Misbehaving When Rendering to Texture  (Read 3703 times)
0 Members and 1 Guest are viewing this topic.
Offline hvince95
« Posted 2012-10-06 01:42:18 »

Hello again!
I managed to get FBO's working after a lot of headache, and scouring the internet of examples.  I know, it shouldn't be that hard!  Anyway, when rendering to the texture, ie. after calling these two lines of code:
1  
2  
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferID);

Weird stuff begins to happen.  This is the code I use to render some points, and a quad (just to test).
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
      glDisable(GL_POINT_SMOOTH);
      glPointSize(2.0f);
      glBegin(GL_POINTS);
         glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
         for (int x = 0; x < 200; x++) {
            for (int y = 0; y < 200; y ++) {
               glVertex2i(x * 2, y * 2);
            }
         }
      glEnd();
     
      glBegin(GL_QUADS);
      glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
         glVertex2i(100, 100);
         glVertex2i(100, 150);
         glVertex2i(150, 150);
         glVertex2i(150, 100);
      glEnd();

And this works great!  Does exactly as I wanted, rendering a large blue box filled with points, and a smaller purple box in the middle.
However, when I change the second glColor4f (in GL_QUADS) method to red (simply changing the third 1.0f to 0.0f), I can no longer see the big blue area (it turns the same colour as the glClear colour).  This is literally the only thing that I change, I can go back and forth between the two.  The frame rate remains the same as it was when it was rendering everything which is also weird.

Is this a common problem, is there any way to fix it?

Thanks.
Offline hvince95
« Reply #1 - Posted 2012-10-06 03:50:44 »

After more experimentation it seems that the two colours are almost merging together.  This is a crude table which shows what colours I set each part to in the code, and what colour actually shows when it has been rendered.  GL_POINTS is the larger area filled with points, and GL_QUADS is rendered over the top of that a little smaller.

GL_POINTS      glColor4ub(0, 0, 255, 255);      Blue
GL_QUADS      glColor4ub(255, 255, 255, 255);   White

GL_POINTS      glColor4ub(255, 255, 255, 255);   Aqua
GL_QUADS      glColor4ub(0, 255, 255, 255);      Aqua

GL_POINTS      glColor4ub(255, 255, 255, 255);   Blue
GL_QUADS      glColor4ub(0, 0, 255, 255);      Blue

GL_POINTS      glColor4ub(255, 255, 255, 255);   Black
GL_QUADS      glColor4ub(0, 0, 0, 255);      Black

GL_POINTS      glColor4ub(255, 255, 0, 255);      Red
GL_QUADS      glColor4ub(255, 0, 255, 255);      Purple

What is going on here???
Offline theagentd
« Reply #2 - Posted 2012-10-06 14:41:01 »

Aren't you just forgetting to disable GL_BLEND?  Clueless What texture format are you using? You should also call glViewport() with the size of your texture if it's not the same as the main render buffer.

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline davedes
« Reply #3 - Posted 2012-10-06 16:47:03 »

Also:
1  
glDisable(GL_TEXTURE_2D);

Offline theagentd
« Reply #4 - Posted 2012-10-06 18:45:22 »

Also:
1  
glDisable(GL_TEXTURE_2D);

Not needed since he does glBindTexture(GL_TEXTURE_2D, 0);

Myomyomyo.
Offline davedes
« Reply #5 - Posted 2012-10-06 19:54:10 »

Quote
Not needed since he does glBindTexture(GL_TEXTURE_2D, 0);
Unless he binds/draws images after binding the frame buffer, but before drawing the primitives.

In any case, it's good practice to disable texturing when you don't want it, rather than binding texture 0 (which can be changed like any other texture).

Offline theagentd
« Reply #6 - Posted 2012-10-06 22:33:39 »

Or use shaders since that ignores glEnable(GL_TEXTURE_2D)...

Myomyomyo.
Offline hvince95
« Reply #7 - Posted 2012-10-07 03:40:11 »

Thanks for helping out everyone.  That didn't seem to help anyway, I added both suggestions, like this:
1  
2  
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);

Should I be using a different blend mode maybe?

I have done further investigation, and tried only rendering the area of points and the quad to the frame buffer object ONCE, instead of every frame.  Here are the two colours:

1  
2  
3  
4  
5  
glBegin(GL_POINTS);
         glColor4ub((byte)0, (byte)255, (byte)255, (byte)255);

glBegin(GL_QUADS);
         glColor4ub((byte)255, (byte)255, (byte)0, (byte)255);

resulting in a yellow quad on a green background (the points render accross the entire screen remember!).

The same results still occur, which means information is travelling back in time, from the quads colour, back to the points colour.  I noticed that if there is a zero in one part of the quads colour (in this case the blue part), that information will ripple back through space and time to change the GL_POINTS blue part to zero as well.  The parts which are 255 in quads leave the corresponding parts in points untouched.  This explains the green background and yellow quad, as well as all the previous examples I posted.

I didn't know java/lwjgl/openGL was into all this quantum mechanics stuff.
Offline hvince95
« Reply #8 - Posted 2012-10-07 06:40:58 »

On a side note, theagentd, I saw this thread:
http://www.java-gaming.org/index.php?topic=25292.0
and am very interested in seeing how you set everything up.  I have accessed the source files on the 15th post, but I have no idea how to set it up for myself!  I get an error on line 66 of the class "Test Java Program".  What does this part mean:
1  
"shaders\\tile\\tile.vert"

and then on the next line:
1  
"shaders\\tile\\tile.frag"

If I were to use this, I probably wouldn't be using textures/images, rather plain colours.  Would that be hard to change and increase performance much?

Thanks.
Offline hvince95
« Reply #9 - Posted 2012-10-08 07:14:51 »

bump?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline davedes
« Reply #10 - Posted 2012-10-08 16:44:27 »

Give us a small self-contained test demonstrating the problem, and we can look into it for you. There are a number of things that you could have set up incorrectly...

Offline hvince95
« Reply #11 - Posted 2012-10-09 06:26:15 »

Here is the main class, I have put it in JGO's pastebin 'to keep the thread readable'.  The FrameBuffer class you will notice begins on line 96, and the main function is on line 92 (Just to help out a little Smiley).  It is not like this in the actual project, obviously FrameBuffer has it's own file, and the game loop is more advanced etc.  If you need to, this code works on its own, if you have the LWJGL jars attached.

http://www.java-gaming.org/?action=pastebin&id=275

Thankyou for taking the time to help!
Offline theagentd
« Reply #12 - Posted 2012-10-09 06:53:04 »

Sorry, I've been busy lately...

Those two strings just refer to the shader files containing the shader source code. Just switch those to wherever you've saved the shaders (also in that post).  If you want to only use a solid color per tile you're just doing basic texture mapping without filtering. Just create a normal texture the size of the world and draw it over the whole world with GL_NEAREST.

1  
GL11.glDisable(GL11.GL_DEPTH_BUFFER_BIT);

... is not valid. You'd do glDisable(GL_DEPTH_TEST), but it's disabled by default.

The reason why your FBO isn't displaying the correct colors is because you're drawing the FBO texture multiplied by the last color set with glColor***(). Your dots ARE white, but you're drawing the whole FBO multiplied by yellow. That also explains why stuff disappears at times, red * blue = black.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
public void renderToDisplay() {

         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, frameBufferID);

         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

+        glColor3f(1, 1, 1);
         glBegin(GL_QUADS);
         glTexCoord2f(0, 0);
         glVertex2i(0, 0);
                        ...

Myomyomyo.
Offline hvince95
« Reply #13 - Posted 2012-10-09 07:04:21 »

haha, wow.  Its that simple huh!  Actually makes a lot of sense, so I can change that when rendering various textures or anything to give the same image various colours.
Thankyou so much for all the help!

And by the way theagentd, all your previous posts and articles in the various topics over JGO are still being used.  Keep up the great work! Grin
Offline theagentd
« Reply #14 - Posted 2012-10-09 07:36:10 »

Heh, good to know. I usually try to help out with these kinds of problems since I've had them so many times myself. There's just too much global state in OpenGL. Things get a lot better once you start using shaders and OpenGL+ since most of the state was replaced with programmable functionality. It's a bit more complicated but a lot more CPU efficient, not to mention the amount of time you save not having to track down bugs like these.

GLHF with FBOs now, they're extremely powerful! =D

Myomyomyo.
Offline hvince95
« Reply #15 - Posted 2012-10-09 10:48:47 »

Thankyou again!
This shader program is unbelievable!  From my experiences it is impossible to even begin to draw that many quads to the screen, let alone textured quads!  I'll have to rummage through the code and see what I can make of it when I get the chance.
Seeing two backslashes in the file path is new to me also. Just read up on it and makes sense. Smiley
Offline theagentd
« Reply #16 - Posted 2012-10-09 16:29:12 »

Apparently using two backslashes only works on Windows, so it's never been a problem for me. I think the correct way is to just use a single forward slash. I wrote that code before I knew about that...

Actually drawing 1 million quads (= 2 million triangles) isn't impossible, it's actually possible to make that run at 60 FPS, although barely and not leaving much GPU time for other things. The point of the shader is that it just uses 4 vertices instead of 4 000 000 vertices. Instead it simply does some more work per pixel, which is what GPUs do best, or in any case at least better than vertices.

It's...
 - more memory efficient since it's just a texture texel per tile instead of 4 vertices with position and texture coordinates. It uses around half as much memory, depending on how you drew quad tiles before.
 - much easier to handle culling, since you don't even have to do any culling at all. The GPU automatically culls pixels outside the screen automatically.
 - faster to update. If you're drawing quad tiles you'll need to batch them into sections. If one changes the whole section needs to be regenerated. Here, you just update the texture with glTexSubImage2D() and forget about it.
 - much more CPU efficient since you only have to bind a shader, bind 2 textures and draw 4 vertices with texture coordinates instead of looping over tiles/batches. This is very important for 2D games since that's usually the main bottleneck.
 - faster to render since it only ever uses 4 vertices and uses the texture cache very well for normal use, and is still a lot faster than millions of vertices for extremely zoomed out views.
 - fully compatible with transparency and custom shaders (as long as all tiles use the same shader which is the same limitation as quad tiles).

I may have a small update for it soon, though nothing really new... =S

Myomyomyo.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

theagentd (19 views)
2014-10-25 15:46:29

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (45 views)
2014-10-16 15:22:06

Norakomi (34 views)
2014-10-16 15:20:20

lcass (39 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (74 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!