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

panda/src/shader/spheretexReflector.cxx

Go to the documentation of this file.
00001 // Filename: spheretexReflector.cxx
00002 // Created by:  mike (09Jan97)
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 #include "spheretexReflector.h"
00019 #include "config_shader.h"
00020 
00021 #include <pt_Node.h>
00022 #include <frustum.h>
00023 #include <get_rel_pos.h>
00024 #include <dftraverser.h>
00025 #include <displayRegion.h>
00026 #include <graphicsWindow.h>
00027 #include <renderBuffer.h>
00028 #include <perspectiveLens.h>
00029 #include <look_at.h>
00030 #include <compose_matrix.h>
00031 #include <cullFaceTransition.h>
00032 #include <colorBlendTransition.h>
00033 #include <transformTransition.h>
00034 #include <directRenderTraverser.h>
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 // Static variables
00038 ////////////////////////////////////////////////////////////////////
00039 TypeHandle SpheretexReflector::_type_handle;
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: SpheretexReflector::Constructor
00043 //       Access:
00044 //  Description:
00045 ////////////////////////////////////////////////////////////////////
00046 SpheretexReflector::SpheretexReflector(int size) : CasterShader()
00047 {
00048   set_size(size);
00049   _is_reflector = true;
00050 
00051   _fnear = 0.1f;
00052   _ffar = 1000.0f;
00053 
00054   Texture* texture = new Texture;
00055   texture->set_minfilter(Texture::FT_linear);
00056   texture->set_magfilter(Texture::FT_linear);
00057   texture->set_wrapu(Texture::WM_clamp);
00058   texture->set_wrapv(Texture::WM_clamp);
00059   texture->_pbuffer->set_xsize(_size);
00060   texture->_pbuffer->set_ysize(_size);
00061 
00062   _spheretex_shader.set_texture(texture);
00063   _spheretex_shader.set_blend_mode(ColorBlendProperty::M_add);
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: SpheretexReflector::destructor
00068 //       Access:
00069 //  Description:
00070 ////////////////////////////////////////////////////////////////////
00071 SpheretexReflector::~SpheretexReflector(void) {
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //     Function: SpheretexReflector::set_priority
00076 //       Access: Public
00077 //  Description:
00078 ////////////////////////////////////////////////////////////////////
00079 void SpheretexReflector::
00080 set_priority(int priority)
00081 {
00082   Shader::set_priority(priority);
00083   _spheretex_shader.set_priority(priority);
00084 }
00085 
00086 ////////////////////////////////////////////////////////////////////
00087 //     Function: SpheretexReflector::set_multipass
00088 //       Access: Public
00089 //  Description:
00090 ////////////////////////////////////////////////////////////////////
00091 void SpheretexReflector::
00092 set_multipass(bool on)
00093 {
00094   Shader::set_multipass(on);
00095   _spheretex_shader.set_multipass(on);
00096 }
00097 
00098 ////////////////////////////////////////////////////////////////////
00099 //     Function: SpheretexHighlighter::pre_apply
00100 //       Access:
00101 //  Description:
00102 ////////////////////////////////////////////////////////////////////
00103 void SpheretexReflector::
00104 pre_apply(Node *node, const AllAttributesWrapper &init_state,
00105           const AllTransitionsWrapper &net_trans, GraphicsStateGuardian *gsg)
00106 {
00107   if (get_num_casters() == 0) {
00108     shader_cat.error()
00109       << "SpheretexReflector::config() - no casters in caster list" << endl;
00110     return;
00111   }
00112 
00113   //We need a state that we can modify to remove the camera transform
00114   //that is passed to us
00115   AllAttributesWrapper state(init_state);
00116   state.clear_attribute(TransformTransition::get_class_type());
00117 
00118   // Get the current camera from the gsg
00119   const LensNode* camera = gsg->get_current_camera();
00120 
00121   // Save the clear color.
00122   Colorf clear_color = gsg->get_color_clear_value();
00123 
00124   // Make a display region of the proper size and clear it to prepare for
00125   // rendering the shadow map
00126   PT(DisplayRegion) scratch_region =
00127     gsg->get_window()->make_scratch_display_region(_size, _size);
00128 
00129   DisplayRegionStack old_dr = gsg->push_display_region(scratch_region);
00130 
00131   // Save scratch region before clearing it to be non-destructive
00132   FrameBufferStack old_fb = gsg->push_frame_buffer
00133     (gsg->get_render_buffer(RenderBuffer::T_back | RenderBuffer::T_depth),
00134      scratch_region);
00135 
00136   gsg->set_color_clear_value(Colorf(0., 0., 0., 1.));
00137   gsg->clear(gsg->get_render_buffer(RenderBuffer::T_back |
00138                                     RenderBuffer::T_depth), scratch_region);
00139 
00140   // Copy the transition wrapper so we can modify it freely.
00141   AllTransitionsWrapper trans(net_trans);
00142 
00143   // Create a temporary node that is the parent of all of the caster
00144   // objects, so we can render them from the point of view of the
00145   // reflector.
00146 
00147   PT_Node caster_group = new Node;
00148   NamedNodeVector::iterator ci;
00149   for (ci = _casters.begin(); ci != _casters.end(); ++ci) {
00150     Node *caster = (*ci);
00151 
00152     // Get the transform of the caster from the point of view of the
00153     // reflector.
00154     LMatrix4f mat;
00155     get_rel_mat(caster, node, mat);
00156 
00157     RenderRelation *arc = new RenderRelation(caster_group, caster);
00158     arc->set_transition(new TransformTransition(mat));
00159   }
00160 
00161   // Build a LensNode that represents a wide-angle view from the
00162   // reflecting object towards the camera.
00163   PT(Lens) *lens = new PerspectiveLens;
00164   lens->set_fov(150.0f);
00165   lens->set_near(_fnear);
00166   lens->set_far(_ffar);
00167   LensNode *projnode = new LensNode;
00168   projnode->set_lens(lens);
00169 
00170   // How shall we rotate the LensNode?
00171   LMatrix4f r_mat;
00172 
00173   // Get camera pos in the coordinate space of the reflecting object
00174   LVector3f camera_pos = get_rel_pos(camera, node);
00175   LVector3f camera_up = get_rel_up(camera, node);
00176   if (_is_reflector == true)
00177   {
00178     // Take the picture looking toward the camera
00179     look_at(r_mat, camera_pos, camera_up, gsg->get_coordinate_system());
00180 
00181     // Flip along the X axis to make it behave like a mirror
00182     r_mat = LMatrix4f::scale_mat(LVector3f(-1.0f, 1.0f, 1.0f)) * r_mat;
00183 
00184     // And the vertex order for front facing polygons to compensate
00185     // for the above flip.
00186     CullFaceTransition *cf =
00187       new CullFaceTransition(CullFaceProperty::M_cull_counter_clockwise);
00188     trans.set_transition(cf);
00189   }
00190   else
00191   {
00192     // For a refractor, take the picture looking away from the camera.
00193     look_at(r_mat, -camera_pos, camera_up, gsg->get_coordinate_system());
00194   }
00195 
00196   RenderRelation *projarc = new RenderRelation(caster_group, projnode);
00197   projarc->set_transition(new TransformTransition(r_mat));
00198 
00199   // Now render the casters.
00200   DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
00201   gsg->render_subgraph(&drt, caster_group, projnode, state, trans);
00202 
00203   // The caster group, and all of the temporary group nodes below,
00204   // will automatically be destructed when the caster_group PointerTo
00205   // object goes out of scope.  We don't have to remove it from the
00206   // scene graph because we never actually inserted it.
00207 
00208   // Copy the results of the render from the framebuffer into the spheretex
00209   // shader's texture
00210   _spheretex_shader.get_texture()->copy(gsg, scratch_region, gsg->get_render_buffer(RenderBuffer::T_back));
00211 
00212   // Restore the original display region and clear value
00213 
00214   //Make sure the restore the depth buffer.  There's only one you know.
00215 
00216   gsg->set_color_clear_value(clear_color);
00217   gsg->pop_frame_buffer(old_fb);
00218   gsg->pop_display_region(old_dr);
00219 }
00220 ////////////////////////////////////////////////////////////////////
00221 //     Function: SpheretexHighlighter::apply
00222 //       Access:
00223 //  Description:
00224 ////////////////////////////////////////////////////////////////////
00225 void SpheretexReflector::
00226 apply(Node *node, const AllAttributesWrapper &init_state,
00227       const AllTransitionsWrapper &net_trans, GraphicsStateGuardian *gsg)
00228  {
00229   Shader::apply(node, init_state, net_trans, gsg);
00230 
00231   // Apply the spheremap reflection
00232   //gsg->prepare_display_region();
00233   _spheretex_shader.apply(node, init_state, net_trans, gsg);
00234 }
00235 

Generated on Fri May 2 00:44:04 2003 for Panda by doxygen1.3