> Date: Mon, 24 Mar 2003 17:30:50 -0800 > From: Justin Couch <[EMAIL PROTECTED]> > Mark Hood wrote: > > > Indexed geometry is great for storage and convenient for > > representation, but terrible for rendering. Graphics hardware wants > > contiguous streams of vertex data for the best performance. With > > indices you can skip around vertex data -- this destroys all > > locality of reference and creates shorter data packets across the > > graphics bus. > > Except that you have also destroyed the end user's request that they > want to optimise in a different way - minimal bus usage. By using > indexed geometry, that's what they are asking for. If they wanted to > provide interleaved data, then there is the facilities to do so in > Java3D. Don't screw around with the data in the way we want it > presented.
So, is your suggestion that Java 3D iterate through the index arrays and send off individual vertex-level commands to the native graphics layer for every indexed geometry array every frame? That would be fairly slow (the vertex-level immediate mode API of OpenGL, while extremely flexible, has a lot of overhead), but not unreasonable for applications prepared to make that tradeoff. It's important to note however, that the scenegraph is also used to derive information for spatial queries, so it would slow down other aspects of the system as well as rendering. I suspect that the overall performance implications and the desire to reduce the complexity of the code led to the implementation decisions to which you object. > We know best how to render our geometry and how we want to > optimise. Not you. If we want to pass it in indexed, leave it that > way. The low level graphics APIs support that form, so there is no > reason not to let it be that way. > [...] > > Allowing more fine-grained update sematics to the API could be a > > reasonable RFE for the next major release of Java 3D. If anybody > > thinks this is important for their indexed geometry application, > > please submit the RFE. > > There is no reason for one. All I want you to do is honour what I've > requested of the rendering API, not what you happen to think might be > best. It's not clear to me that using indexed geometry necessarily means that the programmer is signaling to the implementation that it should conserve memory at the expense of rendering performance. A programmer might decide to use indexed geometry simply because it seems easier to code, or because the data was already in that format, or perhaps because some random loader delivered it that way. Of course you know what you're doing. But anybody who's read this interest list can see that many folks using a high-level scene graph API have the opposite expectation: they want the implementation to figure out what best to do with the data. And implementors of the API and licensees of the source code want to have the flexibility to tune their implementations and add their own value to it. For the most part, Java 3D tries to accomodate that point of view, while providing hooks for advanced users to have more control. Baking in overly rigid implementation semantics into a high-level API can have the effect of making it obsolete faster. Of course it's a balancing act, and mistakes will be made. The RFE mechanism is there to correct mistakes and omissions. As Kelvin pointed out, the USE_COORD_INDEX_ONLY attribute was added to IndexedGeometryArray in Java 3D 1.3 for exactly that problem you're experiencing. A single index array for coordinates, colors, normals, and textures enables Java 3D to use vertex arrays and a single call to the DrawElements OpenGL command to render indexed geometry directly without having to unindexify them. (We need to add a note to the performance guide to this effect). If USE_COORD_INDEX_ONLY is not specified, then we can't use DrawElements to render the geometry. We either have to iterate through the index arrays each time or copy the vertex data to an array in the correct order. The Java 3D sample implementation does the latter. > > We have never characterized indexed geometry as high-performance and > > don't recommend it for performance-sensitive applications. Using > > by-reference mode for the vertex data doesn't improve the situation. > > What do you define as "performance sensitive"? If I have an > application that uses minimal geometry but heavy textures, I want that > bus allocated to shipping my textures in and out of main memory. I > don't want it lost to someone else deciding to unindex the geometry on > me and generating bucketloads of garbage. My code wants to optimise > for minimal geometry being passed over the bus because other far more > important things need it, and rendering performance is going to be > impacted by something else far greater. The graphics system architectures with which I'm familiar don't work that way. I was referring to how the data is transfered, not the amount of data going over the bus. Generally for highest performance you want to initiate a DMA or a low-level system call to transfer the data asynchronously from the client thread, so that it can return immediately and do other tasks while the transfer takes place and the data is rendered. OpenGL can't do this if the client is making individual vertex-level calls while sitting in a loop iterating over an index array; it either has to buffer the data (copy it), or generate a sequence of short transfers that are much slower than one big transfer. This is also why the attribute and state sorting features of the scene graph are so important -- you want to minimize interruptions to the transfer of consistent vertex and texture data. > > There isn't any way for Java 3D to find out if you've changed a normal > > or a texture coordinate in one or more of the array elements addressed > > by the reference without iterating through all the data and keeping a > > copy itself for comparison. > > What's that got to do with it? If I've told you I've changed the normal > data, but nothing else, then that's all I've changed. I was referring to the by-reference mode for indexed geometry arrays. In by-reference mode you can update individual array elements directly without changing the array reference. There isn't any mechanism in the GeometryUpdater interface to indicate that only the normal data has changed, so the current implementation reindexes and recopies everything if USE_COORD_INDEX_ONLY is not set. That's why I suggested the RFE. -- Mark Hood =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA3D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
