PDA

View Full Version : HailStone Map format


Feanor
2002.06.18, 01:25 PM
I need some ideas on the size of levels and how to measure them. I am most familiar with Quake, which used an integer value in the map file (used for editing), but might have used a float in the .bsp file (the file actually read by Quake as a level to play) -- documentation is sketchy on this point, so I may resort to browsing the source on that.

Given an 32-bit integer value for world co-ords gives four billion distinct vertex positions in any of the three directions -- this provides the graininess of the map. The finer the detail level relative to the player, the smaller the map. I guess that should be fine for HailStone, but once it's built into the engine, it might make it more difficult to extend the engine to use floating point values later.

The main difficulty of floating point is making sure the various polygons line up nicely. This is alleviated by sharing vertices amongst polygons, but then we can't use OpenGL dynamic lighting, because that depends upon properly oriented normals (and a situation where one vertex would need a separate normal for each polygon it is a part of). Not sharing polygons is also required for the best use of compiled vertex arrays, or so I gather. Anyway, vertex indices use up storage space which may as well simply be allocated to redundant vertex specifications. Dumping indices simplifies a lot of other things, too.

In that case, I have to have a facility to ensure that the map editor produces the vertices properly. It's possible I'll use a shared-vertex system for the editor, and then flatten the shapes for the level file and remove the indices altogether. This would be like the Quake .bsp compilation -- I'll undoubtedly want to create the view hierarchy at that time as well (though I'm not sure if I'm going to use a bsp or a dynamic visibility system).

So the last problem with floating point vertex specifications is making sure that different model pieces line up together. On an integer grid they either do or they don't. With floating point values, precision gets worse as we move away from the origin -- that's not good! If everything is measured local to a map area, or even local to the player position, this might solve that problem.

FÎanor

Nimrod
2002.06.18, 02:24 PM
Re: lining up polygons. Surely you can solve this problem in the editor, by snapping them to a grid by default?

I've always had polygons share vertices, it's just habit now, are you sure that it's faster not to do it nowadays? I'd be interested to know... Rather than storing the normal data in the vertex (if you share vertices), you could store it in the polygon along with the vertex indices.

I would've thought that 32-bit integers would give you enough room, unless you want so much detail that 65536 translates to 1 mm or something :p If you haven't got enough room while making a map, you're probably at a point where it's time to cut back on your map anyway, big isn't necessarily better!

Feanor
2002.06.20, 10:50 AM
The problem with shared vertices comes in when you decide:

1. lighting -- if you use OpenGL's lighting model, you can't specify the normals independently for each face, because OpenGL uses the normals at the vertices. To make the normals correct on a "real" polygon (as opposed to one that is approximating a curve), you need them all to match the desired face normal (which can't be specified separately). So a cube, for example, gets lit funny and the light blends across the faces, instead of making sharp lines along the edges.

2. vertex submission -- if you use vertex and normal arrays and index into them, then you use glDrawElements(). If you don't use indices, you can use glDrawArrays() (and Compiled Vertex Arrays, if they are available), which can speed up the performance. Indices also use up a lot of space.

The 3DKit which I am using for HailStone uses non-indexed arrays in any case. I will be maintaining my own indexed geometries in the level editor, and then converting them into 3dkit straight arrays during "compilation" (turning a level file into a world file).

You're probably right about the integer grid. I'll undoubtedly stick with that and when I rebuild my engine for high-detail, planet-size VR, I'll find a solution that lets me use localized floating point. But with floating point, there is no grid to snap to, although a good editor application can let you line up edges to other edges or planes.

inio
2002.07.03, 03:18 AM
a quick couple google searches indicates Quake3 uses glDrawElements.

'nuf said.

well, maybe not...

http://lists.ethernal.org/curves-kiddies-0102/msg00018.html
> What advantage do you think Carmack saw in glDrawElements that he used it
> instead? Its ease of use?

Possibly -- flexibility more likely. I don't know enough about modern
cards to know if there is a significant advantage to either. Carmack
does, and he does DrawElements, so it must be able to go full steam.

A long time ago I remember reading a document by Carmack talking about Quake 3's OpenGL optimizations. I found the URL of this document during my search but it has since dissappeared :(.

Allright, thats it, I've debated this in my head enough, I'm gonna go write a tester :) (look for a post in the 3d/ogl forum).

OneSadCookie
2002.07.03, 08:26 AM
I too am forever losing that document, failing to find it again, and rediscovering it entirely by accident. I don't even seem to have a local copy here :(

IIRC, Basically, Quake 3 sends all vertex data via:

glVertexPointer(3, GL_FLOAT, 4 * sizeof(GLfloat), pointer)

and

glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indices)

The triangles are organized into tri-strip order where possible, though, to help the vertex cache on H/W T&L cards.

It sounds to me as if Hail Stone / Storm Cloud are targeting the same kinds of 3D accelerators as Q3A did when it was originally released, so that's probably a good indication of what's fast :)

If you up your requirements to GeForce2MX/Radeon & above, though, you probably want to do things differently...

inio
2002.07.06, 04:43 AM
As promised, I did the tests, and glDrawElements is still the fastest way (http://64.246.17.165/forum/showthread.php?threadid=422) to send polygons to a video card, usually.