00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "planarReflector.h"
00019 #include "config_shader.h"
00020
00021 #include <pt_Node.h>
00022 #include <dftraverser.h>
00023 #include <attribTraverser.h>
00024 #include <displayRegion.h>
00025 #include <graphicsWindow.h>
00026 #include <renderBuffer.h>
00027 #include <perspectiveProjection.h>
00028 #include <look_at.h>
00029 #include <compose_matrix.h>
00030 #include <get_rel_pos.h>
00031 #include <lightTransition.h>
00032 #include <depthTestTransition.h>
00033 #include <depthWriteTransition.h>
00034 #include <depthWriteTransition.h>
00035 #include <textureTransition.h>
00036 #include <stencilTransition.h>
00037 #include <colorBlendTransition.h>
00038 #include <colorBlendAttribute.h>
00039 #include <cullFaceTransition.h>
00040 #include <transformTransition.h>
00041 #include <colorMaskTransition.h>
00042 #include <colorTransition.h>
00043 #include <clipPlaneTransition.h>
00044 #include <directRenderTraverser.h>
00045 #include <nodeAttributes.h>
00046
00047
00048
00049
00050 TypeHandle PlanarReflector::_type_handle;
00051
00052
00053
00054
00055
00056
00057 PlanarReflector::PlanarReflector(void) : CasterShader()
00058 {
00059 Colorf c(0.8f, 0.8f, 0.8f, 1.0f);
00060 init(NULL, c);
00061 }
00062
00063
00064
00065
00066
00067
00068 PlanarReflector::
00069 PlanarReflector(PlaneNode* plane_node) : CasterShader()
00070 {
00071 Colorf c(0.8f, 0.8f, 0.8f, 1.0f);
00072 init(plane_node, c);
00073 }
00074
00075
00076
00077
00078
00079
00080 PlanarReflector::
00081 PlanarReflector(const Colorf& c) : CasterShader()
00082 {
00083 init(NULL, c);
00084 }
00085
00086
00087
00088
00089
00090
00091 PlanarReflector::
00092 PlanarReflector(PlaneNode* plane_node, const Colorf& c) : CasterShader()
00093 {
00094 init(plane_node, c);
00095 }
00096
00097
00098
00099
00100
00101
00102 void PlanarReflector::init(PlaneNode *plane_node, const Colorf& c)
00103 {
00104 if (plane_node == NULL)
00105 plane_node = new PlaneNode;
00106
00107 _save_color_buffer = true;
00108 _save_depth_buffer = true;
00109 _clip_to_plane = true;
00110
00111 _color_buffer = NULL;
00112 _depth_buffer = NULL;
00113
00114 _plane_node = plane_node;
00115 _color = c;
00116 }
00117
00118
00119
00120
00121
00122
00123 void PlanarReflector::
00124 pre_apply(Node *, const AllAttributesWrapper &,
00125 const AllTransitionsWrapper &, GraphicsStateGuardian *gsg)
00126 {
00127 int xo, yo, w, h;
00128 gsg->get_current_display_region()->get_region_pixels(xo, yo, w, h);
00129 _color_buffer = new PixelBuffer(PixelBuffer::rgb_buffer(w, h));
00130 _depth_buffer = new PixelBuffer(PixelBuffer::depth_buffer(w, h));
00131 }
00132
00133
00134
00135
00136
00137
00138 void PlanarReflector::
00139 apply(Node *node, const AllAttributesWrapper &init_state,
00140 const AllTransitionsWrapper &net_trans, GraphicsStateGuardian *gsg) {
00141 DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
00142
00143 Shader::apply(node, init_state, net_trans, gsg);
00144
00145 init_state.write(shader_cat->debug(false), 4);
00146
00147 if (get_num_casters() == 0) {
00148 shader_cat.error()
00149 << "PlanarReflector::apply() - no casters in caster list" << endl;
00150 return;
00151 }
00152
00153
00154
00155 PT(TextureTransition) tex_off = new TextureTransition(TextureTransition::off());
00156 tex_off->set_priority(100);
00157
00158
00159
00160
00161 if (!_multipass_on) {
00162 gsg->render_subgraph(&drt, node, init_state, net_trans);
00163 }
00164
00165
00166 bool clear_stencil = gsg->get_stencil_clear_value();
00167 gsg->set_stencil_clear_value(false);
00168
00169 {
00170
00171 AllTransitionsWrapper trans(net_trans);
00172
00173
00174 int buffer_mask = RenderBuffer::T_stencil;
00175 if (_save_color_buffer) {
00176 gsg->copy_pixel_buffer(_color_buffer,
00177 gsg->get_current_display_region(),
00178 gsg->get_render_buffer(RenderBuffer::T_back));
00179 buffer_mask |= RenderBuffer::T_back;
00180
00181 ColorMaskTransition *cm = new ColorMaskTransition(0);
00182 trans.set_transition(cm);
00183 } else {
00184 ColorMaskTransition *cm =
00185 new ColorMaskTransition(ColorMaskProperty::M_a);
00186 trans.set_transition(cm);
00187 }
00188
00189 if (_save_depth_buffer)
00190 {
00191 gsg->copy_pixel_buffer(_depth_buffer,
00192 gsg->get_current_display_region(),
00193 gsg->get_render_buffer(RenderBuffer::T_depth));
00194
00195 }
00196
00197
00198
00199
00200
00201 trans.set_transition(new LightTransition(LightTransition::all_off()));
00202
00203
00204 DepthTestTransition *dta =
00205 new DepthTestTransition(DepthTestProperty::M_equal);
00206 trans.set_transition(dta);
00207
00208
00209 DepthWriteTransition *dwa = new DepthWriteTransition;
00210 dwa->set_off();
00211 trans.set_transition(dwa);
00212
00213
00214 StencilTransition *sa =
00215 new StencilTransition(StencilProperty::M_not_equal,
00216 StencilProperty::A_replace);
00217 trans.set_transition(sa);
00218
00219
00220 trans.set_transition(tex_off);
00221
00222
00223 trans.set_transition(new ColorBlendTransition(ColorBlendProperty::M_none));
00224
00225
00226 gsg->clear(gsg->get_render_buffer(buffer_mask));
00227
00228
00229 gsg->render_subgraph(&drt, node, init_state, trans);
00230 }
00231
00232 {
00233
00234
00235 gsg->clear(gsg->get_render_buffer(RenderBuffer::T_depth));
00236
00237
00238 AllTransitionsWrapper trans(net_trans);
00239
00240
00241 StencilTransition *sa =
00242 new StencilTransition(StencilProperty::M_equal,
00243 StencilProperty::A_keep);
00244 trans.set_transition(sa);
00245
00246
00247
00248 CullFaceTransition *cf =
00249 new CullFaceTransition(CullFaceProperty::M_cull_counter_clockwise);
00250 trans.set_transition(cf);
00251
00252 if (_clip_to_plane) {
00253
00254 ClipPlaneTransition *cp = new ClipPlaneTransition;
00255 cp->set_on(_plane_node);
00256 trans.set_transition(cp);
00257 }
00258
00259
00260 PT_Node caster_group = new Node;
00261 NamedNodeVector::iterator c;
00262 for (c = _casters.begin(); c != _casters.end(); ++c) {
00263 Node *caster = (*c);
00264
00265 LMatrix4f mat;
00266 get_rel_mat(caster, _plane_node, mat);
00267
00268 RenderRelation *arc = new RenderRelation(caster_group, caster);
00269 arc->set_transition(new TransformTransition(mat));
00270 }
00271
00272
00273
00274 PT(RenderRelation) caster_arc =
00275 new RenderRelation(_plane_node, caster_group);
00276
00277 LMatrix4f plane_mat = _plane_node->get_plane().get_reflection_mat();
00278 caster_arc->set_transition(new TransformTransition(plane_mat));
00279
00280
00281 gsg->render_subgraph(&drt, _plane_node, init_state, trans);
00282
00283
00284
00285
00286 remove_arc(caster_arc);
00287 }
00288
00289 {
00290
00291
00292 AllTransitionsWrapper trans(net_trans);
00293
00294 trans.set_transition(new StencilTransition(StencilProperty::M_none));
00295
00296 ColorBlendTransition *cb =
00297 new ColorBlendTransition(ColorBlendProperty::M_multiply);
00298 trans.set_transition(cb);
00299
00300 ColorTransition *c = new ColorTransition;
00301 c->set_on(_color);
00302 trans.set_transition(c);
00303
00304 trans.set_transition(new LightTransition(LightTransition::all_off()));
00305 trans.set_transition(tex_off);
00306
00307 gsg->render_subgraph(&drt, node, init_state, trans);
00308 }
00309
00310
00311
00312 if (_save_color_buffer) {
00313 NodeAttributes na;
00314
00315 ColorBlendAttribute *cb =
00316 new ColorBlendAttribute;
00317 cb->set_mode(ColorBlendProperty::M_add);
00318 na.set_attribute(ColorBlendTransition::get_class_type(), cb);
00319
00320 gsg->draw_pixel_buffer(_color_buffer, gsg->get_current_display_region(),
00321 gsg->get_render_buffer(RenderBuffer::T_back), na);
00322 } else {
00323
00324
00325 AllTransitionsWrapper trans(net_trans);
00326
00327 StencilTransition *sa =
00328 new StencilTransition(StencilProperty::M_equal,
00329 StencilProperty::A_keep);
00330 trans.set_transition(sa);
00331
00332 DepthTestTransition *dta =
00333 new DepthTestTransition(DepthTestProperty::M_equal);
00334 trans.set_transition(dta);
00335
00336 DepthWriteTransition *dwa = new DepthWriteTransition;
00337 dwa->set_off();
00338 trans.set_transition(dwa);
00339
00340 ColorBlendTransition *cb =
00341 new ColorBlendTransition(ColorBlendProperty::M_add);
00342 trans.set_transition(cb);
00343
00344 gsg->render_subgraph(&drt, node, init_state, trans);
00345 }
00346
00347 if (_save_depth_buffer)
00348 {
00349 gsg->draw_pixel_buffer(_depth_buffer, gsg->get_current_display_region(),
00350 gsg->get_render_buffer(RenderBuffer::T_depth));
00351
00352 }
00353
00354
00355
00356 gsg->set_stencil_clear_value(clear_stencil);
00357 }
00358
00359
00360
00361