Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/ribgsg/ribGraphicsStateGuardian.cxx

Go to the documentation of this file.
00001 // Filename: ribGraphicsStateGuardian.cxx
00002 // Created by:  drose (15Feb99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "ribGraphicsStateGuardian.h"
00020 #include "ribStuffTraverser.h"
00021 #include "config_ribgsg.h"
00022 
00023 #include <directRenderTraverser.h>
00024 #include <displayRegion.h>
00025 #include <projectionNode.h>
00026 #include <projection.h>
00027 #include <camera.h>
00028 #include <renderBuffer.h>
00029 #include <transformTransition.h>
00030 #include <colorTransition.h>
00031 #include <textureTransition.h>
00032 #include <lightTransition.h>
00033 #include <geom.h>
00034 #include <geomprimitives.h>
00035 #include <geomIssuer.h>
00036 #include <graphicsWindow.h>
00037 #include <graphicsChannel.h>
00038 #include <indent.h>
00039 #include <dftraverser.h>
00040 #include <node.h>
00041 #include <projectionNode.h>
00042 #include <texture.h>
00043 #include <textureContext.h>
00044 #include <light.h>
00045 #include <get_rel_pos.h>
00046 #include <projection.h>
00047 #include <perspectiveProjection.h>
00048 #include <frustum.h>
00049 #include <ambientLight.h>
00050 #include <directionalLight.h>
00051 #include <pointLight.h>
00052 #include <spotlight.h>
00053 #include <pandabase.h>
00054 
00055 #include <assert.h>
00056 
00057 TypeHandle RIBGraphicsStateGuardian::_type_handle;
00058 
00059 // Here are some global arrays we use in the various draw() routines
00060 // to hold temporary coordinate values for each Geom for formatting.
00061 
00062 static pvector<Vertexf> rib_vertices;
00063 static pvector<Normalf> rib_normals;
00064 static pvector<TexCoordf> rib_texcoords;
00065 static pvector<RGBColorf> rib_colors;
00066 
00067 static void
00068 issue_vertex_rib(const Geom *geom, Geom::VertexIterator &vi) {
00069   rib_vertices.push_back(geom->get_next_vertex(vi));
00070 }
00071 
00072 static void
00073 issue_normal_rib(const Geom *geom, Geom::NormalIterator &ni) {
00074   rib_normals.push_back(geom->get_next_normal(ni));
00075 }
00076 
00077 static void
00078 issue_texcoord_rib(const Geom *geom, Geom::TexCoordIterator &ti) {
00079   // We need to reverse the V coordinate for RIB.
00080   static LMatrix3f
00081     texmat(1.0, 0.0, 0.0,
00082            0.0, -1.0, 0.0,
00083            0.0, 1.0, 1.0);
00084   rib_texcoords.push_back(geom->get_next_texcoord(ti) * texmat);
00085 }
00086 
00087 static void
00088 issue_color_rib(const Geom *geom, Geom::ColorIterator &ci,
00089                 const GraphicsStateGuardianBase *) {
00090   // RIB only cares about three-component color, so we have to convert
00091   // the four-component color transition to three-component color here.
00092   rib_colors.push_back((const RGBColorf &)geom->get_next_color(ci));
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: RIBGraphicsStateGuardian::Constructor
00097 //       Access: Public
00098 //  Description:
00099 ////////////////////////////////////////////////////////////////////
00100 RIBGraphicsStateGuardian::
00101 RIBGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) {
00102   reset();
00103 
00104   // Create a default RenderTraverser.
00105   _render_traverser =
00106     new DirectRenderTraverser(this, RenderRelation::get_class_type());
00107 
00108   _texture_directory = "maps";
00109   _texture_extension = "tiff";
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: RIBGraphicsStateGuardian::reset
00114 //       Access: Public, Virtual
00115 //  Description: Resets all internal state and prepares a new RIB
00116 //               file.
00117 ////////////////////////////////////////////////////////////////////
00118 void RIBGraphicsStateGuardian::
00119 reset() {
00120   GraphicsStateGuardian::reset();
00121 
00122   // We only have a color buffer in RenderMan.
00123   _buffer_mask = RenderBuffer::T_color;
00124 
00125   _output = NULL;
00126   _indent_level = 0;
00127 
00128   // We clear the texture names only for each file, not for each
00129   // frame, because texture definitions remain across frames.
00130   _texture_names.clear();
00131 
00132   reset_frame();
00133 }
00134 
00135 ////////////////////////////////////////////////////////////////////
00136 //     Function: RIBGraphicsStateGuardian::reset_file
00137 //       Access: Public
00138 //  Description: Resets all internal state and prepares a new RIB
00139 //               file to the indicated output stream.
00140 ////////////////////////////////////////////////////////////////////
00141 void RIBGraphicsStateGuardian::
00142 reset_file(ostream &out) {
00143   reset();
00144   _output = &out;
00145 }
00146 
00147 ////////////////////////////////////////////////////////////////////
00148 //     Function: RIBGraphicsStateGuardian::reset_frame
00149 //       Access: Public
00150 //  Description: Resets whatever state is appropriate at the end of a
00151 //               frame.
00152 ////////////////////////////////////////////////////////////////////
00153 void RIBGraphicsStateGuardian::
00154 reset_frame() {
00155   // We must clear the light definitions for each frame.
00156   _light_ids.clear();
00157   _enabled_lights.clear();
00158   _enabled_lights.push_back(true);
00159 
00160   _current_color.set(1.0, 1.0, 1.0);
00161   _state.clear();
00162 }
00163 
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: RIBGraphicsStateGuardian::clear
00167 //       Access: Public, Virtual
00168 //  Description: Clears all of the indicated buffers to their assigned
00169 //               colors.
00170 ////////////////////////////////////////////////////////////////////
00171 void RIBGraphicsStateGuardian::
00172 clear(const RenderBuffer &) {
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: RIBGraphicsStateGuardian::clear
00177 //       Access: Public, Virtual
00178 //  Description: Clears all of the indicated buffers to their assigned
00179 //               colors.
00180 ////////////////////////////////////////////////////////////////////
00181 void RIBGraphicsStateGuardian::
00182 clear(const RenderBuffer &, const DisplayRegion* ) {
00183 }
00184 
00185 ////////////////////////////////////////////////////////////////////
00186 //     Function: RIBGraphicsStateGuardian::prepare_display_region
00187 //       Access: Public
00188 //  Description: Prepare a display region for rendering (set up
00189 //               scissor region and viewport)
00190 ////////////////////////////////////////////////////////////////////
00191 void RIBGraphicsStateGuardian::
00192 prepare_display_region() {
00193 }
00194 
00195 
00196 ////////////////////////////////////////////////////////////////////
00197 //     Function: RIBGraphicsStateGuardian::render_frame
00198 //       Access: Public, Virtual
00199 //  Description: Renders an entire frame, including all display
00200 //               regions within the frame, and includes any necessary
00201 //               pre- and post-processing.
00202 ////////////////////////////////////////////////////////////////////
00203 void RIBGraphicsStateGuardian::
00204 render_frame(const AllTransitionsWrapper &initial_state) {
00205   _win->begin_frame();
00206   assert(_output != NULL);
00207   _indent_level += 2;
00208 
00209   int max_channel_index = _win->get_max_channel_index();
00210   for (int c = 0; c < max_channel_index; c++) {
00211     if (_win->is_channel_defined(c)) {
00212       GraphicsChannel *chan = _win->get_channel(c);
00213       if (chan->is_active()) {
00214         int num_layers = chan->get_num_layers();
00215         for (int l = 0; l < num_layers; l++) {
00216           GraphicsLayer *layer = chan->get_layer(l);
00217           if (layer->is_active()) {
00218             int num_drs = layer->get_num_drs();
00219             for (int d = 0; d < num_drs; d++) {
00220               DisplayRegion *dr = layer->get_dr(d);
00221               Camera *cam = dr->get_camera();
00222 
00223               // For each display region, render from the camera's view.
00224               if (dr->is_active() && cam != (Camera *)NULL &&
00225                   cam->is_active() && cam->get_scene() != (Node *)NULL) {
00226                 DisplayRegionStack old_dr = push_display_region(dr);
00227                 prepare_display_region();
00228                 render_scene(cam->get_scene(), cam, initial_state);
00229                 pop_display_region(old_dr);
00230               }
00231             }
00232           }
00233         }
00234       }
00235     }
00236   }
00237 
00238   _indent_level -= 2;
00239   _win->end_frame();
00240 
00241   reset_frame();
00242 }
00243 
00244 
00245 ////////////////////////////////////////////////////////////////////
00246 //     Function: RIBGraphicsStateGuardian::render_scene
00247 //       Access: Public, Virtual
00248 //  Description: Renders an entire scene, from the root node of the
00249 //               scene graph, as seen from a particular ProjectionNode
00250 //               and with a given initial state.  This initial state
00251 //               may be modified during rendering.
00252 ////////////////////////////////////////////////////////////////////
00253 void RIBGraphicsStateGuardian::
00254 render_scene(Node *root, ProjectionNode *projnode,
00255              const AllTransitionsWrapper &initial_state) {
00256   _current_root_node = root;
00257 
00258   render_subgraph(_render_traverser, root, projnode,
00259                   initial_state, AllTransitionsWrapper());
00260 }
00261 
00262 
00263 ////////////////////////////////////////////////////////////////////
00264 //     Function: RIBGraphicsStateGuardian::render_subgraph
00265 //       Access: Public, Virtual
00266 //  Description: Renders a subgraph of the scene graph as seen from a
00267 //               given projection node, and with a particular initial
00268 //               state.  This state may be modified by the render
00269 //               process.
00270 ////////////////////////////////////////////////////////////////////
00271 void RIBGraphicsStateGuardian::
00272 render_subgraph(RenderTraverser *traverser,
00273                 Node *subgraph, ProjectionNode *projnode,
00274                 const AllTransitionsWrapper &initial_state,
00275                 const AllTransitionsWrapper &net_trans) {
00276   ProjectionNode *old_projection_node = _current_projection_node;
00277   _current_projection_node = projnode;
00278 
00279   (*_output) << "\n";
00280 
00281   int width = _win->get_width();
00282   int height = _win->get_height();
00283   float frame_aspect = (float)width / (float)height;
00284 
00285   // BMRT, for one, doesn't seem like general matrices for the
00286   // projection matrix.  Therefore, we'll examine the projection type
00287   // and write out the high-level description of the projection if we
00288   // can, instead of just dumping a matrix.
00289 
00290   const Projection *projection = projnode->get_projection();
00291   if (projection->is_of_type(PerspectiveProjection::get_class_type())) {
00292     const PerspectiveProjection &pp =
00293       *DCAST(PerspectiveProjection, projection);
00294     const Frustumf &frustum = pp.get_frustum();
00295 
00296     float yfov, fnear, ffar;
00297     frustum.get_perspective_params(yfov, frame_aspect, fnear, ffar);
00298 
00299     switch (_coordinate_system) {
00300     case CS_zup_right:
00301       new_line() << "Scale [ 1 1 -1 ]\n";      // left-handed to right-handed
00302       new_line() << "Rotate [ -90 1 0 0 ]\n";  // y-up to z-up
00303       break;
00304 
00305     case CS_zup_left:
00306       new_line() << "Rotate [ -90 1 0 0 ]\n";  // y-up to z-up
00307       break;
00308 
00309     case CS_yup_right:
00310       new_line() << "Scale [ 1 1 -1 ]\n";      // left-handed to right-handed
00311       break;
00312 
00313     case CS_yup_left:
00314       break;
00315     };
00316 
00317     new_line() << "Orientation \"lh\"\n";
00318     new_line() << "Clipping " << fnear << " " << ffar << "\n";
00319     new_line() << "Projection \"perspective\" \"fov\" " << yfov << "\n";
00320 
00321   } else {
00322     // Hmm, some unknown projection type.  We'll have to just write
00323     // out the projection matrix and hope for the best.
00324     LMatrix4f proj_mat = projection->get_projection_mat(_coordinate_system);
00325     concat_transform(proj_mat);
00326 
00327     new_line() << "Orientation \"lh\"\n";
00328     new_line() << "Projection \"null\"\n";
00329   }
00330 
00331   new_line() << "Format " << width << " " << height << " "
00332              << (float)height * frame_aspect / (float)width << "\n";
00333   new_line() << "FrameAspectRatio " << frame_aspect << "\n";
00334 
00335   new_line() << "Sides 1\n";
00336   new_line() << "Color [ 1 1 1 ]\n";
00337 
00338   // Get the lights and stuff, while we're here in camera space.
00339   get_rib_stuff(_current_root_node, initial_state);
00340 
00341   // We infer the modelview matrix by doing a wrt on the projection
00342   // node.
00343   LMatrix4f modelview_mat;
00344   get_rel_mat(subgraph, _current_projection_node, modelview_mat);
00345   concat_transform(modelview_mat);
00346 
00347   /*
00348   // And then we must make sure the matrix transform is cleared from
00349   // the initial state.
00350   initial_state.clear_attribute(TransformTransition::get_class_type());
00351   */
00352 
00353   new_line() << "WorldBegin\n";
00354   _indent_level += 2;
00355 
00356   render_subgraph(traverser, subgraph, initial_state, net_trans);
00357 
00358   _indent_level -= 2;
00359   new_line() << "WorldEnd\n";
00360 }
00361 
00362 
00363 ////////////////////////////////////////////////////////////////////
00364 //     Function: RIBGraphicsStateGuardian::render_subgraph
00365 //       Access: Public, Virtual
00366 //  Description: Renders a subgraph of the scene graph as seen from the
00367 //               current projection node, and with a particular
00368 //               initial state.  This state may be modified during the
00369 //               render process.
00370 ////////////////////////////////////////////////////////////////////
00371 void RIBGraphicsStateGuardian::
00372 render_subgraph(RenderTraverser *traverser,
00373                 Node *subgraph,
00374                 const AllTransitionsWrapper &initial_state,
00375                 const AllTransitionsWrapper &net_trans) {
00376   nassertv(traverser != (RenderTraverser *)NULL);
00377   traverser->traverse(subgraph, initial_state, net_trans);
00378 }
00379 
00380 
00381 ////////////////////////////////////////////////////////////////////
00382 //     Function: RIBGraphicsStateGuardian::wants_normals
00383 //       Access: Public, Virtual
00384 //  Description:
00385 ////////////////////////////////////////////////////////////////////
00386 bool RIBGraphicsStateGuardian::
00387 wants_normals() const {
00388   return true;
00389 }
00390 
00391 ////////////////////////////////////////////////////////////////////
00392 //     Function: RIBGraphicsStateGuardian::wants_texcoords
00393 //       Access: Public, Virtual
00394 //  Description:
00395 ////////////////////////////////////////////////////////////////////
00396 bool RIBGraphicsStateGuardian::
00397 wants_texcoords() const {
00398   return true;
00399 }
00400 
00401 ////////////////////////////////////////////////////////////////////
00402 //     Function: RIBGraphicsStateGuardian::wants_colors
00403 //       Access: Public, Virtual
00404 //  Description:
00405 ////////////////////////////////////////////////////////////////////
00406 bool RIBGraphicsStateGuardian::
00407 wants_colors() const {
00408   // If we have scene graph color enabled, return false to indicate we
00409   // shouldn't bother issuing geometry color commands.
00410 
00411   const ColorTransition *catt;
00412   if (!get_transition_into(catt, _state, ColorTransition::get_class_type())) {
00413     // No scene graph color at all.
00414     return true;
00415   }
00416 
00417   // We should issue geometry colors only if the scene graph color is
00418   // off.
00419   return catt->is_off();
00420 }
00421 
00422 ////////////////////////////////////////////////////////////////////
00423 //     Function: RIBGraphicsStateGuardian::compute_distance_to
00424 //       Access: Public, Virtual
00425 //  Description: This function may only be called during a render
00426 //               traversal; it will compute the distance to the
00427 //               indicated point, assumed to be in modelview
00428 //               coordinates, from the camera plane.
00429 ////////////////////////////////////////////////////////////////////
00430 float RIBGraphicsStateGuardian::
00431 compute_distance_to(const LPoint3f &point) const {
00432   // In the case of a RIBGraphicsStateGuardian, we know the modelview
00433   // matrix does not include the camera transform, so we should apply
00434   // that now.  But for now we'll punt, since no one cares anyway.
00435 
00436   return point[1];
00437 }
00438 
00439 ////////////////////////////////////////////////////////////////////
00440 //     Function: RIBGraphicsStateGuardian::draw_point
00441 //       Access: Public, Virtual
00442 //  Description:
00443 ////////////////////////////////////////////////////////////////////
00444 void RIBGraphicsStateGuardian::
00445 draw_point(const GeomPoint *) {
00446 }
00447 
00448 ////////////////////////////////////////////////////////////////////
00449 //     Function: RIBGraphicsStateGuardian::draw_line
00450 //       Access: Public, Virtual
00451 //  Description:
00452 ////////////////////////////////////////////////////////////////////
00453 void RIBGraphicsStateGuardian::
00454 draw_line(const GeomLine *) {
00455 }
00456 
00457 ////////////////////////////////////////////////////////////////////
00458 //     Function: RIBGraphicsStateGuardian::draw_sprite
00459 //       Access: Public, Virtual
00460 //  Description:
00461 ////////////////////////////////////////////////////////////////////
00462 void RIBGraphicsStateGuardian::
00463 draw_sprite(const GeomSprite *) {
00464 }
00465 
00466 ////////////////////////////////////////////////////////////////////
00467 //     Function: RIBGraphicsStateGuardian::draw_polygon
00468 //       Access: Public, Virtual
00469 //  Description:
00470 ////////////////////////////////////////////////////////////////////
00471 void RIBGraphicsStateGuardian::
00472 draw_polygon(const GeomPolygon *geom) {
00473   draw_simple_poly(geom);
00474 }
00475 
00476 ////////////////////////////////////////////////////////////////////
00477 //     Function: RIBGraphicsStateGuardian::draw_tri
00478 //       Access: Public, Virtual
00479 //  Description:
00480 ////////////////////////////////////////////////////////////////////
00481 void RIBGraphicsStateGuardian::
00482 draw_tri(const GeomTri *geom) {
00483   draw_simple_poly(geom);
00484 }
00485 
00486 ////////////////////////////////////////////////////////////////////
00487 //     Function: RIBGraphicsStateGuardian::draw_quad
00488 //       Access: Public, Virtual
00489 //  Description:
00490 ////////////////////////////////////////////////////////////////////
00491 void RIBGraphicsStateGuardian::
00492 draw_quad(const GeomQuad *geom) {
00493   draw_simple_poly(geom);
00494 }
00495 
00496 ////////////////////////////////////////////////////////////////////
00497 //     Function: RIBGraphicsStateGuardian::draw_tristrip
00498 //       Access: Public, Virtual
00499 //  Description:
00500 ////////////////////////////////////////////////////////////////////
00501 void RIBGraphicsStateGuardian::
00502 draw_tristrip(const GeomTristrip *geom) {
00503   Geom *temp = geom->explode();
00504   draw_simple_poly(temp);
00505   delete temp;
00506 }
00507 
00508 ////////////////////////////////////////////////////////////////////
00509 //     Function: RIBGraphicsStateGuardian::draw_trifan
00510 //       Access: Public, Virtual
00511 //  Description:
00512 ////////////////////////////////////////////////////////////////////
00513 void RIBGraphicsStateGuardian::
00514 draw_trifan(const GeomTrifan *geom) {
00515   Geom *temp = geom->explode();
00516   draw_simple_poly(temp);
00517   delete temp;
00518 }
00519 
00520 ////////////////////////////////////////////////////////////////////
00521 //     Function: RIBGraphicsStateGuardian::draw_sphere
00522 //       Access: Public, Virtual
00523 //  Description:
00524 ////////////////////////////////////////////////////////////////////
00525 void RIBGraphicsStateGuardian::
00526 draw_sphere(const GeomSphere *) {
00527 }
00528 
00529 
00530 ////////////////////////////////////////////////////////////////////
00531 //     Function: RIBGraphicsStateGuardian::prepare_texture
00532 //       Access: Public, Virtual
00533 //  Description:
00534 ////////////////////////////////////////////////////////////////////
00535 TextureContext *RIBGraphicsStateGuardian::
00536 prepare_texture(Texture *tex) {
00537   TextureContext *tc = new TextureContext(tex);
00538 
00539   bool inserted = mark_prepared_texture(tc);
00540 
00541   // If this assertion fails, the same texture was prepared twice,
00542   // which shouldn't be possible, since the texture itself should
00543   // detect this.
00544   assert(inserted);
00545 
00546   return tc;
00547 }
00548 
00549 ////////////////////////////////////////////////////////////////////
00550 //     Function: RIBGraphicsStateGuardian::apply_texture
00551 //       Access: Public, Virtual
00552 //  Description:
00553 ////////////////////////////////////////////////////////////////////
00554 void RIBGraphicsStateGuardian::
00555 apply_texture(TextureContext *) {
00556 }
00557 
00558 ////////////////////////////////////////////////////////////////////
00559 //     Function: RIBGraphicsStateGuardian::release_texture
00560 //       Access: Public, Virtual
00561 //  Description:
00562 ////////////////////////////////////////////////////////////////////
00563 void RIBGraphicsStateGuardian::
00564 release_texture(TextureContext *tc) {
00565   Texture *tex = tc->_texture;
00566 
00567   bool erased = unmark_prepared_texture(tc);
00568 
00569   // If this assertion fails, a texture was released that hadn't been
00570   // prepared (or a texture was released twice).
00571   assert(erased);
00572 
00573   tex->clear_gsg(this);
00574 
00575   delete tc;
00576 }
00577 
00578 ////////////////////////////////////////////////////////////////////
00579 //     Function: RIBGraphicsStateGuardian::copy_texture
00580 //       Access: Public, Virtual
00581 //  Description:
00582 ////////////////////////////////////////////////////////////////////
00583 void RIBGraphicsStateGuardian::
00584 copy_texture(TextureContext *, const DisplayRegion *) {
00585 }
00586 
00587 ////////////////////////////////////////////////////////////////////
00588 //     Function: RIBGraphicsStateGuardian::copy_texture
00589 //       Access: Public, Virtual
00590 //  Description:
00591 ////////////////////////////////////////////////////////////////////
00592 void RIBGraphicsStateGuardian::
00593 copy_texture(TextureContext *, const DisplayRegion *, const RenderBuffer &) {
00594 }
00595 
00596 ////////////////////////////////////////////////////////////////////
00597 //     Function: RIBGraphicsStateGuardian::draw_texture
00598 //       Access: Public, Virtual
00599 //  Description:
00600 ////////////////////////////////////////////////////////////////////
00601 void RIBGraphicsStateGuardian::
00602 draw_texture(TextureContext *, const DisplayRegion *) {
00603 }
00604 
00605 ////////////////////////////////////////////////////////////////////
00606 //     Function: RIBGraphicsStateGuardian::draw_texture
00607 //       Access: Public, Virtual
00608 //  Description:
00609 ////////////////////////////////////////////////////////////////////
00610 void RIBGraphicsStateGuardian::
00611 draw_texture(TextureContext *, const DisplayRegion *, const RenderBuffer &) {
00612 }
00613 
00614 ////////////////////////////////////////////////////////////////////
00615 //     Function: RIBGraphicsStateGuardian::copy_pixel_buffer
00616 //       Access: Public, Virtual
00617 //  Description:
00618 ////////////////////////////////////////////////////////////////////
00619 void RIBGraphicsStateGuardian::
00620 copy_pixel_buffer(PixelBuffer *, const DisplayRegion *) {
00621 }
00622 
00623 ////////////////////////////////////////////////////////////////////
00624 //     Function: RIBGraphicsStateGuardian::copy_pixel_buffer
00625 //       Access: Public, Virtual
00626 //  Description:
00627 ////////////////////////////////////////////////////////////////////
00628 void RIBGraphicsStateGuardian::
00629 copy_pixel_buffer(PixelBuffer *, const DisplayRegion *, const RenderBuffer &) {
00630 }
00631 
00632 
00633 ////////////////////////////////////////////////////////////////////
00634 //     Function: RIBGraphicsStateGuardian::draw_pixel_buffer
00635 //       Access: Public, Virtual
00636 //  Description:
00637 ////////////////////////////////////////////////////////////////////
00638 void RIBGraphicsStateGuardian::
00639 draw_pixel_buffer(PixelBuffer *, const DisplayRegion *,
00640         const NodeTransitions &) {
00641 }
00642 
00643 ////////////////////////////////////////////////////////////////////
00644 //     Function: RIBGraphicsStateGuardian::draw_pixel_buffer
00645 //       Access: Public, Virtual
00646 //  Description:
00647 ////////////////////////////////////////////////////////////////////
00648 void RIBGraphicsStateGuardian::
00649 draw_pixel_buffer(PixelBuffer *, const DisplayRegion *, const RenderBuffer &,
00650         const NodeTransitions &) {
00651 }
00652 
00653 ////////////////////////////////////////////////////////////////////
00654 //     Function: RIBGraphicsStateGuardian::issue_transform
00655 //       Access: Public, Virtual
00656 //  Description:
00657 ////////////////////////////////////////////////////////////////////
00658 void RIBGraphicsStateGuardian::
00659 issue_transform(const TransformTransition *attrib) {
00660   reset_transform(attrib->get_matrix());
00661 }
00662 
00663 
00664 ////////////////////////////////////////////////////////////////////
00665 //     Function: RIBGraphicsStateGuardian::issue_color
00666 //       Access: Public, Virtual
00667 //  Description:
00668 ////////////////////////////////////////////////////////////////////
00669 void RIBGraphicsStateGuardian::
00670 issue_color(const ColorTransition *attrib) {
00671   if (attrib->is_on() && attrib->is_real()) {
00672     const Colorf c = attrib->get_color();
00673     set_color(RGBColorf(c[0], c[1], c[2]));
00674   }
00675 }
00676 
00677 ////////////////////////////////////////////////////////////////////
00678 //     Function: RIBGraphicsStateGuardian::issue_texture
00679 //       Access: Public, Virtual
00680 //  Description:
00681 ////////////////////////////////////////////////////////////////////
00682 void RIBGraphicsStateGuardian::
00683 issue_texture(const TextureTransition *attrib) {
00684   if (attrib->is_off()) {
00685     // If no textures are enabled, we can use the nontextured shader.
00686     new_line()
00687       << "Surface \"plastic\"\n";
00688 
00689   } else {
00690     // If we have a texture enabled, just use the normal
00691     // paintedplastic shader.
00692 
00693     Texture *tex = attrib->get_texture();
00694     nassertv(tex != (Texture *)NULL);
00695     const Filename &rib_name = _texture_names[tex];
00696 
00697     // We should have gotten all the texture names already in the
00698     // get_rib_stuff() call.  If this name is empty, we somehow
00699     // missed it!
00700     nassertv(!rib_name.empty());
00701 
00702     new_line()
00703       << "Surface \"paintedplastic\" \"texturename\" \""
00704       << rib_name << "\"\n";
00705   }
00706 }
00707 
00708 ////////////////////////////////////////////////////////////////////
00709 //     Function: RIBGraphicsStateGuardian::issue_light
00710 //       Access: Public, Virtual
00711 //  Description:
00712 ////////////////////////////////////////////////////////////////////
00713 void RIBGraphicsStateGuardian::
00714 issue_light(const LightTransition *attrib) {
00715   nassertv(attrib->get_properties_is_on());
00716   int num_enabled = attrib->size();
00717   if (num_enabled == 0) {
00718     // If no lights are enabled, lighting is off.  Turn off all lights
00719     // except the default one.
00720 
00721     // (if the default light is already on, we'll assume everything
00722     // else is already off and won't bother to run the list.)
00723     if (!_enabled_lights[0]) {
00724       for (int i = 1; i < _enabled_lights.size(); i++) {
00725         if (_enabled_lights[i]) {
00726           new_line() << "Illuminate " << i << " 0\n";
00727           _enabled_lights[i] = false;
00728         }
00729       }
00730 
00731       // And turn on the default light, which illuminates the scene in
00732       // the absence of lighting.
00733       new_line() << "Illuminate 0 1\n";
00734       _enabled_lights[0] = true;
00735     }
00736 
00737   } else {
00738     // If some lights are enabled, we'll turn off the ones that were
00739     // enabled from before, and turn on the ones we need.
00740 
00741     LightTransition::const_iterator li;
00742     for (li = attrib->begin(); li != attrib->end(); ++li) {
00743       Light *light = (*li);
00744       LightIDs::const_iterator ii = _light_ids.find(light);
00745       assert(ii != _light_ids.end());
00746       int id = (*ii).second;
00747 
00748       if (!_enabled_lights[id]) {
00749         new_line() << "Illuminate " << id << " 1\n";
00750       }
00751 
00752       // We'll temporarily set the enabled flag to false, even
00753       // though we've just activated the light.  This is so we can
00754       // later identify the lights we need to turn off.
00755       _enabled_lights[id] = false;
00756     }
00757 
00758     // Now turn off all the lights that are still marked "on".
00759     for (int i = 0; i < _enabled_lights.size(); i++) {
00760       if (_enabled_lights[i]) {
00761         new_line() << "Illuminate " << i << " 0\n";
00762         _enabled_lights[i] = false;
00763       }
00764     }
00765 
00766     // Finally, mark as "on" all the ones that we just enabled.
00767     for (li = attrib->begin(); li != attrib->end(); ++li) {
00768       Light *light = (*li);
00769       int id = _light_ids[light];
00770       _enabled_lights[id] = true;
00771     }
00772   }
00773 }
00774 
00775 ////////////////////////////////////////////////////////////////////
00776 //     Function: RIBGraphicsStateGuardian::set_texture_directory
00777 //       Access: Public
00778 //  Description: Sets the name of the directory into which texture
00779 //               maps are copied to be available to the RIB file.
00780 ////////////////////////////////////////////////////////////////////
00781 void RIBGraphicsStateGuardian::
00782 set_texture_directory(const string &directory) {
00783   _texture_directory = directory;
00784 }
00785 
00786 ////////////////////////////////////////////////////////////////////
00787 //     Function: RIBGraphicsStateGuardian::get_texture_directory
00788 //       Access: Public
00789 //  Description: Returns the name of the directory into which texture
00790 //               maps are copied to be available to the RIB file.
00791 ////////////////////////////////////////////////////////////////////
00792 string RIBGraphicsStateGuardian::
00793 get_texture_directory() const {
00794   return _texture_directory;
00795 }
00796 
00797 ////////////////////////////////////////////////////////////////////
00798 //     Function: RIBGraphicsStateGuardian::set_texture_extension
00799 //       Access: Public
00800 //  Description: Specifies the filename extension that texture map
00801 //               files are given when they are copied into the
00802 //               directory for RIB files.  This might also imply an
00803 //               image type.  The default is "tiff", which implies
00804 //               TIFF files.
00805 ////////////////////////////////////////////////////////////////////
00806 void RIBGraphicsStateGuardian::
00807 set_texture_extension(const string &extension) {
00808   _texture_extension = extension;
00809 }
00810 
00811 ////////////////////////////////////////////////////////////////////
00812 //     Function: RIBGraphicsStateGuardian::get_texture_extension
00813 //       Access: Public
00814 //  Description: Returns the filename extension that texture map
00815 //               files are given when they are copied into the
00816 //               directory for RIB files.
00817 ////////////////////////////////////////////////////////////////////
00818 string RIBGraphicsStateGuardian::
00819 get_texture_extension() const {
00820   return _texture_extension;
00821 }
00822 
00823 
00824 ////////////////////////////////////////////////////////////////////
00825 //     Function: RIBGraphicsStateGuardian::save_frame_buffer
00826 //       Access: Public
00827 //  Description: Saves the indicated planes of the frame buffer
00828 //               (within the indicated display region) and returns it
00829 //               in some meaningful form that can be restored later
00830 //               via restore_frame_buffer().  This is a helper
00831 //               function for push_frame_buffer() and
00832 //               pop_frame_buffer().
00833 ////////////////////////////////////////////////////////////////////
00834 PT(SavedFrameBuffer) RIBGraphicsStateGuardian::
00835 save_frame_buffer(const RenderBuffer &buffer,
00836                   CPT(DisplayRegion) dr) {
00837   return new SavedFrameBuffer(buffer, dr);
00838 }
00839 
00840 ////////////////////////////////////////////////////////////////////
00841 //     Function: RIBGraphicsStateGuardian::restore_frame_buffer
00842 //       Access: Public
00843 //  Description: Restores the frame buffer that was previously saved.
00844 ////////////////////////////////////////////////////////////////////
00845 void RIBGraphicsStateGuardian::
00846 restore_frame_buffer(SavedFrameBuffer *) {
00847 }
00848 
00849 ////////////////////////////////////////////////////////////////////
00850 //     Function: RIBGraphicsStateGuardian::set_color
00851 //       Access: Protected
00852 //  Description: Issues the sequence to change the node color to that
00853 //               indicated.
00854 ////////////////////////////////////////////////////////////////////
00855 void RIBGraphicsStateGuardian::
00856 set_color(const RGBColorf &color) {
00857   if (_current_color != color) {
00858     new_line() << "Color [ " << color << " ]\n";
00859     _current_color = color;
00860   }
00861 }
00862 
00863 
00864 ////////////////////////////////////////////////////////////////////
00865 //     Function: RIBGraphicsStateGuardian::get_rib_stuff
00866 //       Access: Protected
00867 //  Description: Traverses the scene graph to identify any textures
00868 //               or lights, or anything that we need to define up
00869 //               front in RIB.
00870 ////////////////////////////////////////////////////////////////////
00871 void RIBGraphicsStateGuardian::
00872 get_rib_stuff(Node *root, const AllTransitionsWrapper &initial_state) {
00873   RibStuffTraverser trav(this);
00874   df_traverse(root, trav, initial_state, NullLevelState(),
00875               RenderRelation::get_class_type());
00876 }
00877 
00878 
00879 ////////////////////////////////////////////////////////////////////
00880 //     Function: RIBGraphicsStateGuardian::define_texture
00881 //       Access: Protected
00882 //  Description: Called by the RibStuffTraverser (initiated above),
00883 //               this defines a single texture object in the RIB file
00884 //               if it has not already been defined.
00885 ////////////////////////////////////////////////////////////////////
00886 void RIBGraphicsStateGuardian::
00887 define_texture(const Texture *tex) {
00888   Filename &rib_name = _texture_names[tex];
00889 
00890   if (rib_name.empty()) {
00891     Filename image_filename = tex->get_name();
00892     image_filename.set_dirname(_texture_directory);
00893     image_filename.set_extension(_texture_extension);
00894     tex->write(image_filename);
00895 
00896     rib_name = image_filename;
00897     rib_name.set_extension("tx");
00898 
00899     new_line() << "MakeTexture \"" << image_filename << "\"\n";
00900     new_line(12) << "\"" << rib_name << "\"";
00901 
00902     if (tex->get_wrapu() == Texture::WM_clamp) {
00903       (*_output) << " \"clamp\"";
00904     } else {
00905       (*_output) << " \"periodic\"";
00906     }
00907 
00908     if (tex->get_wrapv() == Texture::WM_clamp) {
00909       (*_output) << " \"clamp\"";
00910     } else {
00911       (*_output) << " \"periodic\"";
00912     }
00913 
00914     (*_output) << " \"box\" 1 1\n";
00915   }
00916 }
00917 
00918 ////////////////////////////////////////////////////////////////////
00919 //     Function: RIBGraphicsStateGuardian::define_light
00920 //       Access: Protected
00921 //  Description: Called by the RibStuffTraverser (initiated above),
00922 //               this defines a single light object in the RIB file
00923 //               if it has not already been defined.
00924 ////////////////////////////////////////////////////////////////////
00925 void RIBGraphicsStateGuardian::
00926 define_light(const Light *light) {
00927   LightIDs::const_iterator li = _light_ids.find(light);
00928   if (li == _light_ids.end()) {
00929     // This is the first time this light has been encountered; define
00930     // it.
00931 
00932     // Create a new ID number.
00933     int id = _light_ids.size() + 1;
00934     _light_ids[light] = id;
00935     assert(id == _enabled_lights.size());
00936     _enabled_lights.push_back(false);
00937 
00938     if (light->get_light_type() == PointLight::get_class_type()) {
00939       const PointLight *plight = (const PointLight *)light;
00940       new_line() << "LightSource \"pointlight\" " << id;
00941       write_light_color(plight->get_color());
00942       write_light_from(plight);
00943       (*_output) << "\n";
00944 
00945     } else if (light->get_light_type() == DirectionalLight::get_class_type()) {
00946       const DirectionalLight *dlight = (const DirectionalLight *)light;
00947       new_line() << "LightSource \"distantlight\" " << id;
00948       write_light_color(dlight->get_color());
00949       write_light_from(dlight);
00950       write_light_to(dlight);
00951       (*_output) << "\n";
00952 
00953     } else if (light->get_light_type() == Spotlight::get_class_type()) {
00954       const Spotlight *slight = (const Spotlight *)light;
00955       new_line() << "LightSource \"spotlight\" " << id;
00956       write_light_color(slight->get_color());
00957       write_light_from(slight);
00958       write_light_to(slight);
00959       (*_output)
00960         << " \"coneangle\" " << deg_2_rad(slight->get_cutoff_angle())
00961         << "\n";
00962 
00963     } else if (light->get_light_type() == AmbientLight::get_class_type()) {
00964       const AmbientLight *alight = (const AmbientLight *)light;
00965       new_line() << "LightSource \"ambientlight\" " << id;
00966       write_light_color(alight->get_color());
00967       (*_output) << "\n";
00968 
00969     } else {
00970       cerr << "Ignoring unknown light type " << light->get_light_type() << "\n";
00971     }
00972   }
00973 }
00974 
00975 ////////////////////////////////////////////////////////////////////
00976 //     Function: RIBGraphicsStateGuardian::write_light_color
00977 //       Access: Protected
00978 //  Description: Called by define_light() to write out a single
00979 //               light's color and intensity values.
00980 ////////////////////////////////////////////////////////////////////
00981 void RIBGraphicsStateGuardian::
00982 write_light_color(const Colorf &color) const {
00983   RGBColorf output_color;
00984   float intensity;
00985 
00986   get_color_and_intensity((const RGBColorf &)color, output_color, intensity);
00987   (*_output) << " \"lightcolor\" [ " << output_color << " ] \"intensity\" "
00988              << intensity;
00989 }
00990 
00991 ////////////////////////////////////////////////////////////////////
00992 //     Function: RIBGraphicsStateGuardian::write_light_from
00993 //       Access: Protected
00994 //  Description: Called by define_light() to write out a single
00995 //               light's position.
00996 ////////////////////////////////////////////////////////////////////
00997 void RIBGraphicsStateGuardian::
00998 write_light_from(const Node *light) const {
00999   LPoint3f pos = get_rel_pos(light, _current_projection_node);
01000 
01001   (*_output) << " \"from\" [ " << pos << " ]";
01002 }
01003 
01004 ////////////////////////////////////////////////////////////////////
01005 //     Function: RIBGraphicsStateGuardian::write_light_to
01006 //       Access: Protected
01007 //  Description: Called by define_light() to write out a single
01008 //               light's direction.
01009 ////////////////////////////////////////////////////////////////////
01010 void RIBGraphicsStateGuardian::
01011 write_light_to(const Node *light) const {
01012   LPoint3f pos = get_rel_pos(light, _current_projection_node);
01013   LVector3f forward = get_rel_forward(light, _current_projection_node);
01014 
01015   (*_output) << " \"to\" [ " << pos + forward << " ]";
01016 }
01017 
01018 
01019 ////////////////////////////////////////////////////////////////////
01020 //     Function: RIBGraphicsStateGuardian::new_line
01021 //       Access: Protected
01022 //  Description: Beins a new line of output at the current indenting
01023 //               level.  (Does not actually issue the newline
01024 //               character, however).
01025 ////////////////////////////////////////////////////////////////////
01026 ostream &RIBGraphicsStateGuardian::
01027 new_line(int extra_indent) const {
01028   return indent(*_output, _indent_level + extra_indent);
01029 }
01030 
01031 ////////////////////////////////////////////////////////////////////
01032 //     Function: RIBGraphicsStateGuardian::reset_transform
01033 //       Access: Protected
01034 //  Description: Outputs an RiTransform command with the given
01035 //               transformation matrix, which resets the current
01036 //               transformation to that specified.
01037 ////////////////////////////////////////////////////////////////////
01038 void RIBGraphicsStateGuardian::
01039 reset_transform(const LMatrix4f &mat) const {
01040   new_line() << "Transform [ " << mat(0,0) << " " << mat(0,1) << " "
01041              << mat(0,2) << " " << mat(0,3) << "\n";
01042   new_line(12) << mat(1,0) << " " << mat(1,1) << " "
01043                << mat(1,2) << " " << mat(1,3) << "\n";
01044   new_line(12) << mat(2,0) << " " << mat(2,1) << " "
01045                << mat(2,2) << " " << mat(2,3) << "\n";
01046   new_line(12) << mat(3,0) << " " << mat(3,1) << " "
01047                << mat(3,2) << " " << mat(3,3) << " ]\n";
01048 }
01049 
01050 ////////////////////////////////////////////////////////////////////
01051 //     Function: RIBGraphicsStateGuardian::concat_transform
01052 //       Access: Protected
01053 //  Description: Outputs an RiTransform command with the given
01054 //               transformation matrix, which composes the specified
01055 //               matrix with the current transformation.
01056 ////////////////////////////////////////////////////////////////////
01057 void RIBGraphicsStateGuardian::
01058 concat_transform(const LMatrix4f &mat) const {
01059   new_line() << "ConcatTransform [ " << mat(0,0) << " " << mat(0,1) << " "
01060              << mat(0,2) << " " << mat(0,3) << "\n";
01061   new_line(18) << mat(1,0) << " " << mat(1,1) << " "
01062                << mat(1,2) << " " << mat(1,3) << "\n";
01063   new_line(18) << mat(2,0) << " " << mat(2,1) << " "
01064                << mat(2,2) << " " << mat(2,3) << "\n";
01065   new_line(18) << mat(3,0) << " " << mat(3,1) << " "
01066                << mat(3,2) << " " << mat(3,3) << " ]\n";
01067 }
01068 
01069 
01070 ////////////////////////////////////////////////////////////////////
01071 //     Function: RIBGraphicsStateGuardian::draw_simple_poly
01072 //       Access: Protected
01073 //  Description: Draws a GeomPolygon, GeomTri, or GeomQuad object.
01074 //               This consists of one or more unconnected polygons.
01075 ////////////////////////////////////////////////////////////////////
01076 void RIBGraphicsStateGuardian::
01077 draw_simple_poly(const Geom *geom) {
01078   if (geom == NULL) {
01079     return;
01080   }
01081 
01082   int nprims = geom->get_num_prims();
01083   Geom::VertexIterator vi = geom->make_vertex_iterator();
01084   Geom::NormalIterator ni = geom->make_normal_iterator();
01085   Geom::TexCoordIterator ti = geom->make_texcoord_iterator();
01086   Geom::ColorIterator ci = geom->make_color_iterator();
01087 
01088   GeomIssuer issuer(geom, this,
01089                     issue_vertex_rib,
01090                     issue_normal_rib,
01091                     issue_texcoord_rib,
01092                     issue_color_rib);
01093 
01094   for (int i = 0; i < nprims; i++) {
01095     // First, for each primitive, we build up the various polygon
01096     // attributes in our global arrays.
01097 
01098     // If the colors or normals have overall binding, we'll need to
01099     // repeat it for each primitive.  Thus, we need to reset the
01100     // iterator for each primitive.
01101     if (geom->get_binding(G_COLOR) == G_OVERALL) {
01102       ci = geom->make_color_iterator();
01103     }
01104     if (geom->get_binding(G_NORMAL) == G_OVERALL) {
01105       ni = geom->make_normal_iterator();
01106     }
01107 
01108     // Draw overall
01109     issuer.issue_color(G_OVERALL, ci);
01110     issuer.issue_normal(G_OVERALL, ni);
01111 
01112     // Draw per primitive
01113     issuer.issue_color(G_PER_PRIM, ci);
01114     issuer.issue_normal(G_PER_PRIM, ni);
01115 
01116     for (int j = 0; j < geom->get_length(i); j++) {
01117       // Draw per vertex
01118       issuer.issue_color(G_PER_VERTEX, ci);
01119       issuer.issue_normal(G_PER_VERTEX, ni);
01120       issuer.issue_texcoord(G_PER_VERTEX, ti);
01121       issuer.issue_vertex(G_PER_VERTEX, vi);
01122     }
01123 
01124     write_polygon(geom->get_length(i));
01125   }
01126 }
01127 
01128 
01129 ////////////////////////////////////////////////////////////////////
01130 //     Function: RIBGraphicsStateGuardian::write_polygon
01131 //       Access: Protected
01132 //  Description: Writes out the RIB command to draw the polygon
01133 //               described by the global rib_* arrays.
01134 ////////////////////////////////////////////////////////////////////
01135 void RIBGraphicsStateGuardian::
01136 write_polygon(int num_verts) {
01137   if (num_verts < 3) {
01138     return;
01139   }
01140 
01141   assert(rib_vertices.size() == num_verts);
01142 
01143   if (rib_colors.size() == 1) {
01144     // This polygon has a flat color; just issue the color.
01145     set_color(rib_colors[0]);
01146     rib_colors.clear();
01147   }
01148 
01149 
01150   // We reverse the order of the vertices when we write then out,
01151   // because RIB has a clockwise-ordering convention.
01152 
01153   // Vertices are always per-vertex.
01154   write_long_list(*_output, _indent_level,
01155                   rib_vertices.rbegin(), rib_vertices.rend(),
01156                   "Polygon \"P\" ", "            ", 72);
01157 
01158   if (rib_normals.size() == 1) {
01159     // A single polygon normal.
01160     write_long_list(*_output, _indent_level,
01161                     rib_normals.rbegin(), rib_normals.rend(),
01162                     "       \"Np\" ", "            ", 72);
01163   } else if (!rib_normals.empty()) {
01164     // Multiple per-vertex normals.
01165     assert(rib_normals.size() == num_verts);
01166     write_long_list(*_output, _indent_level,
01167                     rib_normals.rbegin(), rib_normals.rend(),
01168                     "        \"N\" ", "            ", 72);
01169   }
01170 
01171   if (!rib_texcoords.empty()) {
01172     // Per-vertex texcoords.
01173     assert(rib_texcoords.size() == num_verts);
01174     write_long_list(*_output, _indent_level,
01175                     rib_texcoords.rbegin(), rib_texcoords.rend(),
01176                     "       \"st\" ", "            ", 72);
01177   }
01178 
01179   if (!rib_colors.empty()) {
01180     assert(rib_colors.size() == num_verts);
01181 
01182     write_long_list(*_output, _indent_level,
01183                     rib_colors.rbegin(), rib_colors.rend(),
01184                     "       \"Cs\" ", "            ", 72);
01185   }
01186 
01187   // Clear the arrays for the next primitive.
01188   rib_vertices.clear();
01189   rib_normals.clear();
01190   rib_texcoords.clear();
01191   rib_colors.clear();
01192 }
01193 
01194 
01195 ////////////////////////////////////////////////////////////////////
01196 //     Function: RIBGraphicsStateGuardian::get_color_and_intensity
01197 //       Access: Protected, Static
01198 //  Description: Given a three-component color value, extracts it into
01199 //               a normalized three-component color with each
01200 //               component in the range [0..1], and a separate
01201 //               intensity value.
01202 ////////////////////////////////////////////////////////////////////
01203 void RIBGraphicsStateGuardian::
01204 get_color_and_intensity(const RGBColorf &input,
01205                         RGBColorf &output,
01206                         float &intensity) {
01207   intensity = max(max(input[0], input[1]), input[2]);
01208   if (intensity == 0.0) {
01209     output.set(1.0, 1.0, 1.0);
01210   } else {
01211     output = input / intensity;
01212   }
01213 }
01214 
01215 // type and factory stuff
01216 
01217 GraphicsStateGuardian *RIBGraphicsStateGuardian::
01218 make_RIBGraphicsStateGuardian(const FactoryParams &params) {
01219   GraphicsStateGuardian::GsgWindow *win_param;
01220   if (!get_param_into(win_param, params)) {
01221     ribgsg_cat.error()
01222       << "No window specified for gsg creation!" << endl;
01223     return NULL;
01224   }
01225 
01226   GraphicsWindow *win = win_param->get_window();
01227   return new RIBGraphicsStateGuardian(win);
01228 }
01229 
01230 TypeHandle RIBGraphicsStateGuardian::get_type(void) const {
01231   return get_class_type();
01232 }
01233 
01234 TypeHandle RIBGraphicsStateGuardian::get_class_type(void) {
01235   return _type_handle;
01236 }
01237 
01238 void RIBGraphicsStateGuardian::init_type(void) {
01239   GraphicsStateGuardian::init_type();
01240   register_type(_type_handle, "RIBGraphicsStateGuardian",
01241                 GraphicsStateGuardian::get_class_type());
01242 }

Generated on Fri May 2 00:43:55 2003 for Panda by doxygen1.3