WWDC2003 Session 205
Transcript
Kind: captions Language: en afternoon everyone my name is Travis Browne and the graphics imaging evangelist and it's my pleasure to welcome you to vertex programming with OpenGL session 205 and sort of the theme that we have in this year's WC is the aspect of leveraging the GPU and and the graphics imaging overview yesterday we showed a lot of examples of using program ability to do interesting things because an interesting visual effects those are fragment programs but there's also sort of a companion technology or another way to program the GPU called vertex programming which instead of touching fragments and therefore pixels it's actually maybe using the GPU to do very high-speed geometry calculations the two go hand in hand in terms of the ways you can really offload the burden of doing the graphics from the cpu from the cpu and allow the GPU to do what it does best which is work with geometry and then obviously draw that geometry so it's my pleasure to welcome our speaker today mike larson up to this stage so you can take you to the presentation thanks Travis today we're here to talk about vertical grabbing with opengl it's been around for a couple years starting with the ATI RV 200 in that generation so we'll talk about a little bit let's start out we're go through an introduction to vertex programs we're going to talk about vertex programs in the OpenGL pipeline the computation model used by the vertex program the program since X for the our vertex program and go through a number of examples and starting from simple ones using shader builder and some more complicated one using the project builder so starting out why is vertex programs so much Oh get this button faizan you vert fragment program a lot of the inputs that go into a fragment program come out of the vertex program you might have texture coordinates you might have some bearing position coordinate to come through or system generally it will probably end up using vertex programs if you're using fragment program say your application doesn't fit into the standard OpenGL lighting pipeline you've got an existing lighting model that you want to implement in vertex program and you don't want to change that to the OpenGL one you can you can use a very extra much for that say your application is pre-processing a vertex rays or every time you draw an object you're touching the data one way to get rid of that touching the data sea view time is actually moving up the vertex program isolate that that part of your program actually does that and move it up that examples would be surfaces and vertex cleaning in between it's from keyframe animation it's an old old term you know yeah the general cartoonist and the people who do everything in between so it's called tweening so the benefits of a vertex program essentially we can be offloading functionality from the cpu to the GPU you have more flexible per vertex geometric operations higher performance and lower memory usage let's talk about vertex programs in OpenGL pipeline so here's the old fixed model you start out with the OpenGL vertices you have your standard molecule transformation the color materials and the lighting effects and your prospective division and that's been replaced with vertex program essentially your vertex program replaces a lot of same functionality that was quote a fixed functionality a lot of that was actually included in microcode you're just inching allowing you to use that as microcode the FBI machines for years you microphylla for all these transforms so what changes your program if you're using vertex program you're now responsible for doing all the transformations the color materials and lighting the whole whole slew of other issues if you're using the OpenGL color lighting model and if once you if you're using them and you disable them if you you're here's a scenario i'll say you're switching out of vertex program and you're expecting the standard OpenGL lighting model be there you have to disable them or you'll get everything rover runs to the vertex program regardless let's talk about the computation model so what invokes a vertex program well there's a number of standard methods to find the herb spec say that the issuing a GL vertex command which usually kicks off some kind of operation indirectly through OpenGL about vertically draw elements or jaw ll raise commands the current raster position is changed and simply a a vertex program terminates at the end of reaching the end of the program so a computation model is you have independent execution on each vertex there can be and I likely are 24 vertex in each GPU temporary data so from we write a program you kind of feel there's going to be data left over but vertex program you need you run the program you've done and it's all gone so the input output model you have your vertex program you have virtuous data inputs which be your position color textures coordinates and those kinds of values environment parameters OpenGL state let me talk about environment parameters real quick environment parameters are values that you can load up to your vertex program through GL or across all works program or for a single one and OpenGL state information which would see the current lighting model and a number of a matrix matrix is available from open geo the addition you have a number of temporary registers these water available for youth why are your activating the vertex program and then lunch program completes competition for each value to the color the position and everything else you spit out to the vertex data output and once you reach the end at vertex program you sit out everything to your output register you turn and vertex program stops and kicks it off to the thrust of the engine so what's available to vertex program you know standard attributes position color texture coordinates and additional programmable attributes that you set OpenGL transform and lighting state so the parameter information is read only by the program its defining the spec essentially constant values from the from the arm from Center this program from outside you can you can program them up using environment commands from OpenGL there's two types there's global parameters which say you have multiple vertex programs you can load up across these environment parameters across all vertex program or you have local parameter which is only affect the current vertex program running so the instruction set is limited to about 27 instructions they're focused on transformer lighting number this is kind of like a micro code implementation exposed out so they're very limited there's no loops no branches you have limited program length some instructions are macros which means up you know you have instructions they're complicated that might do mobile things in one operation they might actually be two instructions within or two or three instructions and they are defined by the spec well not all pro instructions can be will require two of two instructions or more so oops Lynette this data operon the scalar operand which are you know standard floating points values and cindy operations which are also zach type values for 40 point values indexed by X Y Z and W we are this is a color texture what they're always index closed the same the same thing all data and all operations is a representative that cindy float for so regardless of what you you know you think you're loading up a single value it's always representatives for value so data component selection you have a normal skin the operation like an altar that construction you know a equals B something you got some input parameter goes to some operation it gets flushed out the bottom and they all get set you have a Swizzle simdi selection which allows you to move data between components so it's on the input select it's not on the output select so if you have a to source component you might have a source a might be XYZ and source be might be vzz you can select them all same one you have a scalar mass operation which is these are the scalar operations you can select which source operation or source component you want for the operation so if you're doing like a reciprocal divide and you want to see the reciprocal of why you essentially select why the instruction set has a number of standard scalar and cindy instructions if i could see an altivec you have your standard add subtract multiply and add multiply and adds a very important struction it's not a macro it's a one struck one instruction you can do a lot with mobile ads and you'll see in the example I'll show you you have absolute value minimum and maximum dot product disinfector the real lighting you can see the lighting in here and reciprocal functions math functions you are pretty limited you have you know the exponent base to floor fraction and log base two and then more complex complex instructions you have component selection lighting conditional set on compare does amount like you think anyways but it's well show you how it works and indirect registers load from parameter space so you can't you can't modify your temporary registers you can't index them through address in director at addressing only parameters can be indirect values so let's look at the constraints these are the base requirements for all vertex program implementation so if you write a vertex program the base implementation will have this many values it has 96 program environments 96 local values 8 program matrices one address register 120 instructions and 12 temporary registers now spec allows for anything more than that but you these are the beige requirements that you can you can you can look look to have an all-in implementation so how do you find out what your new piece of hardware has you are 300 or whatever you put in there um used essentially GL program are an integer value and queries the interface and what's there there's a whole bunch of a pneum that you can ask for and see what see what's out there let's talk about this in text all programs must start with the version signature of our vertex program one point 0 must terminate with an end statement and just about anything in between is ok it has loose you know their temper temporary and parameter variable definitions you don't define all your attempts at top you can define them in line just as long you know before you is just like C++ so what is the syntax it's it's effectively a GPU independent assembly language it's not targeting any specific GPU it's independent of all types it's not see and it's not pure assembly there's no fixed register allocation you don't it's independent like I said its GPU independent it's they're loaded as strings there's run time to pile up by by the driver ati and video whoever and there's no fixed allocation of GPU register so three kinds of parameters you have the concert parameters which are not programmable from your program you have the environment program the parameters which are programmable across all vertex program and you have local parameters which are specific to the currently bound vertex program you have temporary registers could you to start off with the temps and you can aim off up to 12 you'd be surprised how few you actually have to use key thing about using temporary registers is you get a mindset from altivec or whatever you're used to programming on of you know creating a whole bunch of data and then having a result in store them away the key thing about using the temporary registers for vertex program is computed results and stick it in the result as fast you can and reuse that temporary register then a number of urinary binary and ternary instructions you know reciprocals may have and adds and multiplies those things so just to look at the instruction set real quick this just comes out of the arms back you see the instruction on that you have a defined a set of inputs everything just pretty much everything takes a vector input might have two sources the output that's the important part by looking at the spec is you might have it might be a scalar function or it might be a vector op a cindy operation you can see the flavor of the instructions and the syntax that's used and more additional instructions you can look at the sum of math functions of power to reciprocal the reciprocal square root all all those instructions are scalar outputs so you have to select a particular if you want to square root of some value like a square root of the Y value it's going to be spread across all the outputs and it's an absolute show them this an example so we're to get more information on our vertex program well the shader builder in the development tool just comes for free and it's a great place to start it has active syntax checking you're not going to you have to build a framework and build a program to make it work and just turn it on start the island way and please work let's talk about loading program and controlling the execution environment for vertex programs so vertex programs are loaded its strength like I said that runtime compiled by these by the driver essentially there's only one way to do it today they left they've left ways to do it different ways in future but strings are the only today it has active syntax checking so after you try a load of vertex program you can test to get the GL get error and if you call a GL get string with its new it'll actually come back the string reporting the actual position in the code where the air was found which is very useful so you'll find out so loading like I said there's parameters you have environment parameters there's a specific call from loading environment parameters its program a and B parameter and they're all loaded Cindy values there's no way to load a scalar value everything gets loaded Cindy also there's an equivalent call for local parameters you know GL local parameters and they also get loaded Cindy let's go through a basic vertex program what's going to do it's a effective leader shader builder example maybe a little bit simplified we're going to do a model you perspective transform of an input vertex and set the result and moving on you so we are here we have shader builder and bring it up a little bit let's look around here a little bit you have essentially your your code input here this is actually loaded as a vertex program it's like it's the you have to load it before any begin end statement by the way you can't you can't change it while you're doing it to get even well you know draw rays and draw elements have implied begin in but effectively before begins statement you better be doing you have you have to have it slowed as a program ok so let's go through this again you have your editor in interface right here you can enable disable the vertex program you have a number of objects available to draw your you think your test your vertex program out on you have the sphere t pas de he'd run plane I think I think is actually called cool everybody drives cheaper and you have a your dl per hour and you can dial up color you can change the color on the fly go to crayons that's right here we go you can also select a number of texture units available for input you can load them up and select them through this this interface but today we're just going to use protection unit 0 and you can enable or disable it turns things on so and then over here you have a bunch of debugging information I'm not going to go through it you know it's essentially allows you to step through a vertex program and watch the values change in addition shader builder has an instruction reference that comes up over here so you're not digging around the r-spec 64 pages long and it's but it's really detailed you want to read it it really gets there you know okay but you can actually have online documentation of all the instructions and what they're supposed to do so let's go back turn it off so start the program out our vertex program one point oh I have an offset a scale and a zero value it's the constant throw it in here I have even once you program enough you start throwing in your standard you know cut paste and I have a whole bunch of standard values I use all the time you know here's a temporary value the vertex position let's show you example of the runtime compile sorry inliner chick so I see ship comes up with an error saying there's something wrong here and if you look at the bottom it says line 9 actually if you did the deal error check and actually pulled that string out like I show them a previous example able to turn this same value so as you work into project builder example and you start to label yourself just about all your vertex programs will pull that string out just to help you out so let's start up right here i'm just adding a here's the vertex position right here that's an input value that comes from the program here's a here's a temporary called beep beep box and a zero value so i can inline axe it can actually add an offset and they actually automatically adds of the program i can change that offset real time these are great tools by the way you know what one thing i do a lot is i actually get a program up and running here cut and paste it stick it in a file and add to my project builder and then once I if I develop errors in the program I always come back and paste it in here see where the air is a and right here so I'm taking the vertex position the ring from the from the input assigning to a temporary but by doing an ad of an offset and then I'm multiplying by some scale value and you can comment all this stuff out just like that it's pretty easy so moving on then we do the transform of the value we can messing around with we set the result color now you can set these two anything you want to I want to spent too much higher but you know that doesn't work alright and then also set the text coordinate so that's an example of a basic vertex program within shader builder it's pretty simple it's probably 10 instructions five inches long so let's go back so we're going to go through an extra ring go through a lighting vertex program that's another major youth for verdicts program for like I said if you don't have standard GL lighting model if you want to use what we're going to do is we're going to use shader builder essentially the same example Kim's later development example area we're going to model view the transferring of a video booth verdict perform some lighting computations and then move on to the demo a little more complex ok so I want to remove some function out here before I moved on too much I'll leave that up with Naomi so you can look at this in stages thing being applied in stages at rib you know effectively it's a pound of flying I mean it really is so if you want to use nice names for standards input values you can call them at ribs you have now I have two parameters here and if you notice in this parameter right here I'm sharing a whole bunch of values rather than creating multiple parameter variables I'm jamming a four scalar value three scalar values into one simdi value you'll save parameter space and it will end here's your life position so what we go through here we do our model view perspective transform now we start computing the lighting value-based like position then we start issuing a light instruction and then we add that to the to the current value so this is standard shading stuff and then here we had a little funk shading to it so we could see the nice thing about this tools you can do things right in line and test them as you go as you develop say you would develop a bug through here you can comment it out real time and actually see what part of the program is actually messing up and then we go through and remove this is the result of the outputs position and the color so those two simple examples of how to use vertex program and the shader builder we're not going to talk about shooter well too much we move on some new new ideas so as far as sheeter building goes it's a great place to start it's great tool you load up textures you don't have to build a framework you can get started today it also provides active syntax checking for you know of your vertex program as they develop in addition as you start out it has online instruction information so far as program possibilities you know a lot of people you know you look at the instruction set it's it's rather small of lighting focused the code space is pretty small we're all used to having much code as you want to and the number of temperature temporary registers is actually pretty small but you'd be surprised what you can actually do is that you can do surfaces you can do active displacements you can do real-time displacements you can do advanced lighting effects keyframe animation and visual computations so let's go some real quick tips from an application standpoint best way to use vertex program is using vertex raise combined with vertex array ranges key thing about this is you're moving all the CPU from the issuing and fetching of all the vertex raise so you're keeping the CPU out of the equation use a compound selection to save parameter space so rather having you know like mobile parameters defined like one to the runtime supplier is not gonna be able figure this out stick them together in addition use a compound parameter save yourself reciprocal multiply save it by actually pre computing these fixed values and combining in one array so here I have factorial 67 twenty- 720 the inverse of that and the negative of that additional programming tip these are things I've had to figure out at once only one value for some instructions can be selected and at some point you might want to merge all those values back into the same vector of our same 50 value and start computing again rather than generating a single scalar value and then doing a whole bunch of work on generating another sim scalar value doing how much to work on it you might want to merge all back together and just compute them like you would using alt of X so you can use the Select parameter and I multiply add instruction to merge everything back together this shows how you're using your doing a reciprocal on 33 values and then you're starting to merge them back together by two and multiply add back into one value this actually is quite helpful conditional selection there is no you know branches so how do you do conditional selection well the only way really do it is through multiplies so you have a you have a value say you want to do if a greater than equal to B been assigned sequels a or some of that you have to do you know set greater than equal which actually set it doesn't actually what does it sets the if it's if it's true it sets the output to one so you're going to use that one value to multiply against the input value and it's so it's either going to be one or zero and a mad instruction in between that merges the two together as like it's like a conditional would so I've got down to four instructions and there's no branches so let's talk about vertex programs for surfaces so a lot of the lighting functionality for vertex program is actually moved down the fragment program you can get perfect cyl lighting so what else can you do with this this is a pretty powerful little tool here you have here so rather than tweaking with your where two verses every time you want to move from a position or you want to find a new shape to see the UV mesh essentially to two-dimensional mesh that you create once and you never touch it again so the vertex programs can compute the XYZ position of all the values you can be surprised that you can do with it you can do quadratic surfaces implicit surfaces parametric surfaces you can do bilinear interpolation busier b-splines and nerves all critics program so what's a what's UV mesh well you be matched the 2d mesh it's bounded by u and v u and v could be bond between any kind of fixed value parametric surface such as 80 surfaces and nerves b-splines we've gone between zero and one implicitly for the whole surface so you know why would you want to use a vertex program for surface well you'll have to define one mesh one match for all all your objects and by using that you never have to touch your virtus again you can load them up from DRAM and you'll never see them again you can animate surfaces using control parameters will show an example that and you're offloading the work from the cpu the GPU let's uh let's talk about the implicit surface vertex program cool math singing stick it off the web page you know that's three sine values I get a USB for x and y sine of U and V for x and y and then for control parameters combined with you and be so it's the final Z value so we're going to build a birthday will the UV mesh with a vertex array we're going to bound it between negative PI and PI and have some number of steps in between so and then we're going to fill in the position with the UV mesh U and V i sees the Z 0 is actually right here the U and V are just input parameters vertex program so we're going to create our program debug it through shader builder and load it as a program string then we r load the shape control parameters the ABC and D you seen in previous equation as local parameters and then we're a submit a number of quad strips and as a for drawing so here's our object in line format d this is actually a one two dimensional UV mesh being input and it's very it's finally capsulated and if all the positions are being computed by the vertex program right here our control parameter we can dial in anything we want change the shape tear it apart so these are the ABS and sees everybody sees this wants to go out and do not and stuff like that good luck but you do a lot of cool stuff so let's do a little demo here right now for computing shape on applied it similar once in the vram not come across a GP at all vector coordinates are being submitted by the vertex program built on the tapes beach deterred by the equalizer value I'm touching them with an OpenGL context right here I'm pulling the input from a good time and here's the volume [Music] that example it's fun so what you see there you've seen a vertex program that competed the object shape and color and the texture coordinates the control value is a B and C D were fed up as control Prem so one cindy value per frame was loaded up and it computed everything else based on that one value there's no sign function so how do I can choose that I use a McLaren power series you could do you can do a lookup but it just about as much work as doing McLaren because you're going to do in direct address register loads and all that stuff so and then once I had the values computed i computed all three signed values the same time using an alternate similar code so let's take a little program about a small up here you guys see that dim the lights name so there's an input parameter ABCD for temporary values not a whole lot so the surface was described by you know to fix UV values for X&Y and then the control parameter for the shape are in the Z so i had to compute those on the vertex program rather than stuffing the vertex array every time new values so that's about two constructions there it's that's example the syntax it's very assembly like then I'm cranking on and I'm starting to compute the sign values through a number of terms so if you notice I'm doing a multiply and a mad instruction and I'm continually moving on then we do a few more term we set the output position so once i have the output position I jam it away because I'm gonna use that temporary value again and then i set the texture coordinates to some input value which is actually get time I jammed it in the EQ 0 1 2 3 x value and then I add it to the vertex coordinate and it's that guy's been normalized between 0 and 1 and that's it so where do you go from there try doing waves waves are actually pretty simple very similar use cosine functions you can have essentially multiple meters you think about things bobbing up in water in the water you have three four bobbing the water and for each point on the on your water you just simply compute how far you are away from that the cosine emitter and computer your Z value on that and then some across all the emitter xin the whole thing there's a demo tomorrow that shows this is pretty cool so let's go through NURBS actually I had violating your surfaces b-splines and everything else figured out nervous took awhile to figure out how to do them so why is this why is the vertex program for NURBS most people who use Newton herbs in OpenGL have already figured out that nerves is slow you have to do multiply accumulate across the number of control points and they've either rolled their own nerves evaluators you can store multiple patches as a single vertex array and just load up control points for each patch you can do automatic level of detail based on how close the patches to the user or the screen by selecting multiple different you viver meshes so what's nerve actually the Maya come to the airport my book dropped out and a guy comes up and goes what's an herb and I got to about non-uniform rational his eyes glazed over you walk away so well people said nobody really understands there's actually that's what remains would so its surface defined by interpolating a number of control points it's used a lot in cat dominant in cat for because it can do spherical and a number of things you can't do with Bezier surfaces if you want more information on nerves i'm not going to explain how they work here go search for introduction to nerves in the web or rogers has a pretty good book on it and is very simple to read so we're doing outline of how to draw an herb using a vertex program we're going to compute the b-spline basis functions for that particular nerve on the host it's recursive evaluator that's the biggest problem I had with figuring out how to do it on the vertex shaders is it's recursive function there's no branches there's no calls or no jobs so how to compute it on the host that's actually pretty good thing because you only compete at once and you never do it again so the low in your load the control points as local program parameters and then you can do the same thing for your position your normal your texture coordinates they just get loaded as control parameters they don't get loaded with a new new mesh since you just control point parameters so you're you're only loading 16 points for each parameter that you want to load in this example so this example is a four by four controlled mesh position information is interpolated vertex program real simple example on the implementation side say a 4 4 by 4 control mesh if you don't know anything about nerve that means are going to have 16 control points 16 basis functions / UV value and that's that's a lot of storage so what I do is I actually post multiply the basis functions in terms of rows and call them on the vertex program as I go along and that's essentially reduces the the the requirements down to a float if you just look a little you know formula right here you see you know the UV point is the sum of your number of control points which is 16 then you have to set the basis functions one for the rose and one for the column this is a demo so we our surface I put a texture on it just to show you know there's a UV that I use come here in the left hand there it's actually quite a few number points 10,000 points 100-500 grid there's the there's a number of the control points right here you can grab the control points you'd move the surface real time it's all been computed on the vertex program then loaded as a meshed UV mash and vram it never gets never goes across the AGP bust more than one and you can do a lot of fun things with it nerve is actually very flexible surface there we go so that's cool so let's talk about what we've seen Nash 100 110 thousand point if you do the math just for the position only that's 96,150 thousand flops the hostess didn't have to do a full screen application on it at 1280 x 1 k75 frames per second not blah de blah blah it's about a gigaflops just the position only so if you want to add textures and normals of that you can add on entry three giggles Bob and the GPUs can do it let's talk about the program real quick hopefully you're not straining your eyes I have to to input a you basis and a V basis there's for floating-point Cindy values their bring them in through the vertex position and the color and have a number of control points as program locals and then show mall there's number of 16 so here I am I'm pre computing a post you know post multiplying the basis functions to come up with the the required basis functions I need for each row column combination so i multiply post multiply and then I start my multiply accumulate on all the control points as I go along for each point for this example there's four it's a four by four so it's four rows so there's four sets of these things I go along continually computing the new basis functions and I finally end up with a final position do a transform I have a result position and then I start then I just move the texture coordinate long if the texture was normalized between zero one flips it across the whole surface so where do you go from here pretty cool stuff well you can add you can import the position and normal and the color information texture information from a modeler program directly into this you can design vertex programs for different sized meshes you know three by five you know anything anything that value if you look at the number of instructions that take let you figure out work you know that you're bound to a certain size you can't interpolate you know 10 by 10 control matches there's just not enough space in the vertex program to do that and then you can actually do I haven't 30 have I know you can do it subdivision surfaces subrogation services people have always said that they're algorithmic they're always like a similar to be slime but if he looks at there's an exact solution for subdivision surfaces in siggraph 98 in the back end of it so we actually sat down figured it out so that was on the biggest problem of implementing subdivision surfaces you know if you want to do very simple demo violating resurfaces are easy Bezier surfaces you compute the basis functions on it on vertex program and neuro feel it more complicated like instead of users recursions of his ears are simple so let's do a wrap-up so vertex program there a powerful tool for shading and lighting you can use custom lighting models outside the OpenGL lighting model you can add additional complexity to your geometries and vertex program and also you can actually load a lot finer level detail I mean if you look at some of the games out there today the level detail is terrific you know you can use UV meshes to define most surfaces and once the UV mesh is defined you can load in vram and i'll never go across the AGP bus again you said you can lower the cpu load for for most applications and you're seeing up to a hundred times faster performance than having the host compute those kinds of values so where do you start start with a shader builder start with simple transforms you know play with the scale play with the position move those things around change of color gives get a feeling for how the language works move on to lighting model actually skip the lighting model don't expect services but as I am and then move on to simple UV meshes try an implicit surface models come with your crazy cool naphthenes and then start exploring b-splines and nerve everything else so more information on the ARB vertex program you can read the spec it's 60 pages long and very detailed lots of information in there and it gives you a kind of a guideline of what things are supposed to do or you can go to use shader builder I'm going to try and have these these posted in the next couple weeks hopefully yeah yeah and then or for the old Mac OpenGL mailing list thank you Michael now I swear what I want to do is just do a quick you know twirl for the road map here we have plans for the remaining sessions talking about open jail and also the graphics technology and Mac OS 10 I think we're actually on Wednesday obviously so what we have remaining for you tomorrow in the OpenGL track is essentially fragment programming with open jail this is the sort of more pixel specific companion to the programmability it's also gonna be a really cool session lots of interesting demos so if you're interested in programmability unlocking the power of the GPU should also attend that session we also have obviously we're talk tomorrow about our course 2d technology which is also relevant for OpenGL developers because one of the things we announced in our graphics imaging overview session yesterday is the ability to use 2d drawing API to draw directly into an OpenGL context that can also be very exciting for OpenGL developers because they can make things like doing high-quality text and open jail very very easy then we have a great session that if you're doing any OpenGL development you have to send session 209 which is the OpenGL optimizations one thing that I realize been working with a lot of developers are using OpenGL is in many cases they're leaving performance on the floor on the platform and it's a mini case you have a great tool set and this session will provide a lot of information for you to learn how to take a look at your applications and figure out how to unlock the true performance potential of both the GPUs and also the Macintosh is a platform and Mac OS 10 and then another thing that might be interesting is session to 11 which is gonna be on Friday which is introduction to court services now this is a non drawing API in courts but one of the things it does it's very important as it manages the display so a lot of OpenGL developers have need to find out what the configuration of this play is what display modes available on the particular display are and this is the core api's that we really want developers to adopt and use in their applications to do things which is screen capture and display reconfiguration so you should attend that and then also we have our hardware partners ati are here this year and then session to 12 which is also on friday they're going to sort of push the envelope and show what you can do with their latest generation of GPU hardware and also programmable features because their demo team is going to essentially show what they do to create their incredibly captivating demonstrations that they they do to support their announcements of their hardware so it's going to be really cool session and it's leverage going to leverage a lot of what you've learned today and tomorrow and fragment programming with from a program session and vertex programming and then obviously we have a feedback forum on Friday our traditional spot the last feedback forum but we urge you to come back come to the feedback forum and let us know what sort of things you want to see in Mac OS 10 from a technology perspective because a lot of feedback we get at WC is what we take back and start working from figure out what goes in the next major release of Mac OS done so I think we have a QA all right way of contact information you can if you have questions about what you've learned you can contact mike larson who is the presenter today and have those questions are Jeff stalls very active with developers directly and you can also use him as a contact reference point I'd also like to add my name to this list if you had questions about the session or any of the graphics technology is on Mac OS 10 you can feel free to contact me Travis Browne at Travis at apple com so we have some additional information these are essentially the where the art vertex program expect can be found and I'll leave this up here for a little bit and what I'm actually going to do is why I go ahead and bite the Q&A team up the OpenGL engineering team up to the stage and we'll actually engage in a question and answer and I'll leave this up here so if you want to copy information down off this you'll have plenty of time okay so we have some microphones in the center right here if you have any questions about what you've seen today please feel free to go to microphone you know basically announced your name and your company and will filled your question you