OpenGL; Overlapping Alpha-Transparent Particles - c

I am writing an OpenGL program in C that implements alpha-transparent bill boarding particles that use a PNG (with transparency) as their texture via pnglib. However, I have discovered that a particle's transparent zones will still replace particles called before it that are also behind it. In other words, particles newly called, though transparent in some areas, are completely overlapping some particles called before them when, instead, those previously called particles should be showing through the transparency.
In order to visualize the effect this is having, I am attaching a few images to display the problem:
Initially I am calling the particles from oldest-to-newest:
However when the view is changed, the overlapping effect is apparent:
When I decide to reverse the call order I get the opposite:
I believe that a solution to this would involve calling the particles in order from farthest from the camera to nearest. However, it is pretty computationally heavy to go through each active particle, order them from furthest-to-nearest, and then call each one every display frame. I am hoping to find an easier, more efficient solution. I've already tried my hand with glBlendFunc() but no sfactor or dfactor seems to work.

Draw all non transparent geometry first. Then, before drawing the particles, disable the depth-buffer writes by calling glDepthMask (GL_FALSE)
That will fix most of the rendering problems.
Sorting the particles by distance from the camera is still a good idea. With todays CPU power that shouldn't be much of a problem.

Related

Clutter: Perspective, Skew, and Matrices

Is there a way to change the clutter perspective for a given container or widget?
The clutter perspective controls how all the clutter actors on the screen are displayed when rotated, translated, scaled, etc.
What I would really like to do is to change the perspective's origin from the center of the screen to another coordinate.
I have messed with a few of the stage methods. However, I haven't had much luck understanding some of the results, and often I hit some stability issues.
I know there are transformation matrices that do all the logic under the hood, and there are documented ways to change the transform matrices. Honestly, I haven't researched much further and just though I would ask for guidance before spending a lot of time on it.
Which leads me to another question regarding the matrices and transformations. Can one of these matrices be used to skew an actor? Or deform it into a trapezoid, etc? And any idea how to get started on that, ie. what a skew matrix would look like?
Finally, does anyone know why the clip path was deprecated? It seems that would have worked for what I ultimately want to do: draw irregular shaped 2d objects on the screen If I can implement an answer to question 2, then I guess a clip box with a transformation can be used here.
1, I do not know if (or how) one might change the Clutter stage's focal point.
2 A skew or shear transformation matrix is easy enough to construct, and can be implemented in the GJS Clutter functions Clutter.Actor.set_transform(T) and Clutter.Actor.set_child_transform(T) where T is a Clutter.Matrix .
This does present another problem, however, for the current codebase; and this leads to another question. (I guess I should post it somewhere else). But, when a transform is set on a clutter actor (or its children), the rest of the actor's properties are ignored. This has the added effect that the Tweener library cannot be used for animation of these properties.
3 Finally, one can use Cairo to draw irregular shaped objects and paths on a Clutter actor, however, the reactive area for the actor (ie. mouse-enter and -leave events) will still be for the entire actor, not defined by the Cairo path.

OpenGL rendering quality vs. number of vertices

I am coding a modern OpenGL application to visualize 3d atomic models (molecules, periodic systems ...) for chemistry and condense matter physics.
I started to work on this few years ago, the first version of my program was in old OpenGL now I am updating it to modern OpenGL.
I come with a question regarding the quality of the rendering of the OpenGL window. In the following examples I draw 3D cylinders and 3D spheres using instanced drawing, in this model to render the bonds I only draw one cylinder, then I translate/scale/rotate it properly in the vertex shader
to render all bonds, same goes for the sphere to render the atoms.
As you can see it works just fine, and the efficiency of the method is amazing and I can render models with hundreds of thousand of atoms smoothly.
However I noticed something weird, that somehow the quality of the rendering seems to be dependent on the number of vertices (objects, atoms and bonds) in the scene, obviously the number of triangles is the most important parameter but not the only one ... since the quality decrease when a lot of vertices are rendered ... please see the attached snapshots:
To render the spheres in the scene I am using 50x50 vertices, and 2x50 for the cylinders (GL_TRIANGLE_STRIP in both cases)
1) In this test model I load: 96 atoms, 512 half bonds, : ~ 291200 vertices:
2) I zoom in to focus on one selected atom and it surrounding, at this scale the result is impeccable:
3) I reset the view and use the builder in my program to increase the number of boxes
(I am simply doing replicas in the 3 direction of space) here I choose to do 20x20x20 replicas,
see the result bellow, the original box is highlighted.
In that scene there are 768000 atoms, 4096000 half-bonds, and thus: 291200x20x20x20 = 2329600000 vertices
quite a lot, yet it works, but something weird appears ...
4) I zoom in again on that particular area of the model I picked before and there is a decrease in quality in particular
in the areas where 3D objects (spheres/cylinders) superimpose/overlap ...
Can somebody explain to me what I see ?
Note 1: In the same window I can decrease the number of replicas back to the original box, zoom again
and see that the result is back to impeccable.
Note 2: the older version of my program still works fine (old OpenGL, using display list with glutsphere and glutcylinders),
I can do the same things, the rendering will take much much longer, but at the end of the process when I zoom in on the 20x20x20
boxes model, the results remains perfect, like for the single box model, and obviously I use same graphic card, driver and else.
Can somebody explain to me what I see ?
You're seeing the limited precision of the depth buffer. There are only so many bits you can work with and in a perspective projection a lonlinear scaling from Z distance to depth buffer value is applied.
The best course of action is to limit the near/depth range of the perspective projection matrix to what's going to be actually visible on screen, to make better use of the depth buffer. Also it's possible to linearize the depth buffer (but that comes with a performance hit). Also you could try to cleanly intersect the geometry where sticks and spheres meet, i.e. constrain the sphere's vertices to the cylinder surface where the sticks and similarly constrain the sticks' end vertices to the sphere where they meet. That way you avoid overlap and hence these artifacts.

VBO for tilemap (draw order and slanted aerial 2D)

I want to draw a tilemap in a (ANSI C, C99 cannot be used due to windows compatibility) game that uses GL for accelerated graphics, although the game is a top-down 2D perspective using textured quads.
The popular opinion for handling a timemap seems to use a GL vertex buffer object, which I am about to write. However, I realized I want some tiles to go a little beyond vertical bounds, faking a slanted aerial view. That will make whatever is directly above the block to be partially covered by the tile.
If I use a VBO here, I will need to draw the entire tilemap in one sitting. Meaning that any object I draw afterwards will be directly on top of the tilemap.
What would be the sanest approach to this problem? Should I draw the tilemap first, then the entities (players/enemies) and then the excess vertical space so they cover the entities, and finally the effects that display over both? (such as shots, explosions, etcetera). But this would give me the issue of shots not being covered by terrain, and if I change the order, terrain covering large explosions awkwardly.
Alternatively I can sort all visual objects and draw them in a top-down fashion, but that would mean I need to change textures often, as sorting by texture wouldn't help too much in this specific case.
As well, I want to be able to modify the colors of every individual vertex in the grid in a dynamic way, so that entities can cast colors into the map. From what I am understanding, the way to achieve this would be with a vertex shader. Is this correct?
EDIT: A last thing. If I draw a VBO like that tilemap that is larger than the screen,by translating, does GL automatically cull out-of-view faces or do I need to reform the VBO every time I move the "camera"?
A VBO is just a piece of abstract memory reserved in the graphics memory. You can place data in any layout and arrangement as you like. You can use a single VBO to store several independent meshes. gl{Vertex,Normal,TexCoord,Color,Attrib}Pointer functions are used to set the offset into memory, that means either process address space or offset into the bound VBO.
Furthermore once can easily draw only subsets of the bound data with either glDrawArrays and glDrawElements by choosing approriate first element or indices in the index buffer.
So, no, you don't have to draw entire VBOs.
I actually answered my own question. I needed to separate the map in two: blocks that have empty space directly on top, and then the rest. Effects will be drawn in two passes, "regular" and "top" "layer"
I feel pretty bad about having an useless question lying around though, so if some admin needs to purge it, please go ahead.

Determining if a polygon is inside the viewing frustum

here are my questions. I heard that opengl ignores the vertices which are outside the viewing frustum and doesn't consider them in rendering pipeline. Recently I ran into a same post that said you should check this your self and if a point is not inside, it is you duty to find out not opengl's! Now,
Is this true about opengl? does it understand if a point is not inside, and not to render it?
I am developing a grass scene which has about 4000 grasses on rectangles. I have awful FPS, and the only solution I came up was to decide which grasses are inside the viewport and then only render them! My question here is that what solution is best for me to find out which rectangle is not inside or which one is?
Please consider that my question is not about points mainly but about rectangles. Also I need to sort the grasses based on their distance, so it is better if native on client side memory.
Please let me know if there are any effective and real-time ways to find out if any given mesh is inside or outside the frustum. Thanks.
Even if is true then OpenGL does not show polygons outside the frustum ( as any other 3d engines ) it has to consider them to check if there are inside or not and then fps slow down. Usually some smart optimization algorithm is needed to avoid flooding the scene with invisible objects. Check for example BSP trees+PVS or Portals as a starting point.
To check if there is some bottleneck in the application, you can try with gDebugger. If nothing is reasonable wrong optimizing in order to draw just the PVS ( possible visible set ) is the way to go.
OpenGL won't render pixels ("fragments") outside your screen, so it has to clip somehow...
More precisely :
You submit your geometry
You make a Draw Call (glDrawArrays or glDrawElements)
Each vertex goes through the vertex shader, which computes the final position of the vertex in camera space. If you didn't write a vertex shader (=old opengl), the driver will create one for you.
The perspective division transforms these coordinates in Normalized Device Coordinates. Roughly, its means that the frustum of your camera is deformed to fit in a [-1,1]x[-1,1]x[-1,1] box
Everything outside this box is clipped. This can mean completely discarding a triangle, or subdivide it if it is across a clipping plane
Each remaining triangle is rasterized into fragments
Each fragment goes through the fragment shader
So basically, OpenGL knows how to clip, but each vertex still has to go through the vertex shader. So submitting your entire world will work, of course, but if you can find a way not to submit everything, your GPU will be happier.
This is a tradeoff, of course. If you spend 10ms checking each and every patch of grass on the CPU so that the GPU has only the minimal amount of data to draw, it's not a good solution either.
If you want to optimize grass, I suggest culling big patches (5m x 5m or so). It's standard AABB-frustum testing.
If you want to optimize a more generic model, you can investigate quadtree for "flat" models, octrees and bsp-trees for more complex objects.
Yes, OpenGL does not rasterize triangles outsize the viewing frustrum. But, this doesn't mean that this is optimal for applications: OpenGL implementation shall transform the vertex coordinate (by using fixed pipeline or vertex shaders), then, having the normalized coordinates it finally knows whether the triangle lie inside the viewing frustrum.
This mean that no pixel is rasterized in that cases, but the vertex data is processed all the same; simply doesn't produce fragments derived from a non visible triangle!
The OpenGL extension ARB_occlusion_query may help you, but in the discussion section make it clear:
Do occlusion queries make other visibility algorithms obsolete?
No.
Occlusion queries are helpful, but they are not a cure-all. They
should be only one of many items in your bag of tricks to decide
whether objects are visible or invisible. They are not an excuse
to skip frustum culling, or precomputing visibility using portals
for static environments, or other standard visibility techniques.
For the question regarding the mesh sorting on depth, you shall use the depth buffer: essentially the mesh fragment is effectively rendered only if its distance from the viewport is less than the previous fragment in the same position. This make you aware of sorting meshes. This buffer is essentially free, and it allows you to improve performances since it discard more far fragments.
Yes. Like others have pointed out, OpenGL has to perform a lot of per-vertex operations to determine if it is in the frustum. It must do this for every vertex you send it. In addition to the processing overhead that must take place, keep in mind that there is also additional overhead in the transmission of those vertices from the CPU to the GPU. You want to avoid sending information to the GPU that it isn't going to use. Though the bandwidth between the CPU and GPU is quite good on modern hardware, there's still a limit.
What you want is a Scene Graph. Scene graphs are frequently implemented with some kind of spatial partitioning scheme, e.g., Quadtrees, Octrees, BSPTrees, etc etc. Spatial partitioning allows you to intelligently determine what geometries are visible. Instead of doing this on a per-vertex basis (like OpenGL is forced to do) it can eliminate huge spatial subsets of geometry at a time. When rendering a complex scene, the performance savings can be enormous.

WPF tabswitch/ render takes too much time

I have a WPF application with many tabs..
in one tab.. i make a verycomplex vector drawing consisting of thousands of drawing visuals.. (this represents a machine and all elements need to be interactable..)
It takes 3/4 seconds for drawing this for the first time..After the first draw it should be done..
The problem is if i switch to another tab and comeback, it takes atlease 2,3 seconds to show the tabpage with drawing again.. Since there is no redraw, why should it take so much time..?
If the component is not going to change, you could call Freeze() on it to mark it as done. Without trying it out I don't know if that would help, but you could give it a shot.
Not all objects are Freezable. Check out the MSDN documentation for more info:
http://msdn.microsoft.com/en-us/library/ms750509.aspx
Another thing you could try would be rendering the vector art to a bitmap, and displaying that. Maybe it makes you feel icky to lose the vector precision, but if you know it's not going to change and it will look the same, what's the harm? (If you support printing or something that will require a hi-res version, you could always switch back for that operation.) For info on how to convert a UIElement to a bitmap, check out:
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.rendertargetbitmap.aspx
Another possible solution: You don't really explain what kind of interaction you are doing with the elements, but if all you want to do is zoom and pan, a RenderTransform may be good enough (which is more efficient than a LayoutTransform and/or moving all the elements individually). I haven't played around with combining Freeze() and a RenderTransform, but you may be able to get the desired zooming while reducing the amount of layout WPF has to do.

Resources