Skip to content

Avogadro: New Ring & Polygon Engines

I recently added a couple of new engines to Avogadro and the screen shot below shows them both. The ring engine finds all the rings of the molecule and draws a transparent plane through the ring. The polygon engine finds atomic centres with three or more atoms bonded and draws a polygon around that atom. This is only done for atoms that are not the common organic types.

Avogadro using the ring and polygon engines

I think these are useful engines that have been prompted by user requests. May be not as exciting as the ribbon engine or the surface support we are working on but useful to display certain structures. The ring engine has not been without its problems though as you can probably spot in the image below showing the ring engine rendering a carbon nanotube.

Avogadro using the ring engine to render a nanotube

The lighting just flips at certain points - the same happens as you rotate molecules that are using the ring or polygon engine. I guess the lighting is flicking on at certain angles. I would be interested if anyone with more OpenGL knowledge than I might know how I can improve the rendering. Some rings are near white and some of the back rings don't seem to be drawn - that could actually be drawing order though which is always tough to get right.

Comments and tips are always welcome. The big challenge right now is getting surface support added in. This is something I think we really need and I would use in my daily work as I am sure many others would. I have been reading up on marching cubes and stuff but would welcome tips in that area too!

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

ephemient on :

ephemientIf you have the OpenGL Programming Guide (the red book), you should look at chapter 5's "Lighting / Selecting a Lighting Model / Two-Sided Lighting". Also, chapter 6's "Blending, Antialiasing, Fog, and Polygon Offset / Blending / Three-Dimensional Blending with the Depth Buffer" has an important hint regarding order of drawing transparent objects. I don't see your code in svn yet, so I dunno if you're doing it right...

Benoit Jacob on :

Benoit JacobGreat work!

I think we have two separate issues there. One with the z-buffer preventing certain polygons from being drawn at all, and one with wrong normal vectors causing the lighting to "flip at certain points" because a normal vector is the opposite of what it should be.

Since you have transparent objects that can be seen from either side, you probably have to draw them twice with two different (opposite) normal vectors.

I wanted to say more but I'm in a hurry to leave -- also I admit it's a nontrivial issue!

Good luck,

Benoit

ephemient on :

ephemientRight, I gave references to The Red Book for exactly those issues. But since Benoit touched on them, I might as well expand on them here...

(a) The depth buffer might be occluding some of the transparent polygons. The correct order of operations is:
1. Draw opaque objects with depth buffer enabled, because it's easier that way.
2. Draw transparent objects with depth testing enabled, but without writing to the depth buffer. This allows the opaque objects to correctly occlude the transparent objects, but makes the transparent objects blend instead of occluding each other.
3. Because the depth buffer is not being used, you need to do painter's algorithm yourself, drawing the furthest transparent objects first. Yes, this is a huge pain! But OpenGL's alpha blending comes out with incorrect results if you don't do this. Consider a red polygon and a blue polygon, both with alpha 0.5, overlaying each other: if red is drawn first, the final color is [0.5,0,1]; if blue is drawn first, the final color is [1,0.0.5].

(b) If a polygon is facing away from a light, the normal is facing the wrong way relative to what you want, and this can give you messed up shading.

Looking at the screenshot in more detail, I'm pretty sure you're suffering from (a), I'm not so sure about (b).

Marcus D. Hanwell on :

Marcus D. HanwellThe code was already checked in and is still there. The problem is with big systems depth sorting destroys the performance but this possibly means we shouldn't support transparent rings...

Now the normal flipping seems a tougher problem to solve. It is apparent in the bottom right of the nanotube. The algorithm has to work across all molecules - not just this one. I can fix that example by working out the centre of the nanotube but this breaks many other flat molecules in this sense. I am not sure on the best fix.

I think with transparent rings I will have to do depth sorting to get it right. When opaque I could switch that off.

ephemient on :

ephemientI was looking in anonsvn/trunk/KDE/kdeedu/kalzium/libavogadro-kalzium; I guess that's not the right place.

Normals can be trivially fixed by using
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
(it incurs a performance penalty, but it's easy).

I was guessing that the depth-buffer was responsible for the lack of polygons in the back of the tube, by the upper-left and lower-right of the screenshot. That is easy to handle.
glDepthMask(GL_TRUE);
// draw opaque
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
// draw transparent

Sorting is a gigantic pain. However, with these simple grays, you could get away without anybody noticing it. :-)

Marcus D. Hanwell on :

Marcus D. HanwellAh - that is a snapshot of Avogadro 0.1. You can get Avogadro trunk from sourceforge - check out http://avogadro.sourceforge.net/. Kalzium 4.1 will use the actual Avogadro library - right now it uses a snapshot as we were not ready for binary stability and the KDE 4.0 tree freeze was too soon.

I didn't think the two pass rendering in that way would work. I will give it a try. Thanks for the tips - I will see what I can do. I always appreciate input - feel free to checkout the code and tell me where I screwed up too ;-)

Marcus D. Hanwell on :

Marcus D. HanwellI was guessing that the depth-buffer was responsible for the lack of polygons in the back of the tube, by the upper-left and lower-right of the screenshot. That is easy to handle.
glDepthMask(GL_TRUE);
// draw opaque
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
// draw transparent

That won't work in this case as far as I see and we are effectively doing that already. All of the rings are transparent and the only way to get proper blending would be to depth sort I think. We already draw all opaque engines before transparent ones and that works for most things.

Ray Giguere on :

Ray GiguereNice molecular images. You may find the following link to an new exhibition about molecules:

http://tang.skidmore.edu/4/exhibitions/doc/2070/

http://tang.skidmore.edu/4/exhibitions/show/1771/doc/2280/

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA 1CAPTCHA 2CAPTCHA 3CAPTCHA 4CAPTCHA 5


You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.