00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00038
00039 TypeHandle SpheretexReflector::_type_handle;
00040
00041
00042
00043
00044
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
00068
00069
00070
00071 SpheretexReflector::~SpheretexReflector(void) {
00072 }
00073
00074
00075
00076
00077
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
00088
00089
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
00100
00101
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
00114
00115 AllAttributesWrapper state(init_state);
00116 state.clear_attribute(TransformTransition::get_class_type());
00117
00118
00119 const LensNode* camera = gsg->get_current_camera();
00120
00121
00122 Colorf clear_color = gsg->get_color_clear_value();
00123
00124
00125
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
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
00141 AllTransitionsWrapper trans(net_trans);
00142
00143
00144
00145
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
00153
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
00162
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
00171 LMatrix4f r_mat;
00172
00173
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
00179 look_at(r_mat, camera_pos, camera_up, gsg->get_coordinate_system());
00180
00181
00182 r_mat = LMatrix4f::scale_mat(LVector3f(-1.0f, 1.0f, 1.0f)) * r_mat;
00183
00184
00185
00186 CullFaceTransition *cf =
00187 new CullFaceTransition(CullFaceProperty::M_cull_counter_clockwise);
00188 trans.set_transition(cf);
00189 }
00190 else
00191 {
00192
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
00200 DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
00201 gsg->render_subgraph(&drt, caster_group, projnode, state, trans);
00202
00203
00204
00205
00206
00207
00208
00209
00210 _spheretex_shader.get_texture()->copy(gsg, scratch_region, gsg->get_render_buffer(RenderBuffer::T_back));
00211
00212
00213
00214
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
00222
00223
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
00232
00233 _spheretex_shader.apply(node, init_state, net_trans, gsg);
00234 }
00235