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?
Related
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.
I've been trying to figure this out for a while now. Is there a way to have multiple shapes you have rendered to become one single object? So you could manipulate the object in any way you want? Currently if I try to use the glcolor method it doesn't change anything because I have multiple colors changing the objects already. Maybe I'm not realizing something obvious, or it's just something that I can't find in any tutorial. But simply put I'm looking for a way to change just the alpha value of multiple shapes draw together to make a more complex shape, but keeping the colors that have already been predefined.
If you want multiple shapes to become one single object you simply calculate or write the correct X, Y, Z numbers into each vertex, so they fit together.
For instance you can make 2 triangles become a square, like this.
To do the same but in code it would look something like this.
glBegin(GL_TRIANGLES);
glVertex3f(0f, 0f, 0f);
glVertex3f(0f, 100f, 0f);
glVertex3f(100f, 0f, 0f);
glVertex3f(100f, 100f, 0f);
glVertex3f(100f, 0f, 0f);
glVertex3f(0f, 100f, 0f);
glEnd();
You can of course just use GL_QUADS, though triangles are usually better in a lot of ways. If you want to color the shape 1 color, you need and can only write one color before.
So for instance this will work and gives a whole red square/quad.
glColor3f(1f, 0f, 0f);
glBegin(GL_TRIANGLES);
glVertex3f(0f, 0f, 0f);
glVertex3f(0f, 100f, 0f);
glVertex3f(100f, 0f, 0f);
glVertex3f(100f, 100f, 0f);
glVertex3f(100f, 0f, 0f);
glVertex3f(0f, 100f, 0f);
glEnd();
Though if you add more glColor in between that will end up giving another result.
If you want to use transparency/opacity/alpha you will need to use glColor4f where the last number is the amount of transparency. But before you are able to use transparency you need to enable blending mode within OpenGL. You do that by calling.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
I wasn't a 100% sure about your questions so if I've forgotten to answer something, just write a comment and tell me.
Info
If you don't statically import your classes then remember that glEnable(GL_BLEND); is actually GL11.glEnable(GL11.GL_BLEND); and the same goes for the rest of the code.
Also take in mind that the glVertex, glNormal, glColor, etc. are deprecated methods and should not be used for that reason, also they are extremely slow when rendering a huge amount of vertices, Though they are really good for the purpose of learning OpenGL, and should only be used for learning. The new and better alternative is to use VBOs and Shaders.
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.
I'm creating an app that only runs in landscape mode. I'm trying to create a background using a textured quad although I'm not going to worry about texturing yet. I've been trying to simply draw a quad that fills the screen from drawOverlay(GL10 gl) with GL_DEPTH_TEST disabled but whenever I do that the quad does not completely fill the screen and I can see bars of the glClearColor on the bottom and top of the screen.
Unable to draw it using the modelview matrix I was using for all the other objects, I tried to draw it using gluOrtho2D and glOrthof but neither of them worked. I don't really understand how the near and far clipping plane work with orthographic drawing. Whenever I tried to draw it using glOrtho2D or glOrthof, the quad wasn't drawn at all(although the rest of the scene was still rendered).
Here is my attempt at drawing using an orthographic matrix
private void drawOverlay(GL10 gl) {
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0f, 1f, 1f, 0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
background.draw(gl, 1.0f, 1.0f, 1.0f, 1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
I call that function from the beginning of onDrawFrame - before anything else is drawn:
public void onDrawFrame(GL10 gl) {
drawOverlay(gl);
gl.glLoadIdentity
//...
}
Here is how "background" is created:
background = new ShapePostcard(1f, 1f);
I'm fairly certain I'm not going to be able to get the quad to cover the screen using the normal modelview matrix, but basically all I was doing was drawing "background" in onDrawFrame before everything else with depth testing disabled.
Thanks for any support!
The easiest way to draw a quad that fills the screen is to set both the projection and model to an identity matrix, and then draw a mesh with coordinates [-1,-1] to [1,1]. Was it this what you were drawing when you saw the borders?
I mean,
(x, y, widht, height) = (-1,-1, 2, 2)
OpenGL ES does not support quads.
http://www.songho.ca/opengl/gl_vertexarray.html
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).