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