Portals and OpenGL

I am going to implement OpenGL in my portal engine. My question is how to check if a polygon has really be drawn when depth testing is enabled, that is if the polygon is totally hidden. I want to draw a portal and only draw the sector behind that when the portal is visible.

Why not cull portals against the frustum using mathematics instead?

I do not want to clip the portal against the frustum, I want to find out if the portal is hidden by other polygons. Something like this:

glBegin(POLY)

for(i = 0; i < numVertices; i++)
glVertex(vert[i].x, vert[i].y, vert[i].z)

glEnd

if(glPolyDrawn)
DrawNextSector();

Ok, I see. I dont know of any clever way to check if a polygon is hidden completely by other polygons through OpenGL functions.

Hmm… Are your sectors convex?. If so, I dont see why you need to check if the portal is hidden by other polygons/walls. Just check the portal to frustums and cull away backfacing portals.

Or do you have other stuff in your sector big enough to hide portals?.

If your sectors are concave… Subdivide them to convex!

My sectors are convex, because of my old own drawing functions which do not use OpenGL.

But consider this example:
(Use a font like monaco or courier)

| 1 |

^
x

The camera is the x in the left-bottom sector. All sectors are convex, but still in this case the portal connecting the sectors 1 and 2 has not to be drawn. I am currently using big maps with about 100 textured walls. Finding out which sectors to draw would give the computer/graficcard more time to do other things.

Oh, I see, spaces are suppressed. Here it is again. Replace points with spaces.

|…1…|

.^.
.
.x.

-----.-----

Can someone help?

In your example, is the problem that sector 2 will be drawn?.
If so, it would be solved by the methods I described in my earlier posts.

How?. Well, after you’ve drawn the sector you are in, you calculate a new frustum of the viewpoint and the portal to sector 1. Then you draw everything in sector 1 that is within this new frustum. Is the portal to sector 2 in this frustum?. No it is not. So then you are done.

Infact, the portal to sector 2 would not even be considered in the frustum test since it is not facing the viewer.

Happy new year

Good idea, then I would not even need to have depth-testing on. But how do you add the portal to the frustum so only the walls in the portal will be drawn?

I’m not following your last post… Dont understand the question. Sorry.
Do you want to know how to build a new frustum from a portal and the viewpoint?

I’m by no mean an expert on portalengines. I’ve so far only read about them,

If thats the only way to clip the polygons, then that is what I need. But then I also have to know how to clip polygons with the frustum.

Clipping polygons to the frustum is relatively easy and straight forward. What you really do is clip the polygon by each plane of the frustum recursively. There are three cases to deal with then. First a polygon may be completely behind the plane (and therefore completely clipped by the frustum so an early exit can occur). Second, it may be completely in front of the plane so the entire polygon gets presented to the next plane in the frustum and this process is repeated with that plane. When all planes have been used and the polygon is in front of all of them then the resulting polygon is in the frustum. The third case is when a plane of the frustum clips a polygon partially, in which case you basically have two options, treat a partial clip as no clip and accept some amount of overdraw, or split the polygon and continue testing the portion of the polygon that is in front. This way each plane of the frustum gets a chance to chop away a portion of the polygon. Note, this may produce ‘sparklie’ visual artifacts due to floating point errors. These errors can be easily removed by offsetting the planes backwards by a small amount when you use them to split the polygon.

[This message has been edited by DFrey (edited 01-02-2001).]

In my own Portal Engine I clip the polygons to screen boundaries. So I have to do the same only with the frustum in 3D. Seams to be easy. The only problem is that I use gluPerspective instead glFrustum. How do I get the frustum then? Backface removal can also be done easily by using glFrontFace, enabling backface removal and then telling OpenGL the normal vector of each vertex I’m drawing. Am I right?

Then I only have to know how to clip the frustum to a portal. Look at this: (replace points with spaces and use a font like manaco or courier)

…/
…----…/
…/
…/
…/
…/
…x

x is the camera, the triangle the frustum and the line the portal. Then I have to let the frustum “go” through the portal. Like this:

…______
…/
…–/…- portal
…/
…/
…/
…/
…x

But how?

Perhaps I’m missing something, but have you tried select mode?

Look into glRenderMode(GL_SELECT) and its supporting functions. This rendering mode will tell you, quite simply, if the geometry you sent would have been rendered. It does not actually render anything.

The documentation is fuzzy as to whether this is valid when using array-rendering functions rather than begin/end pairs, so you’ll want to run a small test or two first.

Good luck,
– Jeff

Easy. Each edge of the portal together with the view point form a plane of the clipped frustum. Here again, you have an option to clip your frustum to the original portal polygon (inviting some overdraw), or to the potentially clipped portal polygon (accurate but generally requires more cpu). Which way is better is largely a function of what is beyond the portal. If there are a few large polys beyond the portal then I’d clip the frustum to the potentially clipped portal. Conversely if there are lots of small detail polys beyond the portal I’d clip against the original portal (assuming it was simpler in design) and live with the overdraw.

Ok, I’ll look at the GL_SELECT mode. Can I change the frustum with that by drawing the portal with GL_LINE_LOOP and then switch back to the normal mode. Well, I’ll look for some sample code about that…

I would strongly advise against using selection mode. Doing so for a portal engine is using OpenGL as a math library, and performance will suffer greatly. And it only determines if a given primitive is in the viewing volume, not within any particular frustum. So doing this would invite overdraw or the use of one or more user clip planes. One note of caution, user clip planes are not likely to lead to an optimized path through most OpenGL implementations.

I made an incorrect assumption when suggesting GL_SELECT. Data is returned prior to fragment tests. Given this knowledge, a manual frustum intersection test would probably be better.

The only solution which comes to mind is (probably) rather slow. One could use the stencil buffer as a feedback mechanism, disabling color buffer updates, and only updating the stencil buffer if the depth-test passed. One could then test for any non-default values in the stencil buffer with glReadPixels… hehehe. I wonder if there’s any way I could make that slower…

I think I’ll go post in ‘future opengl’ with an extension suggestion to resolve the issue.

– Jeff

I am not understanding the last repies. I think I will use the depth buffer until I’ll understand OpenGL better. Thanks to everybody who tried to help.

Have a look at www.flipcode.com/portal It is a collection of tutorials based on making a portal based engine and covers alot of the topics covered in the previous replies.

Seems to have a lot of info, but it doesn’t work with OpenGL. Bad…