350 likes | 511 Vues
1. Hierarchical Modeling II Scene Graph Chapter 10 by Ray Wisman rwisman@ius.edu. Objectives. Examine design of scene graph API. Implement simple scene of partial robot using the API. Scene Graph API Download. Author’s version supports 3 cameras (windows). We will support only one camera.
E N D
1 Hierarchical Modeling IIScene Graph Chapter 10 by Ray Wisman rwisman@ius.edu
Objectives • Examine design of scene graph API. • Implement simple scene of partial robot using the API.
Scene Graph APIDownload • Author’s version supports 3 cameras (windows). • We will support only one camera. • 3
Node class • 4 class Node { public: Node(); virtual ~Node(); virtual void Render(); void AddChild(Node *); private: void Traverse(); Node *LeftChild; Node *RightSibling; friend class GLViewer; }; • All types of nodes of scene graph same. • Each implements a Render() function. • Has LeftChild and RightSibling node. RightSibling LeftChild
Node Traverse() • 5 • KeepMatrix true when child nodes should inherit transformations of parent. • Renders itself first with transformations. • Siblings only inherit parent node’s transformations. void Node::Traverse() { if(!KeepMatrix) glPushMatrix(); Render(); if(LeftChild!=NULL) LeftChild->Traverse(); if(!KeepMatrix) glPopMatrix(); if(RightSibling!=NULL) RightSibling->Traverse(); }
Node Traverse() • A simple scene graph with no siblings. Transformation void Node::Traverse() { if( !KeepMatrix ) glPushMatrix(); Render(); if(LeftChild!=NULL) LeftChild->Traverse(); if( !KeepMatrix ) glPopMatrix(); if(RightSibling!=NULL) RightSibling->Traverse(); } Material Light Base Head
Constants • 7 • Symbolic constants used to specify attributes for color, line style, material properties. enumEnum { PERSPECTIVE, ORTHO, POSITION, AIMAT, UPDIRECTION, ASPECT, NEAR, FAR, YANGLE, BLACK, WHITE, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, GREY, WIDTH, HEIGHT,DEPTH, AMBIENT, DIFFUSE, SPECULAR, SPOT_DIRECTION, DROPOFFRATE, CUTOFFANGLE, EMISSION, SHININESS,TRANSLATION, ROTATION, SCALE, BUFFER, SINGLE, DOUBLE, RADIUS, STYLE, POINTSIZE, LINEWIDTH, FILLED, LINE, POINT, BACKCOLOR };
Geometry classPartial listing • 8 class Geometry: public Node { public: Geometry(); ~Geometry(); void SetColor(Enum); void SetMaterial(Material *); void SetTransform(Enum, float *, int); virtual void Render(); protected: Color *ColorNode; Material *MatNode; Transformation *TransNode; }; • Geometry inherits from Node. • Has Render() function. • Nodes for color, material and transformation.
Line class • 9 class Line: public Geometry { public: Line(){}; void SetVertices(float *, float *); void SetVerticesv(float v[][3]); void Render(); private: float Vertices[2][3]; }; • Line inherits from Geometry. • Inherits nodes for color, material and transformation. • Has Render() function. • And 2 vertices.
Line Render() • 10 Line::Render() { glPushAttrib(GL_ALL_ATTRIB_BITS); if(ColorNode) ColorNode->Render(); if(MatNode) MatNode->Render(); if(TransNode) TransNode->Render(); glBegin(GL_LINES); glVertex3fv(Vertices[0]); glVertex3fv(Vertices[1]); glEnd(); glPopAttrib(); } • Nodes for color, material and transformation. • Line Render() calls each attribute node Render(). • And draws line.
Sphere class • 11 class Sphere: public Geometry { public: Sphere(){}; Sphere(float R); void SetValue(EnumPname, float v); void Render(); private: float Radius; }; • Sphere inherits from Geometry. • Inherits nodes for color, material and transformation. • Has Render() function. • And radius.
Sphere Render() • 12 Sphere::Render() { glPushAttrib(GL_ALL_ATTRIB_BITS); if(ColorNode) ColorNode->Render(); if(MatNode) MatNode->Render(); if(TransNode) TransNode->Render(); glutSolidSphere(Radius, 40, 40); glPopAttrib(); } • Nodes for color, material and transformation. • Sphere Render() calls each attribute node Render(). • And draws sphere.
Camera classpartial • 13 class Camera: public Node { public: Camera(EnumCType); void Render(); void SetValue(EnumPName, float v); private: Enum Type; float Position[3]; float AimAt[3]; float UpDirection[3]; float Near; float Far; float Height; float Aspect; • Camera inherits from Node. • Has Render() function. • Can be positioned, perspective/ortho viewing, bounding volume defined.
Camera Render()partial • 14 void Camera::Render() { float x2=Height*Aspect/2; float x1=(-1)*x2; float y2=Height/2; float y1=(-1)*y2; glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(Type==ORTHO) glOrtho(x1, x2, y1, y2, Near, Far); else gluPerspective(YAngle, Aspect, Near, Far); glMatrixMode(GL_MODELVIEW); • Calculates bounding volume. • Sets projection to either ortho or perspective.
Light classpartial • 15 class Light: public Node { public: void Render(); void SetValue(EnumPName, float f); void TurnOn(); private: static intLightNum; GLenumLightName; float Diffuse[4]; float Specular[4]; float Ambient[4]; float Position[4]; friend class TurnOff; }; • Light inherits from Node. • Has Render() function. • Has position and usual Phong lighting model attributes.
Light Render()partial • 16 • Enables lighting. • Enables light. • Sets light position and attributes. void Light::Render() { glEnable(GL_LIGHTING); glEnable(LightName); glLightfv(LightName, GL_AMBIENT, Ambient); glLightfv(LightName, GL_DIFFUSE, Diffuse); glLightfv(LightName, GL_SPECULAR, Specular); glLightfv(LightName, GL_POSITION, Position); }
Material classpartial • 17 class Material: public Node { public: Material(); void SetValuev(EnumPname, float *); void Render(); private: bool Changed[5]; float Ambient[4]; float Diffuse[4]; float Specular[4]; float Emission[4]; float Shininess; }; • Material inherits from Node. • Has Render() function. • Has usual Phong reflection model attributes.
Material Render()partial • 18 • Sets material attributes. void Material::Render() { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Emission); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, Shininess); }
Transformation class • 19 class Transformation: public Node { public: Transformation(); void SetValuev(EnumPname, float *, int Order); void Render(); private: intOpNum; intTransformOrder[10]; float Transform[10][4]; }; • Transformation inherits from Node. • Has Render() function. • Supports up to 10 transformations. • Applies in reverse order defined.
Transformation Render() • 20 void Transformation::Render() { for(inti=OpNum-1; i>=0; i-- ) switch(TransformOrder[i]) { case TRANSLATION: glTranslatef(Transform[i][0], Transform[i][1], Transform[i][2]); break; case ROTATION: glRotatef(Transform[i][0], Transform[i][1], Transform[i][2], Transform[i][3]); break; case SCALE: glScalef(Transform[i][0], Transform[i][1], Transform[i][2]); break; } }
GLViewer class • 21 • Creates window of given height and width. • Initiates the traversal of scene graph from a given node. class GLViewer { public: GLViewer(); ~GLViewer(); void CreateWin(char *Name, int Width, int Height); void SetValue(EnumPName, Enum Type); void Init(int argc, char **argv); void Show(Node *N); private: void GLInit();
GLView Show() and GLInit() • 22 GLViewer::Show(Node *N) { GLInit(); Root=N; glutMainLoop(); } • Initializes windows. • Defines root of scene graph. • Starts glutMainLoop(). void GLViewer::GLInit() { glutInitDisplayMode(BufType | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(WinWidth, WinHeight); glutCreateWindow(WinName); glutReshapeFunc(Reshape); glutDisplayFunc( Display ); glEnable(GL_DEPTH_TEST); glClearColor(BackColor[0], BackColor[1], BackColor[2], 1.0); }
GLView Display() • 23 • Starts Traverse() from Root. void GLViewer::Display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Root->Traverse(); glFlush(); }
Simple example using scene graph API • The author gave an example using the API to create a scene with a robot, chair and paper. • Our simple example has one window with only the robot’s base and head. • Only one light and material is used. • 24
Scene graph • First, need to define a scene graph using API. • GLView can then traverse the graph. • Because child nodes must first exist in order to be linked to parent nodes, must define graph from bottom-up. • First define the head. Root Camera Transformation Material Light Base Head
Define some constantsmain() #include "Scene.h" #define BaseRadius 0.2 #define Radius 0.08 #define BaseLen 1 int main(intargc, char **argv){ • Include the Scene API. • Define some parameters.
Head • Define the translation transformation of the Head relative to the Base. • Define the Head as a Sphere geometry object. Transformation *HeadTrans=new Transformation; HeadTrans->SetValue(TRANSLATION, 0, 0, BaseLen+BaseRadius+BaseRadius/3, 0); Sphere *Head=new Sphere; Head->SetValue(RADIUS, BaseRadius); Head->SetTransform(HeadTrans); Head
Base • Define the transformations of the Base. • Define the Base as a Cylinder geometry object. • Add Head as a child. Transformation *BaseTrans=new Transformation; BaseTrans->SetValue(ROTATION, -90, 1, 0, 0, 0); BaseTrans->SetValue(ROTATION, -10, 0, 0, 1, 1); Cylinder *Base=new Cylinder; Base->SetValue(HEIGHT, BaseLen); Base->SetValue(RADIUS, BaseRadius); Base->SetTransform(BaseTrans); Base->AddChild( Head ); Base Head
Light • Define the Light. • Define the position of the Light. • Add Base as a child. Light *Light1=new Light; Light1->SetValue(POSITION, -2, -3, 1.5, 1); Light1->SetValue(SPOT_DIRECTION, 2, 3, -1.5); Light1->SetValue(CUTOFFANGLE, 40.0); Light1->TurnOn(); Light1->AddChild( Base ); Light Base Head
Material • Define the Material. • Define the attributes of the material. • Add Light1 as a child. Material *RobotMat=new Material; RobotMat->SetValue(DIFFUSE, 0.0, 0.0, 1.0, 1.0); RobotMat->SetValue(AMBIENT, 0.0, 0.0, 1.0, 1.0); RobotMat->SetValue(SPECULAR, 1.0, 1.0, 1.0, 1.0); RobotMat->SetValue(SHININESS, 100.0); RobotMat->AddChild( Light1 ); Material Light Base Head
Transformation • Define the transformation. • Define the translation to be applied to all children. • Add material as a child. Transformation Material Transformation *Trans1=new Transformation; Trans1->SetValue(TRANSLATION, -0.5, 0, 0, 2); Trans1->AddChild( RobotMat ); Light Base Head
Camera • Define the Camera and attributes. Camera Transformation Camera *Camera1= new Camera(PERSPECTIVE); Camera1->SetValue(POSITION, 2.2, 0.9, 3); Camera1->SetValue(AIMAT, 0, 0, 0); Camera1->SetValue(UPDIRECTION, 0, 1, 0); Camera1->SetValue(ASPECT, 1); Camera1->SetValue(NEAR, 1); Camera1->SetValue(FAR, 20); Camera1->SetValue(YANGLE, 50); Material Light Base Head
Root • Define the Root node. • Add Transformation and Camera as children. Root Camera Transformation Material Node *Root=new Node; Root->AddChild( Trans1 ); Root->AddChild( Camera1 ); Light Base Head
GLView • Define the Viewer. • Traverse the scene graph. Root Camera Transformation Material GLViewer *MyViewer=new GLViewer; MyViewer->Init(argc, argv); MyViewer->SetValue(BACKCOLOR, GREY); MyViewer->SetValue(BUFFER, DOUBLE); MyViewer->CreateWin(“Robot", 500, 500); MyViewer->Show( Root ); Light Base Head
API Questions • Download the complete program using the scene graph API. • Notice there is no direct use of the OpenGL API, only the scene graph API. • What is missing from the API? • Texture • User-interaction • Other? • What would be the effect of mixing OpenGL with the API calls?