OpenGL draw GL_LINES on top of GL_QUADS - opengl

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).

Related

GL_TRIANGLE_STRIP and transparency problems

I want to draw transparent polygon(a pyramid for example). Some faces appear transparent where as some faces appear opaque.
Im drawing using GL_TRIANGLE_STRIP.
I have enabled blend mode, but no luck.
Please see the attached image,
This happens because of the draw order of the triangles. Some triangles get drawn first, these write their depth values to the depth texture, then the next triangle comes along and checks if there's something in front of it. If there is, then it won't render.
If a triangle that is at the back renders first, then there's no problem, the triangle in front of it looks at the depth texture, sees that it has a greater z value so it gets correctly rendered, these are the places where the color is less transparent.
The problem arises when the triangle at the front renders first. It writes it's depth value to the depth buffer, then the triangle in the back comes along, sees that there's already something in front of it, so it doesn't get rendered.
You have multiple ways to solve this, you can disable depth testing, sort the triangles so they come in order or use an algorithm like depth peeling. Each of these algorithms have side effects or are simply very complex, this is why you don't see too much transparency in games.

Is there any way to make front face of gluCylinder() transparent?

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.

OpenGL FBO - White pixels appear transparent

I'm making a 2D game using OpenGL. I recently tried implementing Framebuffer-objects, and I am having some problems regarding blending.
I'm creating an FBO (using GL_RGBA as format).
When I render to the FBO, I first clear it to fully transparent black, and disable GL_BLEND. I then draw my textures and then I enable GL_BLEND again.
When I'm drawing the FBO-texture, I use GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA as source and destination pixels respectively, as the blending-function. I am rendering it as a textured quad.
This does not work properly, as white pixels appear transparent. I have tried experimenting with different blend-function values, but all that I have tried have had issues. I do not fully understand how blending works, so it's hard for me to wrap my head around this. Maybe I'm missing something obvious here?
Here's an image of how it looks right now. There is supposed to be a glow around the button when it is being highlighted, but instead the pixels around it appear transparent: http://i.snag.gy/RnV4s.jpg
You can also see two boxes of text in the image. The top one is drawn normally, without an FBO. The textures are also rendered normally without an FBO, so I know that the problem lies within my framebuffer-code somewhere.
I have pasted my "RenderTarget" class to pastebin (I'm used to calling it a rendertarget instead of FBO): http://pastebin.com/dBXgjrUX
This is how I use it:
RT->Begin();
// draw stuff
RT->End();
RT->Draw();
Can someone help me? Let me know if you need any more info about my issue.
Edit:
Here are the properties of OpenGL that I set on startup:
// Initialize shaders
shaderManager.InitializeStockShaders();
// Set some OpenGL properties
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_SMOOTH);
glAlphaFunc(GL_GREATER, 0.0f);
// Enables/disables
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_DITHER);
glDisable(GL_LIGHTING);
I'ts a bit difficult to tell what your problem is exactly, because you didn't provide source code. Alas, I see several potential troublemakers:
First you told that you want to draw a glow around the button. I presume, that all the buttons are drawn into the FBO, merging them into a UI overlay. Glow sounds to me, like you want to blend something, so you probably also want to have blending enabled, drawing to the FBO.
Next be aware of depth buffer issues. Blending and Depth Buffering have peculiar interactions. In your case I suggest disabling depth testing and depth writes to the FBO (or not using a depth buffer attachment to the FBO at all). Draw the glowing button last, so that it won't block the other buttons from being drawn. Also you must make sure, that your glow comes out with a nonzero alpha value, otherwise it will blend transparent. This is something you control in your shaders, or texture environment (depending on what you use).
Update 1:
Your FBO class doesn't propperly ensure, that textures attached to a bound framebuffer must not be bound themself. It's easy to fix though, by moving attachment code into bind, where the textures are also unbound apropriately. See my edited pastebin http://pastebin.com/1uVT7VkR (I probably missed a few things).

C++, OpenGL Z-buffer prepass

I'm making a simple voxel engine (think Minecraft) and am currently at the stage of getting rid of occluded faces to gain some precious fps. I'm not very experimented in OpenGL and do not quite understand how the glColorMask magic works.
This is what I have:
// new and shiny
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// this one goes without saying
glEnable(GL_DEPTH_TEST);
// I want to see my code working, so fill the mask
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// fill the z-buffer, or whatever
glDepthFunc(GL_LESS);
glColorMask(0,0,0,0);
glDepthMask(GL_TRUE);
// do a first draw pass
world_display();
// now only show lines, so I can see the occluded lines do not display
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// I guess the error is somewhere here
glDepthFunc(GL_LEQUAL);
glColorMask(1,1,1,1);
glDepthMask(GL_FALSE);
// do a second draw pass for the real rendering
world_display();
This somewhat works, but once I change the camera position the world starts to fade away, I see less and less lines until nothing at all.
It sounds like you are not clearing your depth buffer.
You need to have depth writing enabled (via glDepthMask(GL_TRUE);) while you attempt to clear the depth buffer with glClear. You probably still have it disabled from the previous frame, causing all your clears to be no-ops in subsequenct frames. Just move your glDepthMask call before the glClear.
glColorMask and glDepthMask determine, which parts of the frame buffer are actually written to.
The idea of early Z culling is, to first render only the depth buffer part first -- the actual savings come from sorting the geometry near to far, so that the GPU can quickly discard occluded fragments. However while drawing the Z buffer you don't want to draw the color component: This allows you to switch of shaders, texturing, i.e. in short everything that's computationally intense.
A word of warning: Early Z only works with opaque geometry. Actually the whole depth buffer algorithm only works for opaque stuff. As soon as you're doing blending, you'll have to sort far to near and don't use depth buffering (search for "order independent transparency" for algorithms to overcome the associated problems).
S if you've got anything that's blended, remove it from the 'early Z' stage.
In the first pass you set
glDepthMask(1); // enable depth buffer writes
glColorMask(0,0,0); // disable color buffer writes
glDepthFunc(GL_LESS); // use normal depth oder testing
glEnable(GL_DEPTH_TEST); // and we want to perform depth tests
After the Z pass is done you change the settings a bit
glDepthMask(0); // don't write to the depth buffer
glColorMask(1,1,1); // now set the color component
glDepthFunc(GL_EQUAL); // only draw if the depth of the incoming fragment
// matches the depth already in the depth buffer
GL_LEQUAL does the job, too, but also lets fragments even closer than that in the depth buffer pass. But since no update of the depth buffer happens, anything between the origin and the stored depth will overwrite it, each time something is drawn there.
A slight change of the theme is using an 'early Z' populated depth buffer as a geometry buffer in multiple deferred shading passes afterwards.
To save further geometry, take a look into Occlusion Queries. With occlusion queries you ask the GPU how many, if any fragments pass all tests. This being a voxel engine you're probably using an octree or Kd tree. Drawing the spatial dividing faces (with glDepthMask(0), glColorMask(0,0,0)) of the tree's branches before traversing the branch tells you, if any geometry in that branch is visible at all. That combined with a near to far sorted traversal and a (coarse) frustum clipping on the tree will give you HUGE performance benefits.
z-pre pass can work with translucent objects. if they are translucent, do not render them in the prepass, then zsort and render.

Can you render two quads with transparency at the same point?

I'm learning about how to use JOGL and OpenGL to render texture-mapped quads. I have a test program and a test quad, and I figured out how to enable GL_BLEND so that I can specify the alpha value of a vertex to make a quad with a sort of gradient... but now I want this to show through to another textured quad at the same position.
Drawing two quads with the same vertex locations didn't work, it only renders the first quad. Is this possible then, or will I need to basically construct a custom texture on-the-fly based on what I want and then draw one quad with this texture? I was really hoping to take advantage of blending in this case...
Have a look at which glDepthFunc you're using, perhaps you're using GL_LESS/GL_GREATER and it could work if you're using GL_LEQUAL/GL_GEQUAL.
Its difficult to make out of the question what exactly you're trying to achieve but here's a try
For transparency to work correctly in OpenGL you need to draw the polygons from the furthest to the nearest to the camera. If you're scene is static this is definitely something you can do. But if it's rotating and moving then this is usually not feasible since you'll have to sort the polygons for each and every frame.
More on this can be found in this FAQ page:
http://www.opengl.org/resources/faq/technical/transparency.htm
For alpha blending, the renderer blends all colors behind the current transparent object (from the camera's point of view) at the time the transparent object is rendered. If the transparent object is rendered first, there is nothing behind it to blend with. If it's rendered second, it will have something to blend it with.
Try rendering your opaque quad first, then rendering your transparent quad second. Plus, make sure your opaque quad is slightly behind your transparent quad (relative to the camera) so you don't get z-buffer striping.