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

panda/src/ribdisplay/ribGraphicsWindow.cxx

Go to the documentation of this file.
00001 // Filename: ribGraphicsWindow.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 "ribGraphicsWindow.h"
00020 #include "ribGraphicsPipe.h"
00021 #include "config_ribdisplay.h"
00022 
00023 #include <ribGraphicsStateGuardian.h>
00024 #include <ctype.h>
00025 
00026 TypeHandle RIBGraphicsWindow::_type_handle;
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: RIBGraphicsWindow::Constructor
00030 //       Access: Public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 RIBGraphicsWindow::
00034 RIBGraphicsWindow(GraphicsPipe *pipe) : GraphicsWindow(pipe) {
00035   setup_window(pipe);
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: RIBGraphicsWindow::Constructor
00040 //       Access: Public
00041 //  Description:
00042 ////////////////////////////////////////////////////////////////////
00043 RIBGraphicsWindow::
00044 RIBGraphicsWindow(GraphicsPipe *pipe,
00045                   const GraphicsWindow::Properties &props) :
00046   GraphicsWindow(pipe, props)
00047 {
00048   setup_window(pipe);
00049 }
00050 
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: RIBGraphicsWindow::Destructor
00054 //       Access: Public
00055 //  Description:
00056 ////////////////////////////////////////////////////////////////////
00057 RIBGraphicsWindow::
00058 ~RIBGraphicsWindow(void) {
00059   flush_file();
00060 }
00061 
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: RIBGraphicsWindow::flush_file
00065 //       Access: Public
00066 //  Description: Finishes the RIB file currently being output and
00067 //               closes it.
00068 ////////////////////////////////////////////////////////////////////
00069 void RIBGraphicsWindow::
00070 flush_file() {
00071   if (_file_begun) {
00072     end_file();
00073   }
00074 }
00075 
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: RIBGraphicsWindow::begin_frame
00079 //       Access: Public, Virtual
00080 //  Description: Prepares to write a new frame to the RIB file.
00081 ////////////////////////////////////////////////////////////////////
00082 void RIBGraphicsWindow::
00083 begin_frame() {
00084   if (!_file_begun) {
00085     // Open a new RIB file if we need to.
00086     begin_file();
00087   }
00088 
00089   _file << "FrameBegin " << _frame_number << "\n";
00090 
00091   if (image_per_frame()) {
00092     // If we're writing out an image file for each frame, specify it
00093     // here, inside the Frame control group.
00094     _file << "  Display \"" << get_image_filename()
00095           << "\" \"file\" \"rgba\"\n";
00096   }
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: RIBGraphicsWindow::end_frame
00101 //       Access: Public, Virtual
00102 //  Description: Finalizes a frame.
00103 ////////////////////////////////////////////////////////////////////
00104 void RIBGraphicsWindow::
00105 end_frame() {
00106   _file << "FrameEnd\n";
00107 
00108   if (rib_per_frame()) {
00109     // If we're outputting a RIB file for each frame, close the file now.
00110     end_file();
00111   }
00112 
00113   GraphicsWindow::end_frame();
00114 }
00115 
00116 ////////////////////////////////////////////////////////////////////
00117 //     Function: RIBGraphicsWindow::setup_window
00118 //       Access: Protected
00119 //  Description: Called by the constructor to initialize whatever
00120 //               internal structures are necessary, given the
00121 //               indicated pipe and requested properties.
00122 ////////////////////////////////////////////////////////////////////
00123 void RIBGraphicsWindow::
00124 setup_window(GraphicsPipe *pipe) {
00125   RIBGraphicsPipe *rp = DCAST(RIBGraphicsPipe, pipe);
00126 
00127   _file_begun = false;
00128 
00129   set_rib_filename_template(rp->get_file_name());
00130   set_image_filename_template("");
00131 
00132   make_gsg();
00133 }
00134 
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: RIBGraphicsWindow::begin_file
00138 //       Access: Protected
00139 //  Description: Called internally when a new RIB file needs to be
00140 //               created and its suitable headers written.
00141 ////////////////////////////////////////////////////////////////////
00142 void RIBGraphicsWindow::
00143 begin_file() {
00144   assert(!_file_begun);
00145   RIBGraphicsStateGuardian *rgsg = DCAST(RIBGraphicsStateGuardian, _gsg);
00146 
00147   _file_begun = true;
00148   _current_rib_filename = Filename::text_filename(get_rib_filename());
00149   assert(!_current_rib_filename.empty());
00150 
00151   _current_rib_filename.open_write(_file);
00152   rgsg->reset_file(_file);
00153 
00154   if (!_file) {
00155     cerr << "Unable to write to " << _current_rib_filename << "\n";
00156     return;
00157   }
00158 
00159   _file <<
00160     "#\n"
00161     "# RIB file " << _current_rib_filename << "\n"
00162     "#\n";
00163 
00164   // World set-up
00165   _file <<
00166     //    "TextureCoordinates 0 1  1 1  0 0  1 0\n"
00167     "Option \"searchpath\" \"shader\" \"shaders:@\"\n";
00168 
00169   // A default ambient light for when lighting is off
00170   _file <<
00171     "LightSource \"ambientlight\" 0 \"intensity\" 1 \"lightcolor\" [ 1 1 1 ]\n"
00172     "Illuminate 0 1\n";
00173 
00174 
00175   if (!get_image_filename_template().empty() &&
00176       !image_per_frame()) {
00177     // If we have an image filename, and it's the same file for all
00178     // frames, specify it outside the Frame control group.  Maybe the
00179     // renderer will be able to generate a multi-frame output file
00180     // somehow.
00181     _file << "Display \"" << get_image_filename()
00182           << "\" \"file\" \"rgb\"\n";
00183   }
00184 
00185 }
00186 
00187 
00188 ////////////////////////////////////////////////////////////////////
00189 //     Function: RIBGraphicsWindow::end_file
00190 //       Access: Protected
00191 //  Description: Called internally to wrap up the current RIB file and
00192 //               close it.
00193 ////////////////////////////////////////////////////////////////////
00194 void RIBGraphicsWindow::
00195 end_file() {
00196   assert(_file_begun);
00197   RIBGraphicsStateGuardian *rgsg = DCAST(RIBGraphicsStateGuardian, _gsg);
00198   rgsg->reset();
00199 
00200   _file_begun = false;
00201   _file.close();
00202 
00203   cerr << "Wrote " << _current_rib_filename << "\n";
00204 }
00205 
00206 ////////////////////////////////////////////////////////////////////
00207 //     Function: RIBGraphicsWindow::format_name
00208 //       Access: Protected
00209 //  Description: Given a filename template which contains symbols like
00210 //               %f etc., replaces the symbols with the appropriate
00211 //               values to generate an actual filename.
00212 ////////////////////////////////////////////////////////////////////
00213 string RIBGraphicsWindow::
00214 format_name(const string &name_template) const {
00215   string name;
00216 
00217   string::const_iterator ci;
00218   ci = name_template.begin();
00219   while (ci != name_template.end()) {
00220     if (*ci == '%') {
00221       ++ci;
00222       string::const_iterator pi = ci;
00223       while (ci != name_template.end() && isdigit(*ci)) {
00224         ++ci;
00225       }
00226       string format_spec(pi, ci);
00227 
00228       if (ci != name_template.end()) {
00229         switch (*ci) {
00230         case 'f':
00231           // %f : insert frame number
00232           name += format_integer(format_spec, _frame_number);
00233           break;
00234 
00235         case 't':
00236           // %t : insert window title
00237           name += format_string(format_spec, _props._title);
00238           break;
00239 
00240         case '%':
00241           // %% : insert percent sign
00242           name += '%';
00243           break;
00244 
00245         default:
00246           cerr << "Invalid filename template specification: %"
00247                << format_spec << *ci << "\n";
00248         }
00249         ++ci;
00250       } else {
00251         cerr << "Incomplete filename template specification: %"
00252              << format_spec << "\n";
00253       }
00254     } else {
00255       name += *ci;
00256       ++ci;
00257     }
00258   }
00259 
00260   return name;
00261 }
00262 
00263 
00264 ////////////////////////////////////////////////////////////////////
00265 //     Function: RIBGraphicsWindow::format_integer
00266 //       Access: Protected, Static
00267 //  Description: Formats an integer according to a %d-like format
00268 //               specification found in a filename template.
00269 //               format_spec is the string between the percent sign
00270 //               and the command letter (which might be empty, or
00271 //               might contain a field width), and number is the value
00272 //               to format.
00273 ////////////////////////////////////////////////////////////////////
00274 string RIBGraphicsWindow::
00275 format_integer(const string &format_spec, int number) {
00276   // Get the field width requirement.  We don't care if it begins with
00277   // a leading zero or not, since we always pad with zeroes.
00278   int width = atoi(format_spec.c_str());
00279 
00280   string result;
00281   string sign;
00282 
00283   // Is the number negative?
00284   if (number < 0) {
00285     sign = '-';
00286     number = -number;
00287   }
00288 
00289   // Now build the number from the least-significant digit up.  We
00290   // keep going until the width runs out or the number does, whichever
00291   // lasts longer.
00292   do {
00293     int digit = number % 10;
00294     number /= 10;
00295 
00296     result = (char)(digit + '0') + result;
00297     width--;
00298   } while (width > 0 || number != 0);
00299 
00300   return sign + result;
00301 }
00302 
00303 ////////////////////////////////////////////////////////////////////
00304 //     Function: RIBGraphicsWindow::format_string
00305 //       Access: Protected, Static
00306 //  Description: Formats a string according to a %s-like format
00307 //               specification found in a filename template.
00308 //               format_spec is the string between the percent sign
00309 //               and the command letter (which might be empty, or
00310 //               might contain a field width), and str is the value
00311 //               to format.
00312 ////////////////////////////////////////////////////////////////////
00313 string RIBGraphicsWindow::
00314 format_string(const string &format_spec, const string &str) {
00315   int width = atoi(format_spec.c_str());
00316   if (width <= str.length()) {
00317     return str;
00318   }
00319 
00320   // Now we have to pad the string out.
00321   string pad;
00322 
00323   for (int extra = width; extra < str.length(); extra++) {
00324     pad += '-';
00325   }
00326   return pad + str;
00327 }
00328 
00329 
00330 ////////////////////////////////////////////////////////////////////
00331 //     Function: RIBGraphicsWindow::format_string
00332 //       Access: Protected, Static
00333 //  Description: Scans a name template for the appearance of %f (or
00334 //               some variant), and returns true if it appears, false
00335 //               otherwise.
00336 ////////////////////////////////////////////////////////////////////
00337 bool RIBGraphicsWindow::
00338 check_per_frame(const string &name_template) {
00339   string::const_iterator ci;
00340   ci = name_template.begin();
00341   while (ci != name_template.end()) {
00342     if (*ci == '%') {
00343       ++ci;
00344       string::const_iterator pi = ci;
00345       while (ci != name_template.end() && isdigit(*ci)) {
00346         ++ci;
00347       }
00348 
00349       if (ci != name_template.end()) {
00350         if ((*ci) == 'f') {
00351           return true;
00352         }
00353         ++ci;
00354       }
00355     } else {
00356       ++ci;
00357     }
00358   }
00359 
00360   return false;
00361 }
00362 
00363 void RIBGraphicsWindow::make_current(void) {
00364 }
00365 
00366 void RIBGraphicsWindow::unmake_current(void) {
00367 }
00368 
00369 ////////////////////////////////////////////////////////////////////
00370 //     Function: RIBGraphicsWindow::get_gsg_type
00371 //       Access: Public, Virtual
00372 //  Description: Returns the TypeHandle of the kind of GSG preferred
00373 //               by this kind of window.
00374 ////////////////////////////////////////////////////////////////////
00375 TypeHandle RIBGraphicsWindow::
00376 get_gsg_type() const {
00377   return RIBGraphicsStateGuardian::get_class_type();
00378 }
00379 
00380 GraphicsWindow*
00381 RIBGraphicsWindow::make_RibGraphicsWindow(const FactoryParams &params) {
00382   GraphicsWindow::WindowPipe *pipe_param;
00383   if (!get_param_into(pipe_param, params)) {
00384     ribdisplay_cat.error()
00385       << "No pipe specified for window creation!" << endl;
00386     return NULL;
00387   }
00388 
00389   GraphicsPipe *pipe = pipe_param->get_pipe();
00390 
00391   GraphicsWindow::WindowProps *props_param;
00392   if (!get_param_into(props_param, params)) {
00393     return new RIBGraphicsWindow(pipe);
00394   } else {
00395     return new RIBGraphicsWindow(pipe, props_param->get_properties());
00396   }
00397 }
00398 
00399 TypeHandle RIBGraphicsWindow::get_class_type(void) {
00400   return _type_handle;
00401 }
00402 
00403 void RIBGraphicsWindow::init_type(void) {
00404   GraphicsWindow::init_type();
00405   register_type(_type_handle, "RIBGraphicsWindow",
00406                 GraphicsWindow::get_class_type());
00407 }
00408 
00409 TypeHandle RIBGraphicsWindow::get_type(void) const {
00410   return get_class_type();
00411 }

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