00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "spheretexHighlighter.h"
00019 #include "config_shader.h"
00020
00021 #include <light.h>
00022 #include <spotlight.h>
00023 #include <renderBuffer.h>
00024 #include <get_rel_pos.h>
00025 #include <dftraverser.h>
00026 #include <displayRegion.h>
00027 #include <graphicsWindow.h>
00028 #include <materialTransition.h>
00029 #include <materialAttribute.h>
00030
00031
00032
00033
00034 TypeHandle SpheretexHighlighter::_type_handle;
00035
00036
00037
00038
00039
00040
00041 SpheretexHighlighter::SpheretexHighlighter(int size) : FrustumShader()
00042 {
00043 set_size(size);
00044
00045 Texture* texture = new Texture;
00046 texture->set_minfilter(Texture::FT_linear);
00047 texture->set_magfilter(Texture::FT_linear);
00048 texture->set_wrapu(Texture::WM_clamp);
00049 texture->set_wrapv(Texture::WM_clamp);
00050 texture->_pbuffer = new PixelBuffer(PixelBuffer::rgb_buffer(_size, _size));
00051 _spheretex_shader.set_texture(texture);
00052 _spheretex_shader.set_blend_mode(ColorBlendProperty::M_add);
00053 }
00054
00055
00056
00057
00058
00059
00060 void SpheretexHighlighter::
00061 set_multipass(bool)
00062 {
00063
00064 _multipass_on = true;
00065 _spheretex_shader.set_multipass(true);
00066 }
00067
00068
00069
00070
00071
00072
00073 void SpheretexHighlighter::
00074 set_priority(int priority)
00075 {
00076 Shader::set_priority(priority);
00077 _spheretex_shader.set_priority(priority);
00078 }
00079
00080
00081
00082
00083
00084
00085 void SpheretexHighlighter::
00086 pre_apply(Node *node, const AllAttributesWrapper &init_state,
00087 const AllTransitionsWrapper &, GraphicsStateGuardian *gsg)
00088 {
00089 if (get_num_frusta() == 0) {
00090 shader_cat.error()
00091 << "SpheretexHighlighter::config() - no lights in frusta list"
00092 << endl;
00093 return;
00094 } else if (get_num_frusta() > 1) {
00095 shader_cat.warning()
00096 << "SpheretexHighlighter::config() - frusta list has more than one "
00097 << "frustum - ignore all but the first one for now..." << endl;
00098 }
00099 if (_frusta[0]->get_type() != Spotlight::get_class_type()) {
00100 shader_cat.error()
00101 << "SpheretexHighlighter::config() - only works for Spotlights"
00102 << " so far - we'll add point lights later" << endl;
00103 return;
00104 }
00105
00106 Spotlight* light = (Spotlight *)_frusta[0];
00107
00108
00109 float shininess = 0.0;
00110
00111 const NodeAttribute *mat_attrib =
00112 init_state.get_attribute(MaterialTransition::get_class_type());
00113 if (mat_attrib != (NodeAttribute *)NULL) {
00114 const Material *material =
00115 DCAST(MaterialAttribute, mat_attrib)->get_material();
00116 shininess = material->get_shininess();
00117 }
00118
00119 if (shininess == 0.0) {
00120 shininess = 100.0;
00121 }
00122
00123
00124
00125 const LensNode* projnode = gsg->get_current_camera();
00126 LVector3f model_pos = get_rel_pos(node, projnode);
00127 LVector3f norm_model_pos = normalize(model_pos);
00128 LPoint3f light_pos = get_rel_pos(light, projnode);
00129 LVector3f light_vec = light_pos - model_pos;
00130 light_vec = normalize(light_vec);
00131
00132
00133 LVector3f view_vec(0, -1, 0);
00134 LVector3f norm, S;
00135 float ZZ, XX_ZZ, intensity, grazing;
00136 uchar color[3];
00137 float scale = 1.0 / ((float)(_size - 1));
00138
00139 Texture* texture = _spheretex_shader.get_texture();
00140
00141 for (int y = 0; y < _size; ++y) {
00142 norm[2] = 2. * ((float)y * scale) - 1.;
00143 ZZ = norm[2] * norm[2];
00144
00145 for (int x = 0; x < _size; ++x) {
00146 norm[0] = 2. * ((float)x * scale) -1.;
00147 XX_ZZ = (norm[0] * norm[0]) + ZZ;
00148
00149 color[0] = color[1] = color[2] = 0;
00150
00151 if (XX_ZZ <= 1.) {
00152 norm[1] = -(float)sqrt(1. - XX_ZZ);
00153 grazing = dot(norm, light_vec);
00154 if (grazing > 0.) {
00155 S = norm;
00156 S *= 2. * grazing;
00157 S = S - light_vec;
00158 intensity = -dot(S, norm_model_pos);
00159
00160
00161 if (intensity > 0.) {
00162 intensity = pow(intensity, shininess);
00163 color[0] = color[1] = color[2] = (uchar)(intensity * 255.);
00164 }
00165 }
00166 }
00167 texture->_pbuffer->set_uchar_rgb_texel(color, x, y, _size);
00168 texture->unprepare();
00169 }
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178 void SpheretexHighlighter::
00179 apply(Node *node, const AllAttributesWrapper &init_state,
00180 const AllTransitionsWrapper &net_trans, GraphicsStateGuardian *gsg) {
00181
00182 Shader::apply(node, init_state, net_trans, gsg);
00183
00184 _spheretex_shader.apply(node, init_state, net_trans, gsg);
00185 }