More on Drawable Objects, Hierarchical Objects - PowerPoint PPT Presentation

About This Presentation
Title:

More on Drawable Objects, Hierarchical Objects

Description:

It is reasonable to represent different kinds of drawable objects with different data types. Deriving all of these from a common base class ('Drawable' ... – PowerPoint PPT presentation

Number of Views:90
Avg rating:3.0/5.0
Slides: 19
Provided by: glenngc
Learn more at: https://www.cs.uaf.edu
Category:

less

Transcript and Presenter's Notes

Title: More on Drawable Objects, Hierarchical Objects


1
More on Drawable Objects,Hierarchical Objects
  • Glenn G. ChappellCHAPPELLG_at_member.ams.org
  • U. of Alaska Fairbanks
  • CS 481/681 Lecture Notes
  • Wednesday, January 21, 2004

2
ReviewDrawable Objects 1/4
  • Now we begin looking at how to represent a scene
    internally.
  • It will be convenient to be able to deal with
    drawable objects independent of their
    characteristics.
  • There are many ways to do this we discuss the
    usual OO solution, as implemented in C.
  • It is reasonable to represent different kinds of
    drawable objects with different data types.
  • Deriving all of these from a common base class
    (Drawable?) allows us to draw them without
    knowing what type they are.

3
ReviewDrawable Objects 2/4
  • Here is one way to write our base class
  • // class Drawable
  • // Abstract base class for drawable objects
  • class Drawable
  • public
  • virtual Drawable()
  • virtual void draw() const 0
  • Thats all!
  • The destructor is a C detail a base class
    should have a virtual destructor.
  • Note that Drawable is an abstract class (due to
    the 0) we cannot declare objects of type
    Drawable.

4
ReviewDrawable Objects 3/4
  • To declare a drawable object type, do something
    like this
  • class Cokebottle public Drawable
  • public
  • virtual Cokebottle()
  • virtual void draw() const
  • Cokebottle()Drawable(),iscokeit(false)
  • void cokeisit()
  • iscokeit true
  • private
  • bool iscokeit // true if Coke is it.
  • void Cokebottledraw() const
  • Draw a cokebottle here.

5
ReviewDrawable Objects 4/4
  • To use objects polymorphically, refer to them via
    base-class pointers or references
  • void draw_this(const Drawable obj)
  • obj.draw() // Calls the proper virtual
    function.
  • Function draw_this can take a parameter of any
    type derived from Drawable.
  • The above code would not work correctly if the
    object were passed by value.
  • Now we can do this
  • Cokebottle c
  • draw_this(c)

6
More on Drawable ObjectsInheritance and
Containers 1/3
  • Since we can deal with all drawable objects the
    same way, we can stick all of our objects into a
    container (array, vector, etc.), and iterate
    through that container to draw the scene.
  • However, the following will get us into trouble.
  • stdvectorltDrawablegt scene
  • Why?
  • Hint There are two big problems here.

7
More on Drawable ObjectsInheritance and
Containers 2/3
  • stdvectorltDrawablegt scene
  • First, this will not compile.
  • Since Drawable is an abstract class, we cannot
    create objects of type Drawable.
  • But, second, even if we make Drawable a concrete
    class, this is a problem.
  • A Cokebottle is probably bigger than a Drawable.
    So we cannot store a Cokebottle in the space
    meant for a Drawable.
  • The problem resulting from trying to store an
    object of a derived class in a base-class
    variable is called slicing.

8
More on Drawable ObjectsInheritance and
Containers 3/3
  • Solution Use base-class pointers.
  • Be sure that objects are deleted properly!
  • stdvectorltDrawable gt scene
  • To add to the scene
  • scene.push_back(new Cokebottle)
  • To draw the entire scene
  • stdvectorltDrawable gtconst_iterator it
  • for (it scene.begin() it ! scene.end() it)
  • (it)-gtdraw()

9
Hierarchical ObjectsOverview
  • Suppose we wish to draw a moving object with
    moving parts.
  • This is called a hierarchical object.
  • See face.cpp for an example.
  • Two questions
  • How can we handle this conveniently with our
    graphics API?
  • What sorts of data structures are appropriate for
    storing such an object?
  • We begin with the first question.

10
Hierarchical ObjectsIntroduction
  • We think of an object with moving parts as a
    hierarchy.
  • At the top of the hierarchy is the object as a
    whole.
  • At the next lower level in the hierarchy are the
    moving parts (for example, the eyes in face.cpp).
  • Moving parts can contain moving parts these are
    at an even lower level in the hierarchy.
  • We use stack operations to handle the
    transformations involved in drawing hierarchical
    objects.

11
Hierarchical ObjectsTransformations 1/4
  • We want a moving object to have a moving part.
  • We should be able to move the object as a whole.
  • We should also be able to move the part as a part
    of the object.
  • Thus, one transformation is applied to the object
    as a whole, but two transformations are applied
    to the moving part.
  • The transformation for the moving part needs to
    be done before the transformation of the object
    as a whole (right?) therefore it comes later in
    the code (right?).

12
Hierarchical ObjectsTransformations 2/4
  • Pseudocode
  • glPushMatrix()
  • Set up transformation for whole object
  • Draw non-moving parts
  • glPushMatrix()
  • Multiply current matrix by transformation
    for moving part
  • Draw moving part
  • glPopMatrix()
  • glPopMatrix()
  • This is the general form of the code to draw a
    hierarchical object.
  • What are the push/pop really good for? See the
    next slide

13
Hierarchical ObjectsTransformations 3/4
  • What if a hierarchical object has more than one
    moving part?
  • glPushMatrix()
  • Set up transformation for whole object
  • Draw non-moving parts
  • glPushMatrix()
  • Multiply current matrix by transformation
    for moving part 1
  • Draw moving part 1
  • glPopMatrix()
  • glPushMatrix()
  • Multiply current matrix by transformation
    for moving part 2
  • Draw moving part 2
  • glPopMatrix()
  • glPopMatrix()
  • It is convenient to make some of the pieces above
    into separate functions.
  • Then follow this rule If a function changes a
    matrix, then it also restores it to its prior
    value.
  • This is essentially the form of our example
    (discussed shortly).

14
Hierarchical ObjectsTransformations 4/4
  • What if a hierarchical object has more than two
    levels?
  • glPushMatrix()
  • Set up transformation for whole object
  • Draw non-moving parts
  • glPushMatrix()
  • Multiply current matrix by transformation
    for moving part 1
  • Draw moving part 1
  • glPushMatrix()
  • Multiply current matrix by
    transformation for
  • sub-part 1 of moving
    part 1
  • Draw sub-part 1 of moving part 1
  • Etc

15
Hierarchical ObjectsExample (face.cpp) 1/4
  • void display()
  • glClear(GL_COLOR_BUFFER_BIT)
  • // Draw face
  • glPushMatrix()
  • glTranslated(face_move, 0.0, 0.0)
  • glRotated(face_angle, 0,0,1)
  • glScaled(face_scale, face_scale,
    face_scale)
  • draw_face()
  • glPopMatrix()
  • This is the beginning of the display routine. It
    sets up the transformation for the face, then
    calls draw_face to do the drawing.

16
Hierarchical ObjectsExample (face.cpp) 2/4
  • Here is a portion of the code for function
    draw_face
  • // Draw head
  • glColor3d(0.8, 0.6, 0.4)
  • glCallList(disk_list)
  • // Draw left eye (on viewer's right)
  • glPushMatrix()
  • glTranslated( 0.4, 0.3, 0.0)
  • glScaled(0.2, 0.2, 1.0)
  • draw_eye()
  • glPopMatrix()
  • // Draw right eye (on viewer's left)
  • glPushMatrix()
  • glTranslated(-0.4, 0.3, 0.0)
  • glScaled(0.2, 0.2, 1.0)
  • draw_eye()
  • glPopMatrix()

17
Hierarchical ObjectsExample (face.cpp) 3/4
  • Each function can be written to draw its part
    within a square of side 2, centered at the origin
    (x y go from 1 to 1).
  • Then we set up the transformation to put the part
    in the proper place before we call the function
    that draws it.
  • The function that does the drawing uses the
    transformation it is given, modifies it if
    necessary, but always restores it to the original
    value.
  • void draw_eye()
  • // Draw white of eye
  • glPushMatrix()
  • glScaled(1.0, 0.4, 1.0)
  • glColor3d(1.0, 1.0, 1.0)
  • glCallList(disk_list)
  • glPopMatrix()

18
Hierarchical ObjectsExample (face.cpp) 4/4
  • Comments
  • Each function is written to draw the appropriate
    part (and all sub-parts) in some kind of
    standard position.
  • Again, sub-part transformations come before the
    main transformations, which means they are later
    in the code, which means they can go in the
    function that draws the sub-part (right?).
  • This is all very convenient and easy to use, once
    you wrap your mind around it.
  • We are very clear about expectations for matrix
    mode, etc., when entering and leaving each
    function.
  • The initial set-up is done when the reshape
    function is first called.
  • After that, whenever a function finishes, we are
    careful to leave things the way they were when it
    started.
Write a Comment
User Comments (0)
About PowerShow.com