Post by 8XenoTrogdor8 on Feb 23, 2005 0:56:35 GMT -5
Display lists are great! In case you dont know what a display list is, they are lists of OpenGL commands that can be constructed and pre-compiled. The list can hold translations, rotations, quads, triangles, ect. ect. pretty much any OpenGL command. Then the list can be called at any time, and since it's pre-compiled everything loads A_LOT quicker than re-building the list every frame! (This is why models in .bgm format are loaded into a display list). Anyway, I've made a small demo on using the display lists. (Also a little in there about drawing spheres!).
Maybe I went a little overboard with the planets...
But at any rate, this shows how display lists can speed up the code! (if the sphere was re-drawn for each different planet, the code would run at about half, or less than half, the frame rate).
If you're interested in texturing the spheres (or just want to learn a little more about how they work), check out GuppyB's excellent post on textured spheres - basic4gl.proboards20.com/index.cgi?board=demo&action=display&thread=1089685542. Or just PM me and I'll help ya out.
Enjoy!
Later all.
' from the labs of XenoVacivus,
' the display list demo!
' v1.20
' Define the definition of the sphere.
Const Oranges# = 20 ' Wedges like in an orange. specify the number of wedges.
Const Onions# = 10 ' Cut slices like an onion. specify the number of slices.
Const Radius# = 1 ' The initial radius of the sphere.
dim x#, y#, z# ' coordinates for vertices
dim i1#, i2#, i3# ' for/next loop variables
dim rotate# ' scene rotation variable
dim LightAmbient#(3): LightAmbient# = vec4 (.5, 0, .5, 1)
dim LightDiffuse#(3): LightDiffuse# = vec4 (.7, 1, .7, 1)
dim LightPosition#(3):LightPosition# = vec4 (0, -5, -5, 1)
dim MY_SPHERE : MY_SPHERE = 1 ' call lists have to be given a unique nonzero whole number,
' but that number can be in the form of a variable too.
dim MY_DOT_SPHERE : MY_DOT_SPHERE = 2
dim SelectedCallList : SelectedCallList = MY_SPHERE
glEnable (GL_LIGHTING)
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient#) ' light thats always there.
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse#) ' light coming from a source.
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition#) ' where the light source is.
glEnable(GL_LIGHT1) ' enable the light source that was just created.
' Now create and compile two lists of OpenGL commands-
' Draw a sphere using solid quads (quadstrips, anyway)-
glNewList (MY_SPHERE, GL_COMPILE) ' call the start of a list and set it to compile only.
for i1# = 0 to Oranges# ' Orangecount
glBegin (GL_QUAD_STRIP)
for i2# = 0 to Onions# ' Onioncount
' Modify x, y and z coordinates depending on the formula for a circle.
x# = radius# * cos (i1# * 2*M_PI / Oranges#) * sin (i2# * M_PI / Onions#)
y# = radius# * sin (i1# * 2*M_PI / Oranges#) * sin (i2# * M_PI / Onions#)
z# = radius# * cos (i2# * M_PI / Onions#)
glNormal3f (x#, y#, z#)
glVertex3f (x#, y#, z#)
i1# = i1# + 1 ' Add one to the Orangecount to find a vertice in the next wedge over. This will stretch the texture from wedge to wedge.
' Modify the coordinates again to match up with the next wedge over.
x# = radius# * cos (i1# * 2*M_PI / Oranges#) * sin (i2# * M_PI / Onions#)
y# = radius# * sin (i1# * 2*M_PI / Oranges#) * sin (i2# * M_PI / Onions#)
z# = radius# * cos (i2# * M_PI / Onions#)
glNormal3f (x#, y#, z#)
glVertex3f (x#, y#, z#)
i1# = i1# - 1 ' Take that one away to prepare for the next slice or wedge.
next
glEnd ()
next
glEndList ()
' Draw another sphere using just dots-
glNewList (MY_DOT_SPHERE, GL_COMPILE)
glBegin (GL_POINTS)
for i1# = 0 to Oranges#
for i2# = 0 to Onions#
x# = radius# * cos (i1# * 2*M_PI / Oranges#) * sin (i2# * M_PI / Onions#)
y# = radius# * sin (i1# * 2*M_PI / Oranges#) * sin (i2# * M_PI / Onions#)
z# = radius# * cos (i2# * M_PI / Onions#)
glVertex3f (x#, y#, z#)
next
next
glEnd ()
glEndList () ' End the list.
' Start the loop.
While True
glClear (GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT)
glLoadIdentity ()
glTranslatef (0, 0, -10)
glRotatef (45, 1, 0, 0)
while SyncTimer (10)
rotate# = rotate# + .1
wend
if ScanKeyDown (VK_LEFT) then
SelectedCallList = MY_SPHERE
glEnable (GL_LIGHTING)
endif
if ScanKeyDown (VK_RIGHT) then
SelectedCallList = MY_DOT_SPHERE
glDisable (GL_LIGHTING)
endif
glRotatef (rotate#, 0, 0, 1)
glCallList (SelectedCallList) ' Call the pre-compiled list.
for i1# = 0 to 2 ' build a set of planets-
glPushMatrix ()
glRotatef (i1# * 120, 0, 0, 1)
glTranslatef (4, 0, 0)
glRotatef (rotate#, 0, 0, 1)
glScalef (.4, .4, .4)
glCallList (SelectedCallList)
for i2# = 0 to 2 ' build another set of planets-
glPushMatrix ()
glRotatef (i2# * 120, 0, 0, 1)
glTranslatef (4, 0, 0)
glRotatef (rotate#, 0, 0, 1)
glScalef (.6, .6, .6)
glCallList (SelectedCallList)
for i3# = 0 to 2 ' geez, thats a lot of planets!
glPushMatrix ()
glRotatef (i3# * 120, 0, 1, 0)
glTranslatef (4, 0, 0)
glRotatef (rotate#, 0, 1, 0)
glScalef (.8, .8, .8)
glCallList (SelectedCallList)
glPopMatrix ()
next
glPopMatrix ()
next
glPopMatrix ()
next
SwapBuffers ()
wend
' formula for any one point on a sphere-
' x# = radius * cos (longitude) * sin (lattitude)
' y# = radius * sin (longitude) * sin (lattitude)
' z# = radius * cos (lattitude)
' where longitude is between 0 and 2PI and lattitude is between 0 and PI.
' so to get a complete sphere, just go through all the possible values for lattitude and longitude.
Maybe I went a little overboard with the planets...
But at any rate, this shows how display lists can speed up the code! (if the sphere was re-drawn for each different planet, the code would run at about half, or less than half, the frame rate).
If you're interested in texturing the spheres (or just want to learn a little more about how they work), check out GuppyB's excellent post on textured spheres - basic4gl.proboards20.com/index.cgi?board=demo&action=display&thread=1089685542. Or just PM me and I'll help ya out.
Enjoy!
Later all.