OpenGL Architecture Review Board Meeting Sunnyvale, California Monday-Wednesday, December 5-7, 1994 Host: Intel Corporation Attendees Chris Frazier, Silicon Graphics Neil Trevett, 3Dlabs Israel Pinkas, Intel Paula Womack, Silicon Graphics Henri Warren, Megatek Mike Heck, Template Graphics Software Bruce D'Amora, IBM Jim Miller, IBM John Dennis, Digital Jim Cobb, Evans & Sutherland Linas Vepstas, IBM Hock San Lee, Microsoft Dale Kirkland, Intergraph Jeremy Morris, 3Dlabs Kurt Akeley, Silicon Graphics Mason Woo, Silicon Graphics Monday at 1 PM Meeting commenced in parking lot, as Kurt shows us his Lotus automobile with license plates which read "OpenGL." Some discussion about whether the Lotus should be added to the GLU. :-) Jeremy Morris, 3Dlabs presents GLINT chip/functionality * All OpenGL modes in silicon , including texture memory, antialiasing, fogging, alpha, etc. * Many questions about texture * Prices discussed $150 chip; premium for additional $30 retail price--after integration--$700+ can use as coprocessor to S3 architecture; street price $500 for integrated board * Q1 next year for volume ship * 3Dlabs is a chip vendor/30 board vendors are lined up; mainly PC; including SPEA, Omnicomp, Barco Graphics, etc. * OpenGL installable client driver * Can sit in parallel with software implementation with Microsoft's. * GLINT input and output FIFOs allow pixel data to be written and retrieved from framebuffer and localbuffer. (Under Windows NT, pixel data can be returned to host via shared memory.) GLINT Spec is freely available. Neil Trevett, VP of Marketing at 3Dlabs will provide a spec. Live demonstration ensues on PC with OpenGL on Windows NT (what we saw and discussed): * screen saver (3D pipes) drawing with fog, no performance loss * RAMDAC trick (interleaving) performed for double buffering on first window. Subsequent windows will use blt for double buffering. * Scissor rectangles used for window clipping (not window ID bits) * geometry calculations on host; uses DMA for transfer of chip commands from host to hardware * color modes demonstrated: 4 bit dithered and true-color * roller coaster demo with 18,000 polygons; double buffered true-color When smaller than full screen, blts. At full screen, special mode for double buffering ------- Spec and conformance Chris Frazier leads discussion additions * man page glNewList Jim Cobb: what about memory error? Linas: GL_OUT_OF_MEMORY error Kurt: extension documents don't have explicit OUT_OF_MEMORY statement, best to have overall explicit message that these can happen at any time. Jim: since display lists have compile and execute, this is a special case Linas: "errors generated by commands in a display list" Israel: out of memory error can happen at any time. vote on corrections to man page: 7-0 * 17 man page change for gluPerspective for depth buffer precision Israel: Is log r bits the right number? Kurt: The larger the number, the more correct this rule is. vote on corrections to man page: 7-0 * Old action item: add matrix description to gluPerspective, which was voted on last spring Linas: somewhere along the way, near and far got reversed. Kurt: As a programmer, you can do this either way Clarifications * 105 glGetError man page What happens when you call glGetError? Hock: If there is no current context when you call glGetError, what should happen? Kurt: You have to wait until there is a valid time to run glGetError() Paula: If you don't have a current context, ANYTHING can happen. You can crash. wgl can take a stricter approach, if it wants. first half of 105 voted on: 7-0 To satisfy action item from previous meeting, change man page Kurt: don't want to get into detail about when error is generated. Hock: what happens if you call glGetError several times in a glBegin/glEnd? Many: user error. glGetError() query should not take place in there. Chris: wish to append that sentence vote on last half of 105: 7-0 * 106 change all man pages which read as "call" to glEnd, to "execution" of glEnd. will change many man pages. Linas: why bother? Kurt: this is actually an issue. Israel: can you have a display list with no begin, but with an end? Kurt: sure. Vote 7-0. Typos: * 93 glBlendFunc--hyphenation vote 7-0 to remove hyphen from source-blending Clarification last time, new NURBS properties added, but we did not mention to add these to gluGetNurbsProperty. Issue 29: an entire chunk of state can get copied. Assumed that it does it in an atomic chunk. Really, the state gets copied sequentially. There is some state, which depends upon other state. Chris: Is this important? Israel: If it is ambiguous, two different ways will occur. Chris: Is anyone using CopyContext? Israel: Maybe we should wait awhile and find out more. Chris reviews possible interpretations and solutions. Electronic vote to occur after everyone has looked at this. Including some sample programs. Query to all licensees. Issue 30 Some glu commands probably generate display listable OpenGL commands. None are display listable, formally. some discussion; need investigation, maybe a proposal. Paula: it's not obvious now what to do. < take a break > Issue 31 If points are colinear, are they front-facing or back-facing? Indeterminate until n+1 vertices, where n are colinear. Jim Cobb: OpenGL was wise on punting on non-convex polygons. Should be the same here. John Dennis: Another is to do it for lines. Assume it's front facing. Chris: My experience is that this can happen for clipped polygons. Many others: wouldn't clipping replace n vertices with just two? Jim Cobb: at the poles of a sphere, the quads are actually triangles; better do it as front facing! Chris: put no language in the spec to save an indeterminate number of vertices. Maybe can special case quads, convert larger polys into tri fans. Jim Cobb: page 17 (1.0.14) of spec. More than 2 vertices are never required. Linas and others will form a group to firm up a proposal, based upon discussion which began electronically. Issue 32 Should texture in CI mode generate an Error? (Originally discussion from Linas Vepstas and Andy Vesper). Jim, John: So what? Nobody is going to want to do this. Kurt: Can only interpolate one, not several channels of color. Jim: I don't think it's broken now. You're allowed to make RGB calls now in CI mode; it just works. It may not look right, but it doesn't signal you. Kurt: Section in 3.8, the sentence says texturing in CI mode is undefined. It should also be undefined if you set a texture and query it. Because texture goes through Pixel Transfer mode, which is clearly tied to the frame buffer mode. Do we need to make this more explicit? Chris: Will make suggestions. Jim Cobb: Other issue. Is there a Spec which will make PostScript version viewable by emacs to use things like grep. Kurt: There are a bunch of TeX commands, and since the Spec is written with TeX, to convert it into something ASCII readable. Paula: Will put it into quarterly releases. Conformance Proposal #1 1 bit stencil buffer test--Decrement operation was wrong. Limit was set to 1 less than maximum, which is 0 for 1 bit, decrement becomes very large value. Vote for fix: 7-0 xfont.c in Direct Color, green returned by licensee is not "fully on" green. This licensee has been using a green that they like. When people fail, give them a second chance. John Dennis: Why is the green mask under X not correct under all circumstances? Jim Miller: That's not allowed in X. Paula: But there is a color map, which they have loaded. John: Why not use green mask pixel values. Problem is using a named color. Paula: Could change color maps so pixel value works. Chris: Trying not to change color map, can break other tests, which currently pass. Jim Miller and John Dennis: check the bit pattern returned. if (TK_WIND_IS_RGB(windType)) { values.foreground = visual->green_mask; } else { values.foreground = 2; /* 2 is Green */ } gc = XCreateGC ... Linas: what if there is nothing in green in some strange system. Kurt: think we already covered that last time. John: X and OpenGL channels have to be same Paula: If you have a visual with 0 bits, it won't pass conformance tests. Kurt: Practically, it doesn't work. Mason: So the retest (in the original proposal) gets killed? Chris: Yes. Vote: modified proposal Passes 7-0. Conformance Proposal #3 values queried and stored in a structure (stateRec). But if someone had a buffer that was really big, such as evaluator coefficients 4x8x8, it would overrun GLfloat[140] arrays. Suggested that 140 arrays be increased to 256. 140 was selected because stipples would have been 128, so 140 was comfortably larger. Vote to increase to 256. Israel: to bullet proof this problem is to determine order of evaluators, to see if maximum is hit. Jim: you can check for brokenness and still overrun it. Couple of nits: 4x8x8 is 256 elements, not 240. Vote for change to 256 is 7-0 Conformance Proposal #4: Passes 7-0 -------- John Dennis: Conformance Tests which are window systems specific should be distributed along with the rest of the conformance tests, along with the same mechanism as the X Window System test. Also ARB has not discussed or controlled. Jim Cobb: Test to PGL and WGL spec. ARB doesn't control those specs. John: ARB should have some control. Practically, comparing X and other window system. Also couldn't get the source code for those tests, or what was the Rev level of those tests. ARB shouldn't control content, but within domain of the ARB to control conformance test. One stop shopping. Israel: I disagree. Not appropriate for ARB, since they don't control the spec itself. John: Should inform ARB. Hock: Microsoft distributes conformance test binaries to many vendors, including non OpenGL licensees, such as Matrox. They have no sample code. To see they implement certain level of DDI without having to be a licensee. John: Why is that an issue? Hock: As far as I can tell, we include every conformance test. We brought up any changes, such as specular exponents in the ARB, so that's why they might be missing from the tests. So we're exactly the same as the ARB John: But what about window system specific conformance tests? Hock: We don't want to distribute them, such as multi-threaded apps. John: I'm not talking about stress tests. I think ARB's branding mechanism is in danger. Linas: There are 2 components here: enough of tk to make conformance tests run and window specific tests. John: Entire body of code necessary to receive OpenGL certification, such as covglx and conform.x script. I would like to see driver script to be under control of the ARB. I didn't see a cov.wgl Hock: There is no cov.wgl. We have covgl, covglu, etc. I don't see how anything related to wgl is controlled by the ARB. John: ARB should control certification process. Israel: I believe that ARB can certify the GL and GLU, but not WGL, since they control the spec. Hock: Under Windows NT, there is only one vendor. Linas: But you have hardware vendors. John: Then we shouldn't have conformance testing for the X Window System. Hock: We don't require the hardware vendor needs WGL functions. Mike: This is also a concern for 3rd party software vendors. Dale: Are you worried about trademarks or standards? John: Different window systems: philosophical and practical. As a vendor with multiple window systems. For example, fonts. Israel: Don't have any way to make Microsoft provide that. Jim: Important to have source code to the conformance tests. Find out what you're passing. TK discussion: 2 changes to tk and aux to make viewperf work. tkGetContext cant return context (window specific) returns a long. tkGetSystem only for X so it returns an X screen. Jim: seems to be providable for other systems Paula: only spec'd for X Hock: we do have a GetContext for our library Paula: only one TK and Aux under ARB control Hock: called tkGetCurrentContext, already needed Jim: all of these things have been coming to the ARB, now we're hearing of things that didn't come forward. Paula: I assume it's all upwards compatible Hock: yeah Israel: I'd also like context to be handled by type in tkGetSystem argument about C, ansi, and KR types ensue. Proposal to add another enum type fo tkGetSystem, it is GL_CONTEXT it is a (void *) for X it is a context. TK_GLX_CONTEXT Jim Cobb: should only be TK_CONTEXT. Other window systems are coming on. Hock: this is for viewperf Proposal add 2 new enums to return tk_X_Screen and tk_context. to tkGetSystem. (to be filled in) 7 of 7. . .passes. Hock: can't use any files named aux.h requests a file called glaux.h Then aux.h just includes glaux.h Linas: just a symbolic link would do. Isreal and John: just changing the name of aux.h and providing backward compatibility. Hock: all sample apps currently us glaux.h Vote 6 of 7, in favor. End Monday. adjourn. Tuesday Chris Frazier, Silicon Graphics not attending Tuesday Neil Trevett, 3Dlabs not attending Tuesday FORTRAN Paula begins discussion. We know that FORTRAN identifiers: 1) can't end with underscores 2) must be unique for first 31 characters (not sure if underscore is 31st character is legal) Other major decision is FGL or GL prefix Israel: must important thing is to find out what the rules. If compiler doesn't follow rules correctly, failure will be exposed everywhere. John D: What's the motivation about using F? Jim Cobb: Name space collisions Paula: Flexibility to change names. Allen Akin things consensus is not to have FGL. Bruce: Want to have fgl for subroutines, but not for constants. John: Has anyone shipped FORTRAN bindings? Paula: We did, but it doesn't work with current release. Will have patch in early 1995. Jim Cobb: want to know if FORTRAN77 or 90 has more than 6 character limit. If we need to shoehorn, then I want to see constants to be different in different languages. aa>>Allen Akin adds these comments via e-mail: aa>> Standard FORTRAN 77 doesn't allow underscores in names, and aa>> names must be significant in their first 6 characters. aa>> However, every F77 implementation in use today allows both long aa>> names and names containing underscores. We should go with the aa>> 32-character limit. aa>> aa>> Fortran 90 allows underscores and long names. Only the first aa>> 32 characters of names are significant. Neither the first aa>> character nor the last may be an underscore. At the moment, aa>> it's not clear whether the last *significant* character may be aa>> an underscore, so we'll be conservative and assume that's not aa>> allowable. aa>> aa>>Currently, the enumerants GL_POST_CONVOLUTION_GREEN_SCALE_EXT, aa>>GL_POST_CONVOLUTION_ALPHA_SCALE_EXT, GL_POST_CONVOLUTION_COLOR_TABLE_SGI, aa>>and GL_PROXY_GL_POST_CONVOLUTION_COLOR_TABLE_SGI have underscores in aa>>position 32, so we'll have to provide alternatives. aa>> aa>>All names in the C binding are distinguishable in their first 32 aa>>characters. Vote: Same constant names as C and FORTRAN, specifically, if 32nd character cannot be an underscore, then have to make sure that 32nd character is not underscore for both C and FORTRAN. Passes 7-0 Action Item: SGI must figure out underscore issue. If it's a problem, add this to extension naming convention Next Paula: because there are no pointers, glGetString() and gluGetString() are limited to 256 characters. We're going to run into that problem. Probably want to provide a utility routine that returns results of GetString() one token at a time. Paula: Any comments? John Dennis: We might be shipping one soon. Mike: Anyone shipping Ada bindings? Paula: March is target date for SGI. Bruce: Also, we have some sample FORTRAN programs for distribution. Extensions Paula: Came up at SGI. GL_BOOLEAN_EXT good for reading values out of arrays--just for the glGet*(). John D: Please clarify Paula: It's a typedef Kurt: This is something Celeste Fowler suggested. Mason: Let's table it for now and contact Celeste. Kurt: All of state of vertex array operations behaves as client side state, similar to glPixelStore. By using glEnable, glDisable to turn on/off client side state, muddied state machine. Therefore display list (with array extension items) values are evaluated at compile, not execution. Need to clarify specification for vertex array extension to make this clear. Who is doing it for some future release: Intergraph, Digital, SGI Texture Objects Kurt: Is there anything else which needs to be shared between contexts (rhetorical)? Feedback received that texture objects should be shared, but we (at SGI) haven't convinced ourselves that this is true. Texture performance can be severely impacted by implementation. I would really like to understand the need to share textures. Dale: We have a customer who implemented it on a multi-threaded machine. Each object in their scene has a name, but can't predict which thread will execute it. All threads render the graphics to the same window. You have to guarantee z-buffer is atomic. If each thread (context) required a separate copy of texture, then the texture memory would be poorly used. What's your concern? Kurt: Primary issue is address space. Dale: Sharing is only between threads. Kurt: Share semantics needs to be permanent--space shared for life of context, until last sharing context is destroyed. One way to make that work, if context is shared, then textures are shared. Otherwise, you need to make another boolean. Other question: is this worth the effort? In the extension which you did, how was it implemented? Dale: Name space was global to the process, but to no other process. Textures are always sharable for all threads. Best performance is load all the texture and don't touch them. By the time the scene is drawn once, the textures are all bound. Kurt: We have tons of textures. We have apps that take a lot of time to start. Dale: The way we do it: If extensions exist, then name space is shared, only within that process. John D: What does texture extension give you beyond just using display lists. Kurt: Technically, the texture routines (without extensions) only modify the source of the texture, not the texture itself. Display lists doesn't keep all possible modifiers, because extensions are added. Second problem: people want to be able to operate on the display list directly. In practice, textures are too heavyweight to do this efficiently. The semantics for texbind isn't saying to send all the textures through convolution and other pixel transfer modes, it asks me for the current texture. Apps want the current texture. Dale: Isn't "RESIDENT_TEXTURE" a global? Thought I saw that in the Disney model. Kurt: There's only one rendering thread in the Disney model. Dale: Passes out Intergraph "TextureShare" extension. Only problem we had was when the texture is created, modified, or deleted, only a single context should be bound to the texture. Any context that had been previously bound to this texture must have been flushed after binding to a different texture. Kurt: When you say flush.... Dale: glFlush() Kurt: Probably not enough. I would say glFinish()--block until rendered. Dale: flushes can happen out of order. Kurt: Yes, absolutely. We don't build machines like that today, but we're on the verge. Dale: Can you guarantee the sequence when in one thread? Kurt: Yes. If you want to do multi-threaded rendering, you need a synchronization command which doesn't exist today. Linas: (discussion about IRIS GL--what is shared) The Intergraph scheme is nice. Kurt: Do you share priorities? Dale: Yes. Kurt: Would anyone be upset at changing the texture. Jim and Linas: Would like to make semantics for sharing the textures similar to sharing the display list. Extending visual properties for Performance John D: High level. Seeing trade off between which visual is selected and how fast performance is. Usually lightest visual is too weak; heaviest visual too slow. One thing we might want to do is have token that says "this visual is fast with regard to this property." For example, double buffering. Some visuals do double buffering with DAC trick, quickly. Some would do the double buffering with slower blt. Paula: Is fast double buffering, is the RGB depth less? John: Yes. In the particular device, we have 3 different color depths. Paula: Temptation is to put out as much information about each visual. Linas: A general purpose way would be to associate each visual with statistics, such as viewperf bits. John: Another way is to create a ranking for performance. Kurt: Each visual had a handful of properties, which self-described upon query. Jim: Careful not to get something too rigid. Going to be hard to control that. Relative ranking is harder for different hardware vendors. John D: No, that doesn't apply. Ranking will be among one set of visuals on one machine. Israel: Nice to be able to do multiple things. Kurt: Easy to make more complicated than anyone would want to use. glXChooseVisual is there to be used. Jim: Lots of people ask for alphas who don't need it. It's an education issue. Before visual chosen, tell it what you are planning to use (antialias, alpha) and have it return the best visual. Paula: generally good to look for heuristic of deepest buffer. Kurt: Isn't every visual either fast or high quality already? What has been proposed is a pair of tokens: is it fast or slow; high quality or slow. I think you only need ONE token: Fast or best. Standard selection algorithm. Jim: It could be sensitive to window size, etc. Kurt: Want to keep it very simple. Israel: What happens when you get 2 or more characteristics which are affected. John: I don't think the scenario you've outlined works within the current glXChooseVisual(). Want something that works without change to client code. Kurt: How can that work? Paula: It would be hidden. John: No, that's not what I'm saying. You should be able to send something which says "give me all fast double buffer visuals." Paula: Need a new glXChooseVisual(). John: What's really on the table here is the granularity. Is this coarse or fine granularity? Rewriting glXChooseVisual() Kurt: Might want to replace glXChooseVisual, keeping it around for compatibility, of course. John D: Disagree with Jim about how to solve the effect of state. Much state affects performance. Willing to punt on trying to solve that problem. Another thing that has killed people's performance is the use of aux and tk. Mason: Mark Kilgard will be talking about GLUT toolkit. Might be better. John: How do we address this problem? Kurt: How do we bound it? John: Identify the existing properties. Is there a performance penalty for use of that feature? Paula: Maybe Kurt's solution will work. Do you ever want "high quality this" and "fast that?" Kurt: What does Microsoft do? Hock: Applications test their environment and determine what's fast during set up. No matter what you create, if it doesn't work for 100% of cases, then the applications won't trust its selection method. So people will check "Is the program using FASTest" visual. Israel: 90% of applications will benefit from a hinting mechanism. But some will still have to do "IS FAST" Jim Cobb: Have to make the "tire kickers" happy. John D: Even major apps aren't using "IS FAST" technique. The "SmartVisual" commission: Kurt, John, Jim, Dale aa>>Allen Akin adds this comment via e-mail: aa>>It might be worthwhile to check out my Visual chooser in aa>>sgigate:pub/opengl/contrib/visinfo.tar.Z . The feature that's most aa>>pertinent to this discussion is its ability to handle separate Visual aa>>sorting and Visual selection criteria. Currently the only sorting aa>>criteria are "max" and "min" values for an attribute, but with a little aa>>help from glXGetConfig it would be trivial to add "fast" and "best". aa>> aa>>The visinfo routines also allow pretty straightforward specification of aa>>a particular Visual in a window-system-independent way, something John aa>>requested at the meeting. aa>> aa>>I think it would be a good thing to add to GLUT, for this and other aa>>reasons (mentioned in the documentation). Mark? < take a break > What extensions are we working on? Kurt: Everything SGI is doing is already publicly available, nothing new since last ARB meeting Mike H (TGS): Would like to support Vertex Array extension. Not immediately. Would like to know what will be in next sample. Paula: Vertex array will be in next sample GL around Xmas. Linas: IBM Extension work in a holding pattern. John D: Implemented vertex array extension. None others currently considered. Jim Cobb: some partners control API, with some we don't. Focus is on core OpenGL. Hock: will have WGL extension for 3D fonts Dale: vertex array extension already. Palette buffer (for changing colors, such as the weather). Subtexture, blend color, and possibly texture sharing. John D: Interested in when vertex array extension will be a product. Paula: will be part of next major software release from SGI. Not in IRIX 5.3. Can't commit to when it will be. Israel: Intel will ship it, if and when it ever ships. Mike H: TGS will release in Q1 for Sun and Apple Microsoft: for first half of 1995 Dale (Intergraph): for first half of 1995 Jeremy (3Dlabs): starting work on vertex array extensions. Thought about creating pointers to vertexes in the vertex array list. Kurt: Please talk to me off-line John: How can 3Dlabs make extensions for a Windows NT platform? Hock: We work with other vendors to support their extensions. Dale: You can put things in with the driver, which calls the hardware, but doesn't have to. Hock: Pass named string to function, and it returns a function pointer. Mike H: Has anyone created a hack version of Vertex Array Extension on top of standard vertex commands? Kurt: No one has, but I could see it being done. OpenGL 1.1 Dale: Vendors are concerned that texture objects, vertex array extensions, and other features are VERY important. We need to go back and fix things which close up the process. Kurt: agree those two (texture object and vertex array) are important Dale: how often do we want to release? Kurt: not sure we have a goal. We want to focus on debugger, fonts, etc. Linas & John: Isn't 1.1 done? Many: That was GLX 1.1. Israel: Does that mean GL 1.1 will force GLX 1.2? Mason: Yes. Dale: How long from ARB meeting (start) to creating spec and source code? Paula: 6 months, I guess. Mason: Seems like end of 1995 is important to you, Dale. Dale: Get hit mostly about texture objects. Vendors want it ASAP. How real is everybody going to following the extension/conformance/man pages, etc. Kurt: Sounds like we should set a date. Paula: Think we need some high level goals. Are goals to fix things? Add new features? Mason: Need to have a new Addison-Wesley book for 1.1. * Opinions on 1.1 Kurt: do it moderately quickly; do a small, necessary subset of things which are busted. Israel: do we plan to have a public review Kurt: don't know. This is the first revision; open to it. Israel: being the only non-vendor, I'm ambivalent, but I would like a public review. Jim: how will that impact the schedule? Israel: A lot of it could be done in parallel. Henri: Megatek is neutral Mike: TGS wants to see this get started. Start pretty soon. Biggest thing we get from customers about portability is will all licensees implement a feature. Want to know a certain feature will be in GL 1.1. It helps ISVs get less fearful to use an extension. Linas: Would like to set a date? Jim Miller: Would like to see Fall release, but that means spec needs to be done by Spring. Easier for us to get funding, because it's part of the standard. John D: No opinion. Jim Cobb: Not sure what the alternatives are. Hock: just shipped 1.0, not eager to have 1.1 right away. Extension mechanism is effective for us. Think we need more time to see how extensions work. Testing is important, as Kurt said earlier. Dale: Agree with what Kurt said. Like to see it in the fall. Vertex array extensions, texture objects, fix books, better toolkit. Jeremy: Sooner, rather than later. Vertex array extensions. Jim: Earlier, well-tested minimalist model. Topic: next ARB meeting Salt Lake City Monday, Feb. 13th (at noon) Residence Inn (option to reserve it yourself or have Jim's secretary) can arrive Saturday, if you want to go early Huntsville, AL for Spring meeting Mt. View, CA for Summer Austin, TX for Fall Topic: "similarity" of contexts Kurt: Would like to "relax" the restriction of similarity of contexts which are shared (bound) to visuals with different properties. Right now, "similar" is written in the spec as "identical." Can we redefine to windows with somewhat different properties? Does anyone have strong feelings about this? What about Windows NT? John D: How do you proposal mechanism to enumerate "similarity?" Kurt: I don't have a proposal, but am open. Paula: You could group them along lines of the X Window System. Kurt: You could group them "everything is similar" or "all RGB" or "all color index," etc. I just want to find out if it has come up for anyone. Mike: Want to be able to switch between single and double buffer. Kurt: Want to avoid adding more mechanism to do sharing (a la display lists). There is a pbuffer extension, which relaxes requirement for similarity for glReadBuffer(). Pixels can come from another drawable. Linas: CopyContext will work for two drawable types. You can copy almost everything. John D: Need to allow each vendor to decide which visuals share contexts. Kurt: Will textures be copyable into a color index context? John D: Since each vendor can decide for themselves how to group them, doesn't it defeat the purpose. Which visuals can you actually share with? Some will be much easier than others. Linas: Why not extend CopyContext to extend almost everything? Kurt: Interesting idea. John D: Think that it would be restricted to within the same screen. Debugger Status Paula: I'm interested about future plans from IBM. Jim: Like to get stuff back from SGI Bruce: Want to clean it up. (Originally written with AIC). DEC, E&S, and Microsoft are interested. Paula: We have released the debugger on IRIX 5.3. Made SGI specific changes for Dynamic shared libraries. Modified GUI for SGI look and feel. Added feature to read back state. You can dump out trace files OR metafiles. Linas: Have you stripped out the rather impenetrable AIC code and discovered the Motif? Paula: We are willing to give back the source code. John D: Is this code portable? Paula says SGI did a lot of work for porting. Paula: No, it was very portable. We made modifications to the UI and for the DSO. Jim: We have many things we'd like to do to clean it up. We provided a generic method. Craig Dunwoody, Silicon Graphics Topic: Metafiles: GLS: Stream Encoding for OpenGL Commands < Dunwoody memo inserted here > This is describing some work-in-progress on OpenGL "metafiles" (aka byte stream encodings of OpenGL commands). In the interest of keeping my presentation as short as possible and making the discussion as interesting as possible, I'd like to take this opportunity to send out some advance notes on what I'll be talking about. If you're interested in this topic and you have some free time before the meeting, please look these over and let me know (before, during, or after the meeting) if you have any questions or comments. ------------------------------------------------------------------------------- Introduction ------------------------------------------------------------------------------- GLS is a facility for encoding and decoding streams of 8-bit bytes that represent sequences of OpenGL commands. The GLS specification has two components: 1. A set of three byte stream encodings for OpenGL and GLS commands (human-readable text, big-endian binary, and little-endian binary). The three encodings are semantically identical, differing only in syntax. GLS byte streams can therefore be converted freely among the three encodings without loss of information. 2. An API that provides commands for encoding and decoding GLS byte streams. This API is not formally an extension of the OpenGL API. Like the GLU API, the GLS API is designed to be implemented in an optional, standalone client-side subroutine library that is separate from the subroutine library that implements the OpenGL API. The GLS encodings and API are platform independent and window system independent. In particular, the GLS encodings are not tied to the encoding used in the GLX extension to the X Window System protocol. GLS is designed to work equally well in Unix/X, Windows, and other environments. It is expected that GLS will prove useful to the OpenGL community in a wide range of applications, including: - OpenGL command streams for resolution-independent storage, interchange, viewing, and printing of pictures - OpenGL command files for persistent storage of textures, display lists, images, etc. - OpenGL trace streams for debuggers, performance analyzers, and simulators - OpenGL test-vector streams for correctness testing of OpenGL implementations - Picture-level benchmarking using OpenGL command files to represent pictures - Transfer of OpenGL commands between application processes via byte stream connections - Client-side display lists that can contain client callbacks Some of these applications will require the definition and implementation of higher-level APIs that are more convenient to use than the GLS API. The GLS API design is an attempt to provide basic encoding and decoding services in such a way that higher-level services can efficiently be built on top. ------------------------------------------------------------------------------- Status ------------------------------------------------------------------------------- SGI is developing a GLS specification document for presentation to the OpenGL ARB as a proposed standard for the OpenGL community. As soon as the first draft of this document is complete, SGI will distribute it to all interested parties for comment. In order to experiment with GLS design decisions, SGI has developed a portable reference implementation of the GLS API, written in ANSI C. SGI has also developed a simple utility program called glscat that makes it easy to convert a GLS byte stream from one encoding to another. ------------------------------------------------------------------------------- GLS Encodings ------------------------------------------------------------------------------- Each of the GLS encodings is capable of representing all OpenGL commands, without exception. This includes "get" commands that return data to the OpenGL client and all other commands that are not allowed in OpenGL display lists. In addition to OpenGL commands, a subset of the commands in the GLS API are "encodable", meaning that they can be represented in GLS streams. These GLS commands make it possible to encode various kinds of non-OpenGL data in GLS streams. The binary encodings represent most commands as 16 bits of opcode, followed by 16 bits of word-count, followed by zero or more 32-bit words of argument data. An alternate encoding is used for opcodes larger than 65535 and commands that require more than 65535 32-bit words to encode. The text encoding looks like C source code, except that array arguments are represented as lists of numbers delimited by braces. Enumerants are represented symbolically. An example of a GLS text stream: --------------------------------------------------------------------------- glsBeginGLS(1, 0); # arguments are major, minor GLS version glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_POINTS); glVertex3fv({1.3, 2.4, 5.6}); glEnd(); glsEndGLS(); --------------------------------------------------------------------------- All GLS streams begin with the encodable GLS command glsBeginGLS() and end with the encodable GLS command glsEndGLS(). The concatenation of two valid GLS streams is always a valid GLS stream, even if the two streams do not have the same GLS encoding. ------------------------------------------------------------------------------- GLS API ------------------------------------------------------------------------------- This section provides a brief overview of the core of the GLS API. --------------------------------------------------------------------------- GLuint glsGenContext(void); void glsDeleteContext(GLuint inContext); void glsContext(GLuint inContext); /* set thread's current GLS context */ --------------------------------------------------------------------------- Like OpenGL, GLS defines a state machine. A GLS context is an instantiation of this state machine. GLS contexts and OpenGL contexts are completely independent. Like GLU state, GLS contexts are stored entirely on the client side of the OpenGL client-server connection. Each GLS context has a nonzero name of type GLuint. Each client thread has a state variable that always contains either zero (the initial value) or the name of the thread's current GLS context. If the value is zero, all GLS commands are no-ops, and GLS commands that return a value will return zero. If the value is nonzero, all GLS commands apply to the issuing thread's current GLS context. At any given instant, a GLS context may be current to at most one thread. --------------------------------------------------------------------------- void glsBeginCapture( const GLubyte *inStreamName, GLSenum inStreamType, GLbitfield inWriteFlags ); void glsEndCapture(void); --------------------------------------------------------------------------- Between a glsBeginCapture() command and the following glsEndCapture() command, the current GLS context is in "capture mode". In capture mode, all OpenGL commands will be captured by GLS instead of being sent directly to OpenGL and executed, and all encodable GLS commands will be captured instead of being sent directly to GLS and executed. The command glsBeginCapture() opens a named stream for writing and then encodes the command glsBeginGLS(). The command glsEndCapture() encodes the command glsEndGLS() and then closes the currently open GLS stream. The name of the opened stream is formed by appending inStreamName to a write-prefix string that is stored in the current GLS context. The command glsWritePrefix() (not described here) can be used to replace the value of the write-prefix string. inStreamType is one of: GLS_CONTEXT /* in-memory stream stored in GLS context */ GLS_BINARY_LSB_FIRST /* binary stream, little-endian */ GLS_BINARY_MSB_FIRST /* binary stream, big-endian */ GLS_TEXT /* text stream */ inWriteFlags is zero or more of: GLS_WRITE_APPEND_BIT /* if stream exists, don't truncate */ If inStreamType is GLS_CONTEXT, the command glsBeginCapture() will open a named in-memory stream that is stored in the current GLS context. Within the constraints of available memory, a GLS context can contain an arbitrary number of named GLS_CONTEXT streams. GLS_CONTEXT streams can be thought of as client-side display lists that complement the server-side display lists provided by core OpenGL. If inStreamType is GLS_BINARY_LSB_FIRST, GLS_BINARY_MSB_FIRST, or GLS_TEXT, and inStreamName is not the empty string (""), the command glsBeginCapture() will use the standard C library command fopen() to open an external stream of type FILE*. If inStreamName is the empty string, the command glsBeginCapture() will use a default write stream of type FILE* that is stored in the current GLS context (initial value: stdout). The command glsStream() (not described here) can be used to replace the value of the default write stream. If inStreamName is the empty string and the GLS client has used the command glsWriteFunc (not described here) to specify a write callback function, that function will be used in place of the standard C library function fwrite() when bytes are to be written to the stream. --------------------------------------------------------------------------- void glsCaptureFlags(GLSopcode inOpcode, GLbitfield inFlags); --------------------------------------------------------------------------- The current GLS context contains two capture-mode control bits for each opcode: GLS_CAPTURE_WRITE_BIT /* write command to open stream */ GLS_CAPTURE_EXECUTE_BIT /* execute command */ The command glsCaptureFlags() allows the GLS client to specify on a per-opcode basis whether a captured OpenGL or encodable GLS command should be written to the open stream and/or executed by OpenGL or GLS. --------------------------------------------------------------------------- GLSenum glsCallStream(const GLubyte *inStreamName); --------------------------------------------------------------------------- This command decodes a named GLS stream (which may be in any GLS encoding) and issues the commands in the stream to OpenGL and GLS, just as if those commands had been issued directly in immediate mode by the calling thread. The command returns the type of the stream. If inStreamName is not the empty string (""), a sequence of potential stream names is formed. The first name is formed by appending inStreamName to the write-prefix string. The remaining names are formed by appending inStreamName to each of the strings in a list of read-prefix strings that is stored in the current GLS context. The command glsReadPrefix() (not described here) can be used to modify the contents of the read-prefix string list. Beginning with the first potential stream name, the command glsCallStream() tries each successive name until either a readable stream is found or all of the names have been tried. For each name, the current GLS context is first searched for a GLS_CONTEXT stream of that name. If none is found, the command fopen() is issued with the name as an argument, in an attempt to open an external stream of type FILE*. If inStreamName is the empty string, the command glsCallStream() first searches the current GLS context for a GLS_CONTEXT stream named "". If none is found, the command glsCallStream() will use a default read stream of type FILE* that is stored in the current GLS context (initial value: stdin). The command glsStream (not described here) can be used to replace the value of the default read stream. If the GLS client has used the command glsReadFunc (not described here) to specify a read callback function, that function will be used in place of the standard C library function fread() when bytes are to be read from the stream. The command glsCallStream() is encodable. When a GLS decoder reads this command from a GLS stream, the decoder recursively interprets the GLS stream named in the command. As a result, GLS streams provide the same embedding capability on the client side that OpenGL display lists provide on the server side. --------------------------------------------------------------------------- void glsCommandFunc(GLSopcode inOpcode, GLScommandFunc inFunc); --------------------------------------------------------------------------- Register the client callback function inFunc for the OpenGL or encodable GLS command designated by inOpcode. When a GLS decoder reads this command from a GLS stream, the decoder will call inFunc instead of issuing the command. Command arguments are passed to inFunc just as they would have been passed to the function that implements the OpenGL or GLS command. The function inFunc is free to perform arbitrary computations, including the issuing of OpenGL and GLS commands. Certain encodable GLS commands (not described here) are provided for the sole purpose of encoding arrays of arbitrary client data as command arguments in a GLS stream. If a GLS client provides a callback function for one or more of these encodable GLS commands, the client can use GLS_CONTEXT in-memory streams to create client-side display lists that contain client callbacks. This functionality is present in IrisGL but not in core OpenGL. --------------------------------------------------------------------------- void glsUnsupportedCommand(void); --------------------------------------------------------------------------- The GLS encodings and API are designed to handle OpenGL extensions. Extension commands are encoded and decoded in the same way as OpenGL 1.0 commands. Extension opcodes for the binary encodings are to be allocated on demand in blocks of 16 from a registry maintained by SGI. To guarantee successful interchange of GLS streams, it is required that any GLS implementation be able to read any GLS stream, even if the GLS stream contains extension commands that are not recognized by the GLS implementation. If a GLS decoder reads from a GLS stream a command that it cannot decode, the decoder issues the encodable GLS command glsUnsupportedCommand(). The command glsCommandFunc() can be used to register a client callback function for the command glsUnsupportedCommand(). ------------------------------------------------------------------------------- Implementation Considerations ------------------------------------------------------------------------------- Platform-specific mechanisms are required to implement the capture of OpenGL commands without compromising immediate-mode OpenGL performance when GLS is not in capture mode. Otherwise, the reference implementation of the GLS API is quite portable. < Dunwoody memo over > John D: What will be provided? Just a specification? Craig: Both a spec and a sample implementation will be provided to licensees. Structuring Conventions. GLS can provide non-OpenGL commands within a stream. glBeginSequence()--begin to reference a sequence of OpenGL commands. Inside sequence(), gls*Header(), gl*Init(), gl*Static(), gl*Frame(). We have a portable ANSI C reference implementation of API. Portability issue is OpenGL command dispatching. Portable for DSO and DOL. Spec document under development. SGI to release code to licensees in March, 95. Hock: Can encoding be played back with different transformation? How? Craig: You will intercept load matrix and insert transformation into pipeline. John Dennis: What about interaction with window systems? Sounds like record and playback. You are capturing this in a neutral fashion. (Any proof) Craig: Yes. But it will differ on different window systems. Nothing in this library that requires using X. Dale: Where does GLU fit? Craig: This will generate OpenGL routines, generated from GLU. < break > New attendee: H. B. Siegel, Silicon Graphics Topic: Tesselator (Paula Womack) < Tesselator memo inserted here > The GLU tesselator is on sgiblab. To retrieve it, ftp to sgiblab.sgi.com as opengl_l and get libtess.tar.Z. I would like to discuss whether we should replace the existing GLU tesselator with this one. This tesselator--written by a summer student, Eric Veach--is more robust and also handles more cases than the existing tesselator (i.e., it handles degenerate and self-intersecting polygons). I included the README below. Note that new GLU routines were introduced to expose the new features in this tesselator. However, the old GLU routines are still supported so the tesselator is upwards compatible. Thanks to Allen Akin for overseeing this project and, of course, thanks to Eric for writing the tesselator. General Polygon Tesselation - --------------------------- This note describes a tesselator for polygons consisting of one or more closed contours. It is backward-compatible with the current OpenGL Utilities tesselator, and is intended to replace it. Here is a summary of the major differences: - input contours can be intersecting, self-intersecting, or degenerate. - supports a choice of several winding rules for determining which parts of the polygon are on the "interior". This makes it possible to do CSG operations on polygons. - boundary extraction: instead of tesselating the polygon, returns a set of closed contours which separate the interior from the exterior. - returns the output as a small number of triangle fans and strips, rather than a list of independent triangles (when possible). - output is available as an explicit mesh (a quad-edge structure), in addition to the normal callback interface. - the algorithm used is extremely robust. How to use it - --------------- See the Makefile for compilation instructions. The include file for applications is "tesselator.h". The interface - ------------- The tesselator state is maintained in a "tesselator object". These are allocated and destroyed using GLUtesselator *gluNewTess( void ); void gluDeleteTess( GLUtesselator *tess ); Several tesselator objects may be used simultaneously. Inputs ------ The input contours are specified with the following routines: void gluTessBeginPolygon( GLUtesselator *tess ); void gluTessBeginContour( GLUtesselator *tess ); void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data ); void gluTessEndContour( GLUtesselator *tess ); void gluTessEndPolygon( GLUtesselator *tess ); Within each BeginPolygon/EndPolygon pair, there can be zero or more calls to BeginContour/EndContour. Within each contour, there are zero or more calls to gluTessVertex(). The vertices specify a closed contour (the last vertex of each contour is automatically linked to the first). "coords" give the coordinates of the vertex in 3-space. For useful results, all vertices should lie in some plane, since the vertices are projected onto a plane before tesselation. "data" is a pointer to a user-defined vertex structure, which typically contains other information such as color, texture coordinates, normal, etc. It is used to refer to the vertex during rendering. The library can be compiled in single- or double-precision; the type GLUcoord represents either "float" or "double" accordingly. The GLU version will be available in double-precision only. Compile with GLU_TESS_API_FLOAT defined to get the single-precision version. When EndPolygon is called, the tesselation algorithm determines which regions are interior to the given contours, according to one of several "winding rules" described below. The interior regions are then tesselated, and the output is provided as callbacks. Rendering Callbacks ------------------- Callbacks are specified by the client using void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)()); If "fn" is NULL, any previously defined callback is discarded. The callbacks used to provide output are: /* which == */ void begin( GLenum type ); /* GLU_TESS_BEGIN */ void edgeFlag( GLboolean flag ); /* GLU_TESS_EDGE_FLAG */ void vertex( void *data ); /* GLU_TESS_VERTEX */ void end( void ); /* GLU_TESS_END */ Any of the callbacks may be left undefined; if so, the corresponding information will not be supplied during rendering. The "begin" callback indicates the start of a primitive; type is one of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the notes on "boundary extraction" below). It is followed by any number of "vertex" callbacks, which supply the vertices in the same order as expected by the corresponding glBegin() call. After the last vertex of a given primitive, there is a callback to "end". If the "edgeFlag" callback is provided, no triangle fans or strips will be used. When edgeFlag is called, if "flag" is GL_TRUE then each vertex which follows begins an edge which lies on the polygon boundary (ie. an edge which separates an interior region from an exterior one). If "flag" is GL_FALSE, each vertex which follows begins an edge which lies in the polygon interior. "edgeFlag" will be called before the first call to "vertex". Other Callbacks --------------- void mesh( GLUmesh *mesh ); /* GLU_TESS_MESH */ - Returns an explicit mesh, represented using the quad-edge structure (Guibas/Stolfi '85). Other implementations of this interface might use a different mesh structure, so this is available only only as an SGI extension. When the mesh is no longer needed, it should be freed using void gluDeleteMesh( GLUmesh *mesh ); There is a brief description of this data structure in the include file "mesh.h". For the full details, see L. Guibas and J. Stolfi, Primitives for the manipulation of general subdivisions and the computation of Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985. For an introduction, see the course notes for CS348a, "Mathematical Foundations of Computer Graphics", available at the Stanford bookstore (and taught during the fall quarter). void error( GLenum errno ); /* GLU_TESS_ERROR */ - errno is one of GLU_TESS_MISSING_BEGIN_POLYGON, GLU_TESS_MISSING_END_POLYGON, GLU_TESS_MISSING_BEGIN_CONTOUR, GLU_TESS_MISSING_END_CONTOUR, GLU_TESS_COORD_TOO_LARGE, GLU_TESS_NEED_COMBINE_CALLBACK The first four are obvious. The interface recovers from these errors by inserting the missing call(s). GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded the predefined constant GLU_TESS_MAX_COORD in absolute value, and that the value has been clamped. (Coordinate values must be small enough so that two can be multiplied together without overflow.) GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an intersection between two edges in the input data, and the "combine" callback (below) was not provided. No output will be generated. void combine( GLUcoord coords[3], void *data[4], /* GLU_TESS_COMBINE */ GLUcoord weight[4], void **outData ); - When the algorithm detects an intersection, or wishes to merge features, it needs to create a new vertex. The vertex is defined as a linear combination of up to 4 existing vertices, referenced by data[0..3]. The coefficients of the linear combination are given by weight[0..3]; these weights always sum to 1.0. All vertex pointers are valid even when some of the weights are zero. "coords" gives the location of the new vertex. The user must allocate another vertex, interpolate parameters using "data" and "weights", and return the new vertex pointer in "outData". This handle is supplied during rendering callbacks. For example, if the polygon lies in an arbitrary plane in 3-space, and we associate a color with each vertex, the combine callback might look like this: void myCombine( GLUcoord coords[3], VERTEX *d[4], GLUcoord w[4], VERTEX **dataOut ) { VERTEX *new = new_vertex(); new->x = coords[0]; new->y = coords[1]; new->z = coords[2]; new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r; new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g; new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b; new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a; *dataOut = new; } If the algorithm detects an intersection, then the "combine" callback must be defined, and must write a non-NULL pointer into "dataOut". Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no output is generated. This is the only error that can occur during tesselation and rendering. Control over Tesselation ------------------------ void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value ); Properties defined: - GLU_TESS_WINDING_RULE. Possible values: GLU_TESS_WINDING_ODD GLU_TESS_WINDING_NONZERO GLU_TESS_WINDING_POSITIVE GLU_TESS_WINDING_NEGATIVE GLU_TESS_WINDING_ABS_GEQ_TWO The input contours parition the plane into regions. A winding rule determines which of these regions are inside the polygon. For a single contour C, the winding number of a point x is simply the signed number of revolutions we make around x as we travel once around C (where CCW is positive). When there are several contours, the individual winding numbers are summed. This procedure associates a signed integer value with each point x in the plane. Note that the winding number is the same for all points in a single region. The winding rule classifies a region as "inside" if its winding number belongs to the chosen category (odd, nonzero, positive, negative, or absolute value of at least two). The current GLU tesselator implements the "odd" rule. The "nonzero" rule is another common way to define the interior. The other three rules are useful for polygon CSG operations (see below). - GLU_TESS_BOUNDARY_ONLY. Values: TRUE (non-zero) or FALSE (zero). If TRUE, returns a set of closed contours which separate the polygon interior and exterior (rather than a tesselation). Exterior contours are oriented CCW with respect to the normal, interior contours are oriented CW. The GLU_TESS_BEGIN callback uses the type GL_LINE_LOOP for each contour. - GLU_TESS_TOLERANCE. Value: a real number between 0.0 and 1.0. This specifies a tolerance for merging features to reduce the size of the output. For example, two vertices which are very close to each other might be replaced by a single vertex. The tolerance is multiplied by the largest coordinate magnitude of any input vertex; this specifies the maximum distance that any feature can move as the result of a single merge operation. If a single feature takes part in several merge operations, the total distance moved could be larger. Feature merging is completely optional; the tolerance is only a hint. The implementation is free to merge in some cases and not in others, or to never merge features at all. The default tolerance is zero. The current implementation merges vertices only if they are exactly coincident, regardless of the current tolerance. A vertex is spliced into an edge only if the implementation is unable to distinguish which side of the edge the vertex lies on. Two edges are merged only when both endpoints are identical. void gluTessNormal( GLUtesselator *tess, GLUcoord x, GLUcoord y, GLUcoord z ) - Lets the user supply the polygon normal, if known. All input data is projected into a plane perpendicular to the normal before tesselation. All output triangles are oriented CCW with respect to the normal (CW orientation can be obtained by reversing the sign of the supplied normal). For example, if you know that all polygons lie in the x-y plane, call "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons. - If the supplied normal is (0,0,0) (the default value), the normal is determined as follows. The direction of the normal, up to its sign, is found by fitting a plane to the vertices, without regard to how the vertices are connected. It is expected that the input data lies approximately in plane; otherwise projection perpendicular to the computed normal may substantially change the geometry. The sign of the normal is chosen so that the sum of the signed areas of all input contours is non-negative (where a CCW contour has positive area). - The supplied normal persists until it is changed by another call to gluTessNormal. Backward compatibility with the GLU tesselator ---------------------------------------------- The preferred interface is the one described above. The following routines are obsolete, and are provided only for backward compatibility: typedef GLUtesselator GLUtriangulatorObj; /* obsolete name */ void gluBeginPolygon( GLUtesselator *tess ); void gluNextContour( GLUtesselator *tess, GLenum type ); void gluEndPolygon( GLUtesselator *tess ); "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or GLU_UNKNOWN. It is ignored by the current GLU tesselator. GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END, GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG. Polygon CSG operations - ---------------------- The features of the tesselator make it easy to find the union, difference, or intersection of several polygons. First, assume that each polygon is defined so that the winding number is 0 for each exterior region, and 1 for each interior region. Under this model, CCW contours define the outer boundary of the polygon, and CW contours define holes. Contours may be nested, but a nested contour must be oriented oppositely from the contour that contains it. If the original polygons do not satisfy this description, they can be converted to this form by first running the tesselator with the GLU_TESS_BOUNDARY_ONLY property turned on. This returns a list of contours satisfying the restriction above. By allocating two tesselator objects, the callbacks from one tesselator can be fed directly to the input of another. Given two or more polygons of the form above, CSG operations can be implemented as follows: Union Draw all the input contours as a single polygon. The winding number of each resulting region is the number of original polygons which cover it. The union can be extracted using the GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules. Note that with the nonzero rule, we would get the same result if all contour orientations were reversed. Intersection (two polygons at a time only) Draw a single polygon using the contours from both input polygons. Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO. (Since this winding rule looks at the absolute value, reversing all contour orientations does not change the result.) Difference Suppose we want to compute A \ (B union C union D). Draw a single polygon consisting of the unmodified contours from A, followed by the contours of B,C,D with the vertex order reversed (this changes the winding number of the interior regions to -1). To extract the result, use the GLU_TESS_WINDING_POSITIVE rule. If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an alternative to reversing the vertex order is to reverse the sign of the supplied normal. For example in the x-y plane, call gluTessNormal( tess, 0.0, 0.0, -1.0 ). Performance - ----------- The tesselator is not intended for immediate-mode rendering; when possible the output should be cached in a user structure or display list. General polygon tesselation is an inherently difficult problem, especially given the goal of extreme robustness. The implementation makes an effort to output a small number of fans and strips; this should improve the rendering performance when the output is used in a display list. Single-contour input polygons are first tested to see whether they can be rendered as a triangle fan with respect to the first vertex (to avoid running the full decomposition algorithm on convex polygons). Non-convex polygons may be rendered by this "fast path" as well, if the algorithm gets lucky in its choice of a starting vertex. For best performance follow these guidelines: - supply the polygon normal, if available, using gluTessNormal(). This represents about 10% of the computation time. For example, if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1). - render many polygons using the same tesselator object, rather than allocating a new tesselator for each one. (In a multi-threaded, multi-processor environment you may get better performance using several tesselators.) Comparison with the GLU tesselator - ---------------------------------- On polygons which make it through the "fast path", the tesselator is 3 to 5 times faster than the GLU tesselator. On polygons which don't make it through the fast path (but which don't have self-intersections or degeneracies), it is about 2 times slower. On polygons with self-intersections or degeneraces, there is nothing to compare against. The new tesselator generates many more fans and strips, reducing the number of vertices that need to be sent to the hardware. Key to the statistics: vert number of input vertices on all contours cntr number of input contours tri number of triangles in all output primitives strip number of triangle strips fan number of triangle fans ind number of independent triangles ms number of milliseconds for tesselation (on a 150MHz R4400 Indy) Convex polygon examples: New: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.0459 ms Old: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.149 ms New: 4 vert, 1 cntr, 2 tri, 0 strip, 1 fan, 0 ind, 0.0459 ms Old: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.161 ms New: 36 vert, 1 cntr, 34 tri, 0 strip, 1 fan, 0 ind, 0.153 ms Old: 36 vert, 1 cntr, 34 tri, 0 strip, 0 fan, 34 ind, 0.621 ms Concave single-contour polygons: New: 5 vert, 1 cntr, 3 tri, 0 strip, 1 fan, 0 ind, 0.052 ms Old: 5 vert, 1 cntr, 3 tri, 0 strip, 0 fan, 3 ind, 0.252 ms New: 19 vert, 1 cntr, 17 tri, 2 strip, 2 fan, 1 ind, 0.911 ms Old: 19 vert, 1 cntr, 17 tri, 0 strip, 0 fan, 17 ind, 0.529 ms New: 151 vert, 1 cntr, 149 tri, 13 strip, 18 fan, 3 ind, 6.82 ms Old: 151 vert, 1 cntr, 149 tri, 0 strip, 3 fan, 143 ind, 2.7 ms New: 574 vert, 1 cntr, 572 tri, 59 strip, 54 fan, 11 ind, 26.6 ms Old: 574 vert, 1 cntr, 572 tri, 0 strip, 31 fan, 499 ind, 12.4 ms Multiple contours, but no intersections: New: 7 vert, 2 cntr, 7 tri, 1 strip, 0 fan, 0 ind, 0.527 ms Old: 7 vert, 2 cntr, 7 tri, 0 strip, 0 fan, 7 ind, 0.274 ms New: 81 vert, 6 cntr, 89 tri, 9 strip, 7 fan, 6 ind, 3.88 ms Old: 81 vert, 6 cntr, 89 tri, 0 strip, 13 fan, 61 ind, 2.2 ms New: 391 vert, 19 cntr, 413 tri, 37 strip, 32 fan, 26 ind, 20.2 ms Old: 391 vert, 19 cntr, 413 tri, 0 strip, 25 fan, 363 ind, 8.68 ms Self-intersecting and degenerate examples: Bowtie: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.483 ms Star: 5 vert, 1 cntr, 5 tri, 0 strip, 0 fan, 5 ind, 0.91 ms Random: 24 vert, 7 cntr, 46 tri, 2 strip, 12 fan, 7 ind, 5.32 ms Font: 333 vert, 2 cntr, 331 tri, 32 strip, 16 fan, 3 ind, 14.1 ms : 167 vert, 35 cntr, 254 tri, 8 strip, 56 fan, 52 ind, 46.3 ms : 78 vert, 1 cntr, 2675 tri, 148 strip, 207 fan, 180 ind, 243 ms : 12480 vert, 2 cntr, 12478 tri, 736 strip,1275 fan, 5 ind, 1010 ms < end Tesselator memo > Paula: written by summer intern at SGI. NextContour() takes on concave polygons, and self intersecting, degenerate, and intersecting contours. May not want to use mesh() callback, but doesn't correspond to any OpenGL data type. May not want it in next release. Hock: works pretty well for degenerate cases. Haven't run into problems. John Dennis: Built it and tried in in trials. Didn't have any test programs, so we wrote some. After verifying it, gave it to PHIGS group, but they haven't reported back on their impression (they're busy). Minor nits: not really backwards compatible with existing one in handling of contours, because it generates errors if you don't say "BeginContour." With the old tesselator (if you ifdef your code), the old library doesn't demand you call "NewContour." That's not backwards compatible. aa>>Allen Akin adds his comments via e-mail: aa>>Eric and I discussed this, and I thought he handled it correctly, but aa>>it's always possible we goofed up. Let us know when you've got a test aa>>case, and we'll put in a fix. Paula: The new semantics don't work that way. Some confusion about whether John's case is using new or old semantics. John Dennis: Action item will be to send test case to Paula. Mike H: Is tesselator code single or double precision? Which version are people going to use? John D: Comment about API is that the vertex interface is clumsy. Demands that you create a temporary set of double data types to call these routines. Kurt: should be like the doubles in NURBS John D: Values being passed back via blind data pointers--are they doubles? Paula: New tesselators have combine callback. Hock: This is same design as original tesselator John D: I also think the original design was poor. It is forcing you to pass VERTEX data through that pointer. You're never passed just the coordinate data. Might want to revisit the original API before we copy previous bad design. Paula: to fix it, you'd need to define a new vertex callback. Hock: It's clumsy, but it works, and I don't see a good workaround. Mason: A vote needs to be made to include this into the GLU specification. Paula: this won't make it to the next sample GL Linas: Is proposal to replace the previous tesselator? Paula: Yes, with backwards compatibility Linas: Need to fix some references to "triangulation" to more generic "tesselation" Goal is to have a vote to accept or reject tesselator as replacement for existing tesselator code in early January. Israel: Request to reduce size of file name from tesselator.h Jim: Please either fold tesselator.h into glu.h or have a gl prefix. Topic: X/Open Mason discusses that Mike Lambert and Robert Noyes of X/Open would like to address the ARB at the next (Salt Lake) meeting to discuss X/Open branding issues. A series of pros and cons are discussed. Mason thinks there are marketing pluses for acceptance of OpenGL as an X/Open standard. There is agreement that some large companies and governments which are reassured by this. There are many concerns voiced, including what happens to the conformance test. Is the ARB bound to the technical suggestions which arise from the X/Open Technical Review of the Spec? Is there loss of control of the OpenGL trademark? Will this slow down the adoption of new releases, such as OpenGL 1.1? Mason asks that such a list of questions be readied for the next meeting. Topic: PC Game subset of OpenGL Mason announces that Silicon Graphics has been approached by a PC software vendor who is interested in creating a PC game subset of OpenGL. This OpenGL subset would be a different product from standard OpenGL, and its API would only be exposed to game vendors. It's price structure would be very different, and it might have a completely different name. Mason brings this up because the ARB may choose to approve the subset or otherwise distance itself, but it should be aware of this effort and may wish to review it. Topic: Benchmark status latest version of viewperf out via ftp. several buckets: Data Explorer, CDRS intent is to make code widely available in public (and data sets) after freeze Jim Cobb: freeze is imminent John D: Need to see more information from OPC, updates, etc. Most of info was level of rumor. John Spitzer of SGI is tasked to get more viewsets. Wednesday 9 AM Mark Kilgard, SGI attending Mike Heck, TGS had to leave H.B. Siegel, SGI not here Paula Two new X extensions which affect OpenGL. One is the Double Buffer extension, which is an offshoot of the Multibuffer extension. It's currently in its public review cycle until February. Most interesting is the idiom. Going to be difficult to incorporate idiom into OpenGL. The other extension is EVE (advertising "extended visual attributes"). Mark K: begin idiom DBEswapBuffers waitForX glClear end idiom it's up to each renderer to figure out how to handle double buffering for that window system At some point, the idiom breaks down. Linas: it allows you to synchronize swap in several windows Paula/Jim Miller: not sure it's synchronized or guaranteed Linas: is it a hint? John D: What's the relationship between this and GLX? Should ARB proceed independently? Mark K: There is language in the OpenGL spec, which says it will work with what is provided with X. Linas: I have customer who uses OpenGL just for double buffering, because X doesn't! Mark: I was hoping they would drop this and leave it undefined Jim Miller: 2 ISV's want to use glXSwapBuffers. Wouldn't use MBX, because no control over which buffer is swapped. But DBE gives them virtual naming (front and back buffer). Mark: For EVE, OpenGL community should take same capabilities. Can advertise transparent pixels, can video be supported in a window. Maybe an extension to glXMakeCurrent(). John D: Is there anything missing from current glX which motivates us to provide DBE? glX doesn't allow us to access the back buffer. Paula: DBE provides double buffering for both OpenGL and X rendering. Mark: DBE is not implemented for direct rendering. The DBE swap is part of the X stream. Jim Cobb: So if you use the DBE swap with OpenGL, you'll have to use the GL/X synchronization. So you won't have to remove the glXSwapBuffers, which will be more efficient. Paula: Yes John D: I think it's important to understand WHY we need to do this. Kurt: If a double buffered window is created this way, other windows can access each of the buffers (window ID). Paula: you can use glX to create the window, but should still be able to use DBE to access it Mark: some people (with software implementations of double buffering) want to be able to turn off double buffering. Not interesting case to me. Jim Miller: we've never used the MBX (our OpenGL works with it today) practically. This DBE seems much easier Mark K: I'd like to see OpenGL come out and endorse the DBE. Might be needed to amend GLX document. Paula: might want to add more language to the GLX document John: Who is going to implement these? Jim: DBE definitely. EVE, probably. Mark: Both DBE and EVE, near-term being in the next year and a half. Paula: I think HP and Sun are high on it. Jim Cobb: I guess we'll do what our partners want us to do. John: think we'll do DBE. And EVE is of interest to us, as well. The code which manages extended visuals is a real mess, at this point. When we clean it up, writing it in support of EVE makes real sense. Paula: EVE is a little less clear cut. We could always fix those things in GLX. If we buy into the notion that we want to advertise these capabilities, that's the motivation for picking up EVE. Mark K: EVE puts it in one place. Linas: That's a server-internals, but customer doesn't see it. Paula: But if you're using multiple extensions, you have one-stop shopping. I'd like to investigate how easy it is to use EVE in an application. Linas: I still don't know why you want to use it. Mark K: Makes it easy to pick the right visual. If there is a "FAST DEPTH BUFFER" extension, EVE makes it easy to find. John D: Would like to have an e-mail discussion with Mark Kilgard, Kurt, and other interested parties. Linas: How bad is the explosion of visuals? Kurt: Haven't gone past a couple of hundred (for the Reality Engine). John D: What's SGI's experience with ChooseVisual on the Reality Engine? Kurt: Reality Engine doesn't export visuals that don't run well, such as software zbuffer. Mark K: Good example is destination alpha where there is no hardware alpha buffer. Worse than depth buffer, because it uses blending. If we didn't preclude you from using destination alpha without hardware, you'd get clobbered. Multisample buffers are another example. Kurt: Intended design is that if machine doesn't support it well, don't supply the visual. John D: My understanding early on (perhaps naively) was to supply the full complement of capabilities. Kurt: The design is to "fake up" a feature, like texture mapping, in all situations, but not necessarily to "fake up" all buffers in all situations. Designed for "here's what hardware I've got." Given that, ChooseVisual is consistent--give the user the best visual that is supported. John: The SGI low-end doesn't support alpha blending. Mark: destination alpha Mason: But the SGI low-end does support software accum, software stencil, and even software depth sometimes. Jim M: You can have software alpha buffer and mask it out unless they REALLY want it. Paula: alpha does slow you down, even if you have hardware for it. Paula: take an action item to come up with some words in GL spec about how DBE works with OpenGL. Linas: EVE is interesting, but we need to look more closely at the GLX spec. Mark K: a reasonable action item is for the OpenGL ARB to recommend to the X consortium a set of visuals which EVE should handle John D: willing to work with Paula to review EVE Paula: willing to work with John to see how code can be written with EVE, and is it easier than using GLX Linas: one note on EVE: would be nice to advertise floating point z buffer. Topic: GLUT (GL utility toolkit) Mark Kilgard Mark Kilgard explains GLUT. For document describing Mark's discussion: ftp://sgigate.sgi.com/pub/opengl/xjournal/GLUT/glut.column1.ps.Z John D: Two things: 1) Thanks. 2) Deeply disappointed that this has been out in public access without any other window system, other than X. Mark K: Don't anticipate any problems. John D: Can we get an NT port done? Mark K: If someone wants to do it. Mason: would like feedback for book. Glut is an aux killer, but everyone agrees that's good. Willing to change book examples for OpenGL Book Release 1.1 John D: What's the visual selection like now? Mark K: Visual selection similar to aux John D: I feel very strongly about visual selection--Paula has written some. tk isn't a good example. People will look inside of tk for visual selection, and if it's bad, they'll still copy it. I would like to see Paula's code inserted (not using glXChooseVisual, where code is hidden), so people can paste it into their code. Paula: will send code with "good visual selection" to Mark Kilgard. Jim Miller: can GLUT get into quarterly release of sample code. Should ARB sanction this? Mason: If ARB doesn't sanction it, then the Addison-Wesley book might not use it. Or we'll have to take the OpenGL ARB off the red book. Mark K: Still want time to evolve it. Might still be early for this. Agree upon using contrib mechanism. Nice internal routines, name space, regular, etc. John D: At 90% percentile of cases, this is enough. Sometimes, you need access to window system specific information. Ability to force a specific visual pixel format is important. Mark K: Wish to keep it completely window system independent. Hock: Concerned about usage of AUX and GLUT. I don't want to support multiple libraries. Mason: I would like to see AUX dead. It's not well written and it's limited on top of that. Hock: We said we would not change the AUX or add functions. Now GLUT adds lots of functions. And there isn't a port to Windows NT. Mark: GLUT was written to be ported to other window systems. Hock: But it's not today. Agreement to adjourn meeting.