I am using gluCylinder() to create a cylinder in openGL and then plotting points inside the cylinder with Depth Test On .
When i see the front view of the cylinder, the points inside the cylinder are obstructed by front face.
To make front face of the cylinder translucent i am using Blending.
I am using below functions.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
But whatever coloring or alpha value i assign to the cylinder the front face is not looking transparent due to its back face.
Tell whether it is possible to do with blending only or else i need to introduce lighting for both the faces of Cylinder.Here it clearly visible the change in the color of front face and back face of cylinder. And the points inside the cylinder are not visible due to being obstructed by front face of cylinder.
You should be able to accomplish this by drawing the cylinder twice, while culling the front faces the first time, and culling the back faces the second time. This way, you can draw the front and back parts differently, e.g. by making the front part transparent.
The code sequence could look like this:
// Draw back part of cylinder, opaque.
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
gluCylinder(...);
// Draw points.
// Draw front part of cylinder, transparent.
glCullFace(GL_BACK);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gluCylinder(...);
glDisable(GL_BLEND);
If I understand you right then no, you can't do it with blending alone.
If the cylinder's normals all point outward then you also won't be able to see the cylinder's internal parts no matter what you do.
I do something similar to show characters behind walls and it goes like this - render your scene normally and save it all to a framebuffer. Then render what you want shown behind with the buffer contents on top, using a custom shader to make a bubble of transparency around the thing you want shown behind.
Not sure if I am explaining it well or not but it unfortunately requires multiple steps to get the results you want.
Your problem is still a bit unclear to me despite the image but I will attempt to answer based on my perception of your issue.
You are drawing a cylinder and have geometry (lines or other models) inside the cylinder. You want the cylinder to look translucent so the inner objects are visible. Here is one way to do it. Assuming your render functions are drawCylinder() and drawPoints().
init()
{
...
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
...
}
drawScene()
{
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
drawCylinder();
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
drawPoints();
}
doing so will make sure that the points are drawn regardless of the cylinder. Try using lower values of alpha for your cylinder color.
Please note this is one way to do it. I suggest using shaders to have more control over blending as well as exploring fragment/pixel discard options.
Related
When drawing a quad, it vanishes when rotation brings in a position perpendicular to the screen. Ideally what I'd like to see is (b) but I get nothing
Is there something wrong with my code ? (warning old openGL code following)
void draw_rect(double vector[4][3], int rgb[3], double transp)
{
GLint is_depth, is_blend, blend_src, blend_dst;
glGetIntegerv(GL_DEPTH_WRITEMASK, &is_depth);
glGetIntegerv(GL_BLEND, &is_blend);
glGetIntegerv(GL_BLEND_SRC, &blend_src);
glGetIntegerv(GL_BLEND_DST, &blend_dst);
glEnable(GL_BLEND);
glDepthMask(0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// code to set the color ...
glBegin(GL_POLYGON);
glVertex3v(&vector[0][0]);
glVertex3v(&vector[1][0]);
glVertex3v(&vector[2][0]);
glVertex3v(&vector[3][0]);
glEnd();
if (!is_blend){ glDisable(GL_BLEND); }
glDepthMask(is_depth);
glBlendFunc(blend_src, blend_dst);
}
A quad (assuming it is defined by coplanar faces, as in this case) is by definition infinitely thin. It is correct behavior for it to be invisible when perpendicular to the camera.
The "correct" solution is to make a box rather than a single quad.
See Drawing cube 3D using Opengl for an example using a cube. You'll need to tweak the vertex positions to make the cube smaller along one dimension (probably Z), but it'll give you the effect that you're looking for.
Also, stop using the fixed function stuff (glVertex, etc.). It's been deprecated for years. Shaders aren't that difficult, and examples are easy to find via your favorite search engine.
try making it a line of some definite width when the quad is perpendicular to the screen
I am trying to check transparency and how it works.
I have created a solidsphere and a solidcube in it.
I have enabled
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
The transparency works as expected using color4f.
The problem is that when I am setting the transparency of the sphere to 1.0, the cube still appears.
I am also using these:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
How can I make the cube visible only when the transparency of the sphere is != 1.0 ?
Is there a reason you've set glFrontFace(GL_CW); ? The default is GL_CCW, so you'll be culling front faces, and rendering back faces. With the front of the sphere missing, you'll see inside it.
To elaborate:
When rendering translucent objects using a normal (src_alpha , 1-src_alpha) blend, the translucent surfaces need to be rendered in depth order, back to front.
If you render only the back-surfaces of an object, it may (if it's more or less symmetrical) appear normal, but it is in fact inside-out, and thus cannot occlude objects correctly which are actually inside it.
So for this to work, it is important both that the front-surfaces are not culled, and that the opaque or more distant objects are rendered first.
If you want both front and back of the sphere to render translucently, and correctly, you would need to render the back before the front. This could be done with polygon sorting, but for a convex object it would suffice to render it twice, with the backface culling inverted - so render back faces first, and then the front faces, in two seperate passes.
I am drawing a cube and a line grid in 3D in OpenGL:
glBegin(GL_QUADS);
...
glEnd();
glBegin(GL_LINES);
...
glEnd();
Now, independent of the order (if I draw the lines first or the quads first) and independent of the position it always happens that the lines are draw over the cube. I thought OpenGL draws front to back.
What I tried is to use:
glEnable(GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
which does work but part of the cube is transparent now.
I also tried glDepthFunc(GL_NEVER) with disabling glEnable (GL_DEPTH_TEST) but I get the same problem that the cube appears transparent.
Does anyone have a hint to overcome this problem?
If you want to draw the lines in the background, just draw them (and the rest of the background) first, clear the depth buffer, then render the rest of the scene.
Or you can just give the lines a depth such that they will always be behind everything else, but then you have to make sure that none of your gameworld objects go behind it.
Now, independent of the order (if I draw the lines first or the quads first) and independent of the position it always happens that the lines are draw over the cube.
IF your lines have proper depth, then you forgot to enable depth buffer. If you enabled depth buffer, then you must make sure that your library used for initializing OpenGL requested depth buffer.
I thought OpenGL draws front to back.
It does not. OpenGL draws polygons in the same order you specify them. There is no automatic sorting of any kind.
Does anyone have a hint to overcome this problem?
Well, you could clear depth buffer, but this will be slow and inefficient. Technically, you should almost never do that.
glDepthMask(GL_FALSE) will disable writing to depth buffer. i.e. any object drawn after that call will not update depth buffer but will use data that is already stored. It is frequently used for particle systems. So call glDepthMask(GL_FALSE), draw "lines", call glDepthMask(GL_TRUE), then draw cube.
If you combine glDepthMask(GL_FALSE) with glDepthFunc(GL_ALWAYS) then object will be always drawn, completely ignoring depth buffer (but depth buffer won't be changed).
I am trying to create a simple ray tracer. I have a perspective view which shows the rays visibly for debugging purposes.
In my example screenshot below I have a single white sphere to be raytraced and a green sphere representing the eye.
Rays are drawn as lines with
glLineWidth(10.0f)
If a ray misses the sphere it is given color glColor4ub(100,100,100,100);
in my initialization code I have the following:
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA);
You can see in the screen shot that for some reason, the rays passing between the perspective view point and the sphere are being color blended with the axis line behind the sphere, rather than with the sphere itself.
Here is a screenshot:
Can anyone explain what I am doing wrong here?
Thanks!!
Is it a possibility you cast those rays before you draw the sphere?
Then if Z-buffer is enabled, the sphere's fragments simply won't be rendered, as those parts of rays are closer. When you are drawing something semi-transparent (using blending), you should watch the order you draw things carefully.
In fact I think you cannot use Z-buffer in any sensible way together with ray-tracing process. You'll have to track Z-order manually. While we are at it OpenGL might not be the best API to visualize ray-tracing process. (It will do so possibly much slower than pure software ray-tracer)
You dont need the glAlphaFunc, disable it.
Light rays should be blended by adding to the buffer: glBlendFunc(GL_ONE, GL_ONE) (for premultiplied alpha, which you chose.
Turn off depth buffer writing (not testing) when rendering the rays: glDepthMask(GL_FALSE)
Render the rays last.
AlphaTest is only for discarding fragments - not for blending them. Check the spec
By using it, you are telling OpenGL that you want it to throw away the pixels instead of drawing them, so you won't can any transparent blending. The most common blending function is
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); You can also check out the OpenGL Transparency FAQ.
I am rendering 4 vertices (a square) in front of a colored cube. The vertices are colored white, but are blended at 0.5f.
Related: Why does my colored cube not work with GL_BLEND?
Please could someone tell me why the colored cube appears brighter when obscured by the semi-opaque square?
Cube rendered without square in front:
Normal cube http://img408.imageshack.us/img408/2853/normalcube.png
And, rendered with the square:
Cube with square http://img142.imageshack.us/img142/6255/brightsquare.png
Please see the code used to create the colored cube, the code used to actually draw the cube, and the code where the cube and square are rendered.
This is the code in my init function:
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
I'd say it's because your semi-transparent square gets added to the existing pixels, thus incrementing their intensity.
The documentation for glBlendFunc() recommends setting the second parameter to GL_ONE_MINUS_SRC_ALPHA, that is the boilerplate for implementing transparency. Try it.