Alpha blending / transperency of a texture bound to quad - java lwjgl slick - java

I need someone to help me with this. I can't really figure out how the alpha channel or blending works. The Image is in .bmp format, it loads perfectly.
But I want a specific color to be transparent, in paint that color is R255xG0xB255.
I've been searching for similar topics, but everything I found or tried just seems to mess stuff up, like give me a full black screen or make everything have a magenta touch...
Everything else works just fine with my code... Should I maybe switch to .png? could that solve the issue? does it have any pros or cons if I use png or bmp?
// Initialization Code OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, HEIGHT, WIDTH, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
while (!Display.isCloseRequested()) {
// Render
glClear(GL_COLOR_BUFFER_BIT);
this.drawMapToScreen();
this.drawCreatureToScreen();
Display.update();
Display.sync(60);
}
Display.destroy();
}
private void drawCreatureToScreen() {
Texture tex3 = SpriteLoader.loadTexture("player");
Color.magenta.bind();
tex3.bind();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i((HEIGHT-32)/2,(WIDTH-32)/2);
glTexCoord2f(1, 0);
glVertex2i((HEIGHT-32)/2 +32,(WIDTH-32)/2);
glTexCoord2f(1, 1);
glVertex2i((HEIGHT-32)/2 +32,(WIDTH-32)/2 +32);
glTexCoord2f(0, 1);
glVertex2i((HEIGHT-32)/2,(WIDTH-32)/2 +32);
glEnd();
}

What are looking to do is that when your color is 1.0f, 0.0f, 1.0f (in the eyes of OpenGL: full red, no green, full blue) have the alpha (transparency) channel be zero, so that the pixel is drawn completely transparent. Unfortunately, there is no way to do this in OpenGL, unless you use shaders, and believe me using shaders is far messier than the solution I propose: doing "pre-multiplied alpha" in your image editor. What this means: it doesn't depend on which format you use - .png or .bmp are both fine, and they both support an alpha channel. Alpha is transparency; in OpenGL, you'll be dealing with floats a lot, so I'll use floats here. Alpha is the fourth color channel; we have Red, Green, Blue, and then Alpha. Alpha controls transparency (as a float) by being multiplied by the other channels: if alpha is 0.0f, then that color is fully transparent, but if alpha is 1.0f, it is fully opaque. To sum up: In your editor, you must make sure that the area you want transparent is transparent in the editor. For alpha blending, which still must be enabled for any transparency whatsoever: the generally preferred blend mode is as follows:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Now, blending is a technique for making objects appear transparent, among other things. In your case, you'll want to use the blend function above: use glDisable(GL_BLEND) to disable blending from occurring after enabling it. The blend function above essentially mixes the preexisting colors and colors to be rendered in such a way that an object rendered overlapping another, after said other, makes it appear that the "top" and most recently rendered object is transparent relative to the "bottom" object.
TL;DR:
Make sure the area you want transparent is transparent in your image editor. OpenGL cannot make specific colors have alpha values of 0.0f unless you use a needlessly complex shader.
Use the blending setup glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); to enable blending. Make sure the top object is rendered after the bottom object.

Related

Transparent shape texture

How can I make the texture of a shape transparent? (E.g. cube or cylinder).
I'm trying now:
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER, 1f);
glColor4f(0.5f, 0.5f, 0.5f, 0.2f);
//Cube code
This doesn’t work quite right, the textures are getting lighter, but I don’t see the objects behind them.
How can I make transparency, which will show what is behind the object?

LWJGL: Discolored Textures

So I am developing a small Pong replica simply for some practice with LWJGL. Since there is no easy way to write customizable text in LWJGL, I am using textures for the start button, other buttons, and so on. However, when I drew the texture, it turned out to be discolored on my purple background. If I change the background to white, there is no discoloration. Help?
Also, my start button texture is something like 50x22, but I put it on a 64x64 image because Slick can only load resolutions that are an exponent of two. I adjusted the rectangle being drawn so that it is not warped, and the rest of the image is transparent, so it shouldn't be visible once I sort out the above problem. Are there any alternatives to my method?
This is where I initialize my OpenGL stuff:
public static void setCamera()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,width,0,height,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
And this is where I draw the texture:
public void draw()
{
logic();
glPushMatrix();
glTranslated(x,y,0);
texture.bind();
glBegin(GL_QUADS);
glTexCoord2d(0,1); glVertex2d(0,-196.875);
glTexCoord2d(1,1); glVertex2d(width+18.75,-196.875);
glTexCoord2d(1,0); glVertex2d(width+18.75,height);
glTexCoord2d(0,0); glVertex2d(0,height);
glEnd();
glPopMatrix();
}
Thanks :)
As discussed in comments, your initial problem was that you had neglected to reset the "current color" before drawing your texture. GL is a glorified state machine, it will continue to use the color you set for every other draw operation... so setting glColor3d (...) when you drew your background also affects your foreground image.
Adding the following before drawing your textured quad will fix this problem:
glColor3f (1.0f, 1.0f, 1.0f);
However, you have brought up a new issue in your comments related to blending. This question boils down to a lack of a blending function. By default when you draw something in OpenGL it will merely overwrite anything else in the framebuffer.
What you need for transparency to work is enable blending and use this function:
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
This effectively does the following:
NewColor = (NewColor.RGB * NewColor.A) + OldColor.RGB * (1.0 - NewColor.A)
With this, the parts of your texture that have an alpha value != 1.0 will be a mix of whatever was already in the framebuffer and what you just drew.
Remember to enable blending before you draw your transparent objects:
glEnable (GL_BLEND);
and disable it when you do not need it:
glDisable (GL_BLEND);
Lastly, you should be aware that the order you draw translucent objects in OpenGL is pretty important. Opaque objects (such as your background) need to be drawn first. In general, you need to draw things from back-to-front in order for alpha blending to function correctly. This is the opposite order you would ideally want for opaque geometry (since hardware can skip shading for obstructed objects if you draw objects in front of them first).

Drawing with transparent texture, then opaque color

I initialize OpenGL like so to make transparent textures transparent:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
I draw my texture like this:
glPushMatrix();
//translate
//neutralize colors
//bind texture
//vertex points
glPopMatrix();
But when I try to draw a quad immediately afterwards, it won't show up:
glPushMatrix();
{
glTranslatef(x, y, 0);
glColor3f(1f, 0f, 0f);
glBegin(GL_QUADS);
{
glVertex2f(0, 0);
glVertex2f(10, 0);
glVertex2f(10, 10);
glVertex2f(0, 10);
}
glEnd();
}
glPopMatrix();
If I remove the initialization above, the quad appears, but then my texture is no longer transparent.
What am I doing wrong here?
Edit: Should I call glDisable(GL_BLEND); whenever I want to draw something that is not a texture?
You need to disable blending before drawing your quad.
EDIT: Can you post more code? The problem may be somewhere else, for example if you have not disabled the texture before drawing the quads.
There's no need to disable blending when drawing.
I call glBlendFunc(GL_SRC_ALPHA, GL_ONE) when I need to draw transparent cubes (with texture).
I usually disable DEPTH test upon drawing with blend mode enabled:
glEnable(GL_BLEND); // Turn Blending On
glDisable(GL_DEPTH_TEST); // Turn Depth Testing Off
NeHe has a nice tutorial on blending.

Java OpenGL only blue Textures

I've have a little Problem with Textures and OpenGL. I made a small .obj Loader (with Texture Loading) but everything is drawn blue. Example:
I load a Texture. I bind the texture with GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureId).
If I do:
glColor3f(1f,1f,1f);
glBegin(GL_QUADS);
glVertex3f(50f,0,-50);
glVertex3f(-50f,0,-50f);
glVertex3f(-50f,0,50f);
glVertex3f(50f,0,50f);
glEnd();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
it draws a white quad ... but if I do:
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
glColor3f(1f,1f,1f);
glBegin(GL_QUADS);
glVertex3f(50f,0,-50);
glVertex3f(-50f,0,-50f);
glVertex3f(-50f,0,50f);
glVertex3f(50f,0,50f);
glEnd();
it draws a blue quad and everything else is blue too.
Maybe somebody knows a solution?
There is no texture because you didn't specify texture coordinates using glTexCoord2f.
The colors are wrong probably due to incorrect parameters to glTexImage.
Everything else is blue because, you are using the same texture for everything. Bind different texture or use the default texture 0.
This is the problem because you are not using the glTexCoord2f with each vertex. Please try this with each vertex because it can solve it as presently your color is not binding to all the areas.

How do I get openGL to render a coloured quad?

Basically, I am trying to let openGL draw a bunch of quads. Each of these quads has different colours. Now my problem is that when I call glColor4f(), the colour is not applied on the material. I found out that that was because I had been using textures somewhere else in the rendering process, so I disabled that. Still, not result. After some googling I came across glColorMaterial(), which did display the quads correctly, but because I used glColour4f() to colour each of the quads, each of the 3D textures objects on the stage were tinted. So now I am a bit stuck; I want to have lighting enabled on my 3D objects, yet those few quads should just be drawn in a flat colour, without any lighting whatsoever. What is the openGL method of doing this?
My openGL context setup:
glViewport(0, 0, dim.width, dim.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (float)(dim.width/dim.height), 0.1f, 10000.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(94.0f/255.0f, 161.0f/255.0f, 255.0f/255.0f, 0.5f);
glClearDepth(1.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glEnable(GL_TEXTURE_2D);
As Platinum Azure said, you need to disable lighting and texturing right before drawing your quads, and then turn it back on afterwards. Like this:
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
// Draw quads
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
You should be fine to just use glColorf as usual (you don't need glColorMaterial).

Categories