render text and game problems.

Started by thatdude624, June 08, 2011, 16:51:26

Previous topic - Next topic

thatdude624

well, im using the slick-utill library with LWJGL, and i cannot render my game and show text at the same time!

code:
public void render() {
		Color.white.bind();
		
                 if (display==1)
                 {
                 rendergame();
                 font.drawString(100, 50, "test", Color.yellow);
                 }
                 if (display==0)
                 {
                  rendermenu();   
                 }
	}


I used the tutorial found here: http://lwjgl.org/wiki/index.php?title=Slick-Util_Library_-_Part_3_-_TrueType_Fonts_for_LWJGL

if I render the text, I get black,nothing but that text. if i comment it, everything else works fine.
the rendergame() youses for loops and checks arrays for objects to render,may that have something to do with it?
IDE: netbeans
OS: windows
EDIT: its 2D, nothing else required?
i'm only 14,BTW, so I probably did something stupid.

CodeBunny

Can you give screenshots of the game without text, with it, and a screenshot of what you're expecting?

And can you briefly explain what you do in rendergame()?

thatdude624


i know, its a crappy game. you are the yellow square,move with arrows.
red square=mouse, use it to select movable blocks(green) and "hold" them,and move them somewere else
purple is unmovable.
this is just the main engine, i will add more blocks and NPCs to solve puzzles,etc.

this is only my 1st game.you see that empty sqare at the bottom? that will be the GUI/heds down display.

this is what happens when i try to add text.


the "display" var is what screen you are currently on, the menu or the game screen,currently.
this is the rendergame code:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            GL11.glLoadIdentity();

            object=world.updateworld(object);
            for (int ydraw = 12; ydraw < 535; ydraw+=22) {
                for (int xdraw = 12; xdraw < 785; xdraw +=22) {
                    GL11.glColor3f(0.0f, 0.5f, 0.5f);//layer 1:def colour
                    colourblock((xdraw-12)/22,(ydraw-12)/22);//layer 2: block colour
                    if (world.inrange(xdraw,ydraw,mouseX,mouseY,10)==true)
                    {GL11.glColor3f(1.0f, 0.5f, 0.5f);mousegridX=xdraw;mousegridY=ydraw; }//if mouse=square make it red
                    GL11.glBegin(GL11.GL_QUADS);
                    GL11.glVertex2f(xdraw - 10.0f, ydraw + 10.0f);
                    GL11.glVertex2f(xdraw + 10.0f, ydraw + 10.0f);
                    GL11.glVertex2f(xdraw + 10.0f, ydraw - 10.0f);
                    GL11.glVertex2f(xdraw - 10.0f, ydraw - 10.0f);
                    GL11.glEnd();
                    GL11.glColor3f(0.0f, 0.5f, 0.5f);

hope that helps

thatdude624

also,when going into the menu(witch has text) from the game is fine, but when going back to the normal game(with no text,commented) i get a block screen

i think it may have something to do with how i draw the grid...is there another way for drawing tons of squares on the screen that may fix this? ???

CodeBunny

Try this call right before rendergame():

GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);


I'm guess that all of your squares are untextured quads. However, you're attempting to render a Slick font, and that automatically enables and binds a texture. OpenGL is a state-based machine, so that texture is still bound. Since it's an image of a character, the corner of the quad being rendered for the letter is transparent. Then, all of the quads you render will be transparent as well, since you're multiplying [texture color: r, g, b, 0]x[gl color: r, g, b, 1] = [final color: rr, gg, bb, 0].

However, if you make the above call, OpenGL gets rid of the bound texture. An alternative is to call GL11.glDisable(GL11.GL_TEXTURE_2D), but I've always preferred binding texture 0 because you don't have to re-enable textures if you want to use images in conjunction with polygons.

Does this make sense?

thatdude624

thanks! although before i read your post, i found out that                  GL11.glDisable(GL11.GL_BLEND); somehow works too.
"blend"probably has to do with transparicy, so you were right! i have to disable blend when drawing normal stuff, and reanable when i want to draw text.

now i have level saving/loading
deadly lazers
mouse limit
level editor....

thanks!

CodeBunny

Don't use GL_BLEND, it disables alpha blending. Trust me, it's a better idea to disable or unbind textures instead - it's actually what you're attempting to do, and you can still use blending to get some cool effects.

Nice work.

thatdude624

thanks, although i dont even know how to use alpha blending.
all i know of openGL is change colour and draw a square,lol.
can you mabie show me how to, say, draw a half transparent mouse block instead of one that replaces whatevers above it? the code is in the main post.

its not necesary, the game will work fine without it, but it whould be cool.  ;)

CodeBunny

Okay, sure. Be ready for a wall of text, though.

First off, here's the actual description of glBlendFunc in the OpenGL API: http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml. It's deeper and more accurate than I can hope to be, but I'll try to give a brief, less complex explanation on the side.

For all this to work, you need to have alpha blending enabled (so don't call glDisable(GL_BLEND). Alpha blending controls how two pixels blend, given a particular color and alpha value for each.

When OpenGL tries to render something, it has a set of incoming pixels (the Source) that will in some way write over what is already there (the Destination). So, if you have a partially rendered scene and want to draw onto it, the current image that is rendered is the Destination, and the quad that you are drawing is the source. After the render, the Destination has been altered.

The manner in which the Source pixels affects the Destination is controllable. I believe that you can use shaders to customize this effect, but OpenGL has some built-in functions which already give you a good deal of control (most likely, more than enough for your purposes). These built-in blending functions are accessed through glBlendFunc(int src_factor, int dst_factor). This method defines how the pixels are blended. Basically, the red, blue, green, and alpha values for the Source and Destination pixels are multiplied by their respective values. The OpenGL API provides excellent descriptions about how the possible values for these function.

The default value for blending is "replacement" blending - alpha values are ignored, and colors simply replace one another. Instead, at the very beginning of your game, call this:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


This functions similarly to replacement blending, but allows the alpha channel to moderate the affect.

IN YOUR CASE:

After the font has been rendered, the texture that contains its character data is still bound, and that bound texture is affecting everything you draw. Because characters tend to not hit the edges of their bounding rectangles, the vertex is actually on a completely transparent position of the texture, so everything you draw has an alpha value of 0.

No problem, right? You never changed your blending function, so what do you care? Wrong! I believe Slick automatically enforces the blending function that will work properly with the text it's trying to render, so all of a sudden you're using alpha during blending, but everything is at 0, so not a single thing gets rendered (except for your font, which uses its texture properly). Thus, your initial bug.

What you do when you call glDisable(GL_BLEND) is you turn off alpha blending. Basically, this forces the graphics card to constantly use the replacement blending I mentioned before, so, once again, your alpha level of 0 is ignored. But, you want alpha, so instead you want to call glBindTexture(GL_TEXTURE_2D, 0) like I said. This will get unbind that texture that is causing the alpha problem.

Really, once your blending mode is set, simply render a quad with a transparent color and it will work as you want.

thatdude624

... using your sugested texture binding instead of the GL_DISABLE thing, i get this:

those red,green and yellow squares are meant to be text. when the texture gets bound, there does not seem to be a texture for the text...
gaaah!
is there something to "unbind" it?
previously, i used GL_ENABLE then render text, then DISABLE it again, and render everything else, otherwise similar problems occurred.

CodeBunny

Hmm... Try calling glDisable(GL_TEXTURE_2D) instead and see what happens.

thatdude624

yay! replacing the GL11.glEnable(GL11.GL_BLEND) and GL11.glDisable(GL11.GL_BLEND) with
GL11.glEnable(GL11.GL_TEXTURE_2D) and GL11.glDisable(GL11.GL_TEXTURE_2D)
makes it all work again!
then replacing GL11.glColor3f with GL11.glColor4f and adding 1f makes it all work again.
however, if I draw another box on top of the normal ones with blend set to, say, 0.5f, it "blends" with the black background. mabie it needs to know the depth or something?

CodeBunny


thatdude624

if you mean GL11.glDisable(GL11.GL_DEPTH_TEST);, then yes
turning it on shows me nothing at all, though...

CodeBunny

Yeah, you need to be rendering objects away from the current viewpoint to see them when depth mode is turned on.

What's your rendering code now?