WWDC2000 Session 187

Transcript

Kind: captions Language: en like to introduce Dave Springer a Senior Open GL graphics engineer at apple he's done a tremendous amount of work with OS 10 with NSEL and he's going to talk specifically about OpenGL on Mac OS 10 and then the nuances of working there and talk about some of the new architectures and give you a lot of good code to work through even actually I work through some codes with you to show exactly how you can do it with the OS 10 so Dave Springer hi I'm Dave will talk about OpenGL on OS 10 just had a big long talk about it on OS 9 there's three main pillars of OpenGL and I was ten when we wrote it we kept all these three things in mind all the time first thing is that we want it to be fully integrated with OS 10 we'll talk about what that means not you know a bag on the side it's like you get OS 10 and then somehow you get to do 3d this is fully integrated we wanted to preserve the full OpenGL programming model so that time if you're already an OpenGL programmer and you know how to do it you still know how to do it nothing changed plus it's got to be fast so we made a lot of architectural decisions inside of OpenGL on OS 10 we'll talk about what some of those are so that you get a lot of speed and you know that OS 10 is very different from OS 9 it's multitasking it's multi-threaded it's multiprocessor it's multi a lot of things and that means that the operating system is always in your way slowing you down so we had to think about that a lot to make OpenGL really shaft we'll talk a bit about what kind of api's we have and I'll touch on how we well not how we did it but what do you get an implementation no this is a picture of OS 10 shows the level of integration that we have achieved with OpenGL it really is a full part of OS 10 is it's like I said it's not some afterthought saying that we glued on it's built right into it under there under in application services so when you're writing your stuff in classic or carbon or cocoa it's really a part of the OSS of substrate that's in there for you right ok OS 10 gives us a lot of stuff we have multi-headed graphics multi-threaded multiprocessor these are all things that come with the OS 10 operating system kernel and that means that OS 10 has to do a lot of work it takes up a lot of cycles of the CPU to do all this stuff so that really works properly we had to integrate in with all of that so that you can preserve a lot of your performance that you used to get an OS 9 which was none of those things OS 9 you could own the whole machine if you wanted to and just kind of elbow everything out of the way run your game and you're on the iron well that's not really true in OS 10 we've made it just as close to that as possible I'm still preserved full OS 10 so you're still fully multi-threaded you're still fully multitasking all those little needle little UNIX demons are still running in the background but you get your performance anyways we've worked inside the OS 10 hardware acceleration layers inside the drivers so that we are really on the iron we have the ati rage 128 fully supported other stuff is coming soon as it's really awesome and i can't tell you what it is we support coco api's which Jeff showed you that was NS OpenGL view and things like that we have full carbon support so if you've written something in OS 9 you can carbonate it and bring it over to OS 10 it will still work and we have glut as well it's 3.7 we preserved the full OpenGL programming model it's kind of implicit within the API we changed nothing so it's still the same opengl state machine you still make polygons with vertices you transform and lights and you stick textures to them you render stuff it's exactly the same so all your OpenGL code that you wrote those big beautiful applications you've labored over for so long can just come right over what's a little bit of work you can we added also this is a feature that's an OS 9 as well and we pulled it over to OS 10 which is that you can not use the console I say the current context you don't have to set it all the time this gives you about a five percent of performance game which doesn't sound like a lot but when you're going from 60 to 70 frames per second it makes a huge difference so we preserved all that stuff those of you who wrote high performance stuff in OS 9 you can do the same thing in OS 10 the same model OpenGL is fully integrated with cocoa and carbon both so that you can write your applications native OS 10 and cocoa or you can bring carbon stuff over from OS 9 or you can write carbon ABS native OS 10 too so if you have a bunch of legacy code that you want to rewrite or port up to OS 10 you can do that as well the optimization in OS 10 are centered around this this pre-emptive model that we have it really has to do with texture paging and how we access the driver I don't want to get into a great deal of detail here partly because I don't know it and also partly because we can leave that to QA later for those of you who really want to get into how that technology really works it is fully supported inside the rage 128 driver and it gives you really fast texturing we have an excellent paging model that will get your textures in and out of the card on your it doesn't kind of on your behalf so you don't have to have fancy texture paging algorithms and know how to do a vm system just to make things texture maps we do it for you it also works so that when your application is running on 10 it acts like it owns the whole machine which is the same as nine but on 10 you actually can't own the whole machine the colonel own good you never can but we made it so that it seems like you do so if you have two applications running and they're both using opengl they don't beat against each other but they both perform really well you're going to see some degradation of course because you have two apps so you know they go slow or does but you can get it so it seems like you have the whole machine you don't have to do special programming for that kind of stuff the API is that we currently support this is NDP for right now so the CDs you either got or are going to get have these extensions in them and I'm not going to go into a huge amount of detail and what each of these do there they're documented pretty well this is the OpenGL 1.1 API that is on your CD right now so you can program this as soon as you get it what's coming post DP for so the next user seed or few seeds after it'll be full OpenGL one point to point to and we'll have these other extensions as well I know Jeff went over some too and again I think in a Q&A session we can we can address these in great detail if you need to know all right the when you're programming OS 10 if you've come over from OS 9 you have to think about a few things we don't have any color index mode on OS 10 so you can't do those cheats you know the when you should be using compositing and you're not you can't do those anymore you really have to use compositing now you can't go into color index mode and use mask off planes and things like that's not going to work and this in no 8-bit kind of look at mode either on OS 10 so you really have to you know pull up your socks do compositing there's no real truth single buffer window mode there's there's some technical reasons for that in the windows server and its really all really is double buffered although in the API you can ask for a single buffer you just don't get it multiple contexts can share drumble that's the same as nine so you can have a bunch of OpenGL context all drawing into the same bit if you want and we will have true full screen support not indeed before didn't make it sorry it's coming soon but that means that you can own the whole screen blow away the desktop do cool games that are full screen so we'll have that it'll be really super fast just some notes on implementation OS 10 classic is not indeed before so if you have an appt an OS 9 app that you wrote and you didn't bother to carbonator you're just hoping that classic will will handle it it's not going to work and be before we do have full carbon support full cocoa support and I'll show you the level of integration we have a cocoa later with an example we support glut 3.7 so we ported that over and that is a real OS 10 framework it's not a carbonated version of the 1040 s10 it sits underneath it cocoa and accesses methods inside coconut to run so it's a full native OS 10 but I want to add to jeff's note there's we don't really encourage using glut4 shipping applications it's an excellent way to get started if you're not really hip to how to make windows and do mouse advanced oh no it's and stuff like that glut is a fairly easy way to get started it's got a pretty low admission price and you can make windows that have mouse control advanced and stuff like that and we'll have a full screen API but that's coming soon and that full screen API will also be integrated back in the gloves so that you can get stuff up and running pretty fast okay enough slides now I want to do something here which is i'm going to write some code okay you guys switch me over thank you all right remember how we all talked about I got to take a swig of this we don't talk about how fabulous our integration is with OS 10 I want to show you how rather than talk about it so I have project builder here okay no is this this is coming through how many you have used project builder had any exposure to attend at all about half okay well there are a lot of bugs got fixed there's still some in there ok so I'm going to start a new project I'm going to make a 3d application ok before your very eyes nothing up my sleeves no I'll start with a cung co application and let's call it our favorite the teapot I don't know if you guys probably can't see the this stuff way in the back there but bear with me for sex ok so project builder thinks about for a while this is here's the start of our application we've got project builders made a whole collapse framework forming now what I'm going to do is use interface builder to to make the 3d application ok so here project builder is given me a window and the main menu and a lot kind of good stuff so all I have to do to make a 3d application is take this custom view all right so I'm going to take a custom view in there and this big gray area here is going to be my 3d view it's in my treaty app I have to right now this is just a basic view within cocoa so I have to tell it that I want it to be a 3d view I'm going to do it in a couple steps first I'm going to say all right I'm going to take an NS OpenGL view which is right there it's built into interface builder but I also i need to sub classic because i'm going to do some of my own drawing i'm going to draw guess what a teapot ok so i want to call this subclass of OpenGL view at Eve you and I'm going to get it to create the H dot HTM file for me and then I take the custom view here and I say all right interface builder I want you to make it one of my TV classes so now it says you can't I can't read that too well but that says t view right there so that means this view is now one of my opengl view subclasses okay and then i'm also going to tell it to resize itself when the window resizes okay save that and I already made the class file so now i'm done i basically just made a 3d app and finished don't quit interface builder I have to do a little thing behind the scenes here and just built pay attention to this for a second really don't pay attention to this for a second for some reason interface builder puts things in funny places and you know well that's all I'm going to say okay this is you know little unix shell hacking here I'm sure you're all very familiar with it all right now to come back to my fabulous 3d project I need to take those class files that interface builder route for me and add them to the project from what I can understand this is all going to be much more tightly integrated in later versions probably available in any project really people here know too good ok so now i have my my classes here my 3d view and i'm basically done this is a 3d application it's not real exciting yet I know you guys are excited by cone I know you are so ok now let me grab some you guys all remember the galloping gourmet this isn't going to work either i got to get the dang terminal again or I'm finder okay I made some other files I'm not going to hack the whole thing now so I'm going to take these pre-built things they're a bunch of objects that I built we can go through some of them that do a lot of the 3d stuff to draw the teapot and i'm going to add these to the project as well ok so that's done and i have to add thing i always forget to add ok now i'm going to open my cut and paste source because isn't that what we all really do is we all just cut and paste I don't think anybody ever really types anything ok copy and I want to go to hear and paste ok this is objective c stuff for those of you don't know how many worked with Objective C before okay about half C++ programmers nearly everybody too bad straight see and stuff yeah okay objective-c is it's really object oriented so these are actual real method names they're like your class functions inside c++ only these are messaged at runtime so that's a big difference just a little side note okay so let me get some implementation for that using first thing I'm going to do is I have to include whoops wrong file promising stuff alive first of all I have to include the standard headers which in OS 10 are in OpenGL flesh opengl that age so GL program is here you've probably seen big GL there instead so this is a you know the different it's always a pain on every platform everybody puts their header files in a different spot I don't know why we just do so you know you have to get over it ok now I'm going to pull up some implementation here and I hope everybody can see this this you guys in the back and you see this code ok they're asleep all right now let me go over this real fast and then we can build a run this is not a super exciting program yet and you'll see what I mean in a minute what happens here is you if you're in jest talk you heard about the pixel format that's a way to ask for a certain kind of a drawable in our case in OS 10 is a certain kind of a window so you want a particular pixel depth you want a z-buffer a depth buffer stuck to it you want hardware accelerated and you send that off to the the cocoa layer which is in an opengl pixel format that's this line right here and you it goes into the GL engine which queries the hardware and says okay yes I can support that or here is the closest that i can get so what I asked for here is a depth size of one well you obviously I don't want a 1-bit deep z-buffer that would be dumb what I'm asking for there is the smallest z-buffer that you have but in this case I happen to know it's 16 I think we have 16 and 32 bit and there are cards with support different different z depths but this will give me a 16-bit give deep v buffer that's for accelerated and this is just 0 2 to terminate the list okay so then I get the pixel format here this generates one of these pixel formats and then since I'm a subclass of NS OpenGL view when we do this I just say hey super class I'm already I've got my pixel format you know what the frame rekt is go ahead and initialize yourself okay that makes it 3d now I've hooked up everything it takes care of hooking up the GL contacts everything I need then I have some responsibility to draw something well that's done with this method right here draw rect it gives me a wreck to draw inside of and all I'm going to do now at first is set the clear color to green that's RGB and alpha and then I'm just going to say clear the color buffer and the depth buffer in and then GL finish okay so let's see if this works I'm going to say build and run and it's worked before on another machine okay it's doing something there it is to 3d app let me say Dave it's a green square 3d okay well let's do something more all right now what I'm going to do is cut and paste more stuff and i'll add a peep on how about that okay i made a teapot object because you know I know how to do that and all I do here in my view are still inside mighty view object my subclass of OpenGL view i'm going to say i want to think on star oops hey these little keyboards you know there they're annoying and all right first step in oops first step in making my teapot is in my view class when initializes I'm just going to go ahead and make an instance of the teapot and so an objective seeing this is the same as your C++ constructor all right so i have a teapot object i wrote that has constructors and destructors and stuff like that and accept that they're not called that an objective-c and this is just calling the constructor so thanks anyone ok big deal now I have to draw it but drawing it is going to get a little more complicated than my green square because the teapot is more complicated the teapot object I implemented the draw method on the teapot object right here so you just met send a message draw and it's going to go and pump all the polygons and the texture information in the color and stuff like that into the GL engine to draw the teapot pretty straightforward well before that can happen I have to set up my 3d environment and that's what all this stuff is so the first thing I do is I need to set up a couple of light I'm going to put one light in this scene and this is how I do it I put it somewhere in space with the GL position parameter ok the GL position is here as 0066 then I give the light some ambient properties so it lights everything and this is a good way to avoid black screams and boy you get them a lot in GL then there's the diffuse component of the light which is really just saying that it's a white light by saying 111 here can I turn lighting on with this then I turn on the light that I made GLI 0 then i have to say okay opengl i want you to handle all visible surface computation for me turn on the depth test so that it doesn't show stuff you know inside out and weird like that then i want you to make sure the peapod looks like smooth i want you to clear the buffer the color buffer to all black and that's the clear statement there then i'm going to set up a way to look at the teapot i'm using glue perspective here because it's a handy way to think about positioning the eye instead of going straight to GL frustum which is really a brain cramp although once you figured out its cool so i say i want a 60 degree field of view that's you know like 35 millimeter camera then I take the drawing rectangle that I'm given which is the whole view and I figure out the aspect ratio by this you know its width / height pretty easy x over Y and then these are just parameters you just keep changing around till you can see the picture what I do okay then then I'm going to position the teapot in space six units down the negative z axis and I always like to think of unison like real like meters you know so I say six meters so that way when i get a black picture i can go and get a meter stick and i can put it on the ground and i can measure 6 meters and I can stand and measure me and say oh that's why I have the black picture because these six lug units or what units you don't know so I say meters okay so six meters all right so that's it now and then I tell my teapot to draw itself okay let's try it okay looks black back there it resizes does it all automatically and that's all that's all just from cocoa okay but it doesn't move with the mouse okay so how about if I make it move mouse yeah fortunately I made another object which is a trackball and it's it's the virtual trackball object for you know it's the thing that takes the 2d mouse motion and turns it into 3d rotations actually turns into court earnings which are really cool so i recommend you you read up on those when I figured out how to do the mic I felt really smart it's like math okay so I'm just adding a bunch of stuff here i'm happily copying and pasting and what I'm doing is adding a bunch of interface stuff onto this T view object the interesting thing here is that i can add these member variables and by the way you know I'm an old Microsoft hacker and Apple hired me so I put em under bar in front of my class that's a real nono an apple apparently why anyways so I have I'm going to put a trackball object in here and then I'm going to add some rotations so before you saw that I had no rotate I just I just move the teapot that's all GL translate now what I'm going to do is I'm going to make some rotations GL stores this rotation in angle axis which is almost the quaternion but not quite and well I'll talk to some people about that so then I'm going to add this rotate by method that the trackball object is going to call and I'm going to take the standard in its view methods that are already in cocoa and I'm going to add some code on my own code underneath them all right so this is mouse down mouse a mouse drag and I think you can probably guess what these do this is when the mouse is clicked this method gets called and when the mouse is led up this gets called when it's dragged this gets called with the events and stuff like that so your object sits there and gets messages from the event system in cocoa all right so let's go ahead and add the implementation of these things first I have to initialize these rotations so up here in the initialization code I'm going to go ahead and add this line here which makes a new track well object and then these lines here just initialize the rotations of the teapot to an identity rotation now they're words no angle and unit vector along the x-axis remember that linear algebra stuff you were all supposed to study yeah this is it okay learn it you'll feel smarter all right now I'm going to add the rotations one thing you have to remember when doing OpenGL if you've done 3d programming you know you got Foley in Van Dam and you read it all and it's really cool and you can write renders and stuff and make models and and you know you're cool right you can make 3d it's great well the thing to remember is that in GL the matrix functions are backwards I don't know why they just they're backwards so in normal life you would say okay first I want to take the teapot and I'm going to rotate it by whatever rotation are currently has then I'm going to add a little bit that the trackball does and then I'm going to move it away from me all right that's normally what you'd say well in GL you have to do it backwards so I like to think of if you're standing in the code at the teapot and looking backwards it served almost four words well you can figure it out so all right let's just say that that will work okay then I'm going to take all this code of this this stuff oh I showed off my sequence that i want to say till the end okay so let's talk about what this code does here the rotate by is going to be called from the trackball object and you want to see what that looks like the track logic it's cool use quaternions it's like math and stuff okay it does this junk and then somewhere in here it's going to call aha okay it figures he has stuff like 8-10 to is cool it's going to it figures out a rotation the trackball you know I don't really need to explain this but you've got the I'm going anyways the mouse defines a 2d vector which you then mapped to a sphere and unit sphere usually and that gives you two vectors and take the cross product you've got a rotation angle and if you take the dot product you have the cosine and angle and stuff like that and then you can turn that into an angle axis rotation through some core training math which is down here and then I just send that back to the view that requested the trackball okay so let's look back at the view this is still 9ns opengl view which is an ask you and what I do in when the mouse goes down is I tell the trackball to start and I say here here's where the mouse was clicked so the view knows where the mouse is clicked with you is handling all the 2d stuffs the mouse events and everything like that is coming into the view then I send that I the event is it as an object from cocoa I say what's the location in the window so does all the window transformation for me and I get an XY this relative to window coordinates I give that to the trackball the trackball start as I drag the trackball around okay this wait that looks better I say first of all I'm going to do some drawing inside this view so i have to do some things according to coco life to lock focus on myself then track I say trackball roll through the new Mouse location because as i get these mouse drags it's telling me the XY where the mouth is and there's the event location windows i give that attract all the trackball and track will does roll too it's going to figure it all that cool math stuff and then it's going to say rotate by to this view it's going to message this view back with the new rotations which is right here and then those get accumulated up here right so this all sounds pretty good let's see what happens when the rubber meets the road okay hang on to your pocket protectors [Applause] and that's it now I can look that was the wrong thing to do let me get project builder back alive here I can put a brick texture map on that why not we got time okay yeah yes it's rotating with the teapot I think hang on a second let me let me get this up here and then i gotta finish the scripted part and then because now you're asking for stuff I haven't tried that's really scary this is bad enough alright let's go here and then i put a little method on my teapot object let's says and cut use texture there I type it into I didn't even cut and paste honey like that alright build and run okay okay so now you want me to make it so that the light doesn't move with the teapot I don't know you guys you're pushing okay well we have to go to QA i specify the texture inside of the teapot object which is right here these are the teapot coordinates oh okay this is kind of an interesting little cocoa tidbit which is I use theirs NS bundles if you work with those before SEF bundles you know there a way of accessing the applications are built in what are called apparatus because we don't have resource forks in OS 10 so you can't just take your stuff you need to append to your app and all your little adornments to go with your app and sticking the resource for can call it good you have to put them in the UNIX file system somewhere well in s bundle and CF bundle are ways to abstract away the fact that you have to do that on can and not online and what I do here is I say finds the briquette RGB resource so that's just a file sitting in the file system then i have this file called retexture or this function i mean called retexture which goes and sucks up all the RGB pixels excuse me so now i have a big a ring which is my texture map and here is where I set all the stuff to turn the texturing on and if you're in Jeff stock you saw a lot of this stuff already so this this turns on it a 2d texture I want to repeat and ask for Pete and T use linear filters then here is where I say what the texture is so M texture is a pointer to that big array of RGB pixels and this is where I tell it to use the texture and then I turn that switch on down here this is the set use texture method you some before so this is the implementation I just turn a texture flag on that's all okay why don't we go to Q&A because I think yeah okay that's it lets go to QA