Warning, /include/Geant4/tools/sg/zb_action is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_sg_zb_action
0005 #define tools_sg_zb_action
0006
0007 #include "zb_manager"
0008
0009 #include "render_action"
0010 #include "primitive_visitor"
0011 #include "../glprims"
0012
0013 #include "../zb/buffer"
0014
0015 #include "../colorfs"
0016 #include "../lina/plane"
0017 #include "../mathf"
0018 #include "../lina/vec3d" //ZZ=double
0019
0020 namespace tools {
0021 namespace sg {
0022
0023 class zb_action : public render_action {
0024 TOOLS_ACTION(zb_action,tools::sg::zb_action,render_action)
0025 private:
0026 zb_action& get_me() {return *this;}
0027 public:
0028 virtual void draw_vertex_array(gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs){
0029 m_pv.add_primitive(a_mode,a_floatn,a_xyzs);
0030 }
0031
0032 virtual void draw_vertex_array_xy(gl::mode_t a_mode,size_t a_floatn,const float* a_xys){
0033 m_pv.add_primitive_xy(a_mode,a_floatn,a_xys);
0034 }
0035
0036 virtual void draw_vertex_color_array(gl::mode_t a_mode,size_t a_floatn,
0037 const float* a_xyzs,const float* a_rgbas){
0038 m_pv.add_primitive_rgba(a_mode,a_floatn,a_xyzs,a_rgbas);
0039 }
0040
0041 virtual void draw_vertex_normal_array(gl::mode_t a_mode,size_t a_floatn,
0042 const float* a_xyzs,const float* a_nms){
0043 m_pv.add_primitive_normal(a_mode,a_floatn,a_xyzs,a_nms);
0044 }
0045
0046 virtual void draw_vertex_color_normal_array(gl::mode_t a_mode,size_t a_floatn,
0047 const float* a_xyzs,const float* a_rgbas,const float* a_nms){
0048 // We expect a_nms of size : 3*(a_floatn/3)
0049 // (then one normal per 3D point).
0050 m_pv.add_primitive_normal_rgba(a_mode,a_floatn,a_xyzs,a_nms,a_rgbas);
0051 }
0052
0053 virtual void clear_color(float a_r,float a_g,float a_b,float a_a){
0054 zb::buffer::ZPixel pix;
0055 zb::buffer::rgba2pix(a_r,a_g,a_b,a_a,pix);
0056 m_zb.clear_color_buffer(pix);
0057 }
0058 virtual void color4f(float a_r,float a_g,float a_b,float a_a){
0059 m_rgba.set_value(a_r,a_g,a_b,a_a);
0060 }
0061 virtual void line_width(float a_v){m_line_width = a_v;}
0062 virtual void point_size(float a_v) {m_point_size = a_v;}
0063 virtual void set_polygon_offset(bool a_v) {m_POLYGON_OFFSET_FILL = a_v;}
0064 virtual void normal(float a_x,float a_y,float a_z) {
0065 m_normal.set_value(a_x,a_y,a_z);
0066 }
0067
0068 virtual void set_winding(winding_type a_v) {
0069 m_ccw = (a_v==winding_ccw?true:false);
0070 }
0071 virtual void set_shade_model(shade_type) {}
0072
0073 virtual void set_depth_test(bool a_on) {m_DEPTH_TEST = a_on;}
0074
0075 virtual void set_cull_face(bool a_on) {m_CULL_FACE = a_on;}
0076 virtual void set_point_smooth(bool a_on) {m_POINT_SMOOTH = a_on;}
0077 virtual void set_line_smooth(bool a_on) {m_LINE_SMOOTH = a_on;}
0078
0079 virtual void load_proj_matrix(const mat4f& a_mtx) {
0080 m_proj = a_mtx;
0081 }
0082
0083 virtual void load_model_matrix(const mat4f& a_mtx) {
0084 m_model = a_mtx;
0085 set_normal_matrix();
0086 }
0087
0088 virtual unsigned int max_lights() {return 1000;}
0089
0090 virtual void enable_light(unsigned int,
0091 float a_dx,float a_dy,float a_dz,
0092 float a_r,float a_g,float a_b,float a_a,
0093 float a_ar,float a_ag,float a_ab,float a_aa){
0094 m_light_color.set_value(a_r,a_g,a_b,a_a);
0095 m_light_ambient.set_value(a_ar,a_ag,a_ab,a_aa);
0096 m_light_direction.set_value(a_dx,a_dy,a_dz);
0097 m_light_direction.normalize();
0098 m_light_on = true;
0099 }
0100
0101 virtual void set_lighting(bool a_value) {m_light_on = a_value;}
0102 virtual void set_blend(bool a_value) {m_blend = a_value;}
0103
0104 virtual void restore_state(unsigned int /*a_ret_num_light*/) {
0105 const sg::state& _state = state();
0106 m_proj = _state.m_proj;
0107 m_model = _state.m_model;
0108 set_normal_matrix();
0109
0110 m_rgba = _state.m_color;
0111 m_normal = _state.m_normal;
0112
0113 m_ccw = (_state.m_winding==winding_ccw?true:false);
0114 m_POLYGON_OFFSET_FILL = _state.m_GL_POLYGON_OFFSET_FILL;
0115 m_CULL_FACE = _state.m_GL_CULL_FACE;
0116 m_POINT_SMOOTH = _state.m_GL_POINT_SMOOTH;
0117 m_LINE_SMOOTH = _state.m_GL_LINE_SMOOTH;
0118 m_line_width = _state.m_line_width;
0119 m_point_size = _state.m_point_size;
0120 m_light_on = _state.m_GL_LIGHTING;
0121 m_DEPTH_TEST = _state.m_GL_DEPTH_TEST;
0122 m_blend = _state.m_GL_BLEND;
0123 }
0124
0125 /////////////////////////////////////////////////////////////////
0126 /// texture /////////////////////////////////////////////////////
0127 /////////////////////////////////////////////////////////////////
0128 virtual void draw_vertex_array_texture(gl::mode_t,size_t a_xyzn,const float* a_xyzs,
0129 gstoid a_id,const float* a_tcs) {
0130 img_byte img;
0131 if(!m_mgr.find(a_id,img)) return;
0132 m_pv.add_texture(m_out,a_xyzn,a_xyzs,img,a_tcs);
0133 }
0134
0135 virtual void draw_vertex_normal_array_texture(gl::mode_t a_mode,
0136 size_t a_xyzn,const float* a_xyzs,const float* /*a_nms*/,
0137 gstoid a_id,const float* a_tcs) {
0138 draw_vertex_array_texture(a_mode,a_xyzn,a_xyzs,a_id,a_tcs);
0139 }
0140
0141 /////////////////////////////////////////////////////////////////
0142 /// VBO /////////////////////////////////////////////////////////
0143 /////////////////////////////////////////////////////////////////
0144 virtual void begin_gsto(gstoid) {}
0145 virtual void draw_gsto_v(gl::mode_t,size_t,bufpos){}
0146 virtual void draw_gsto_vc(gl::mode_t,size_t,bufpos,bufpos) {}
0147 virtual void draw_gsto_vn(gl::mode_t,size_t,bufpos,bufpos) {}
0148 virtual void draw_gsto_vcn(gl::mode_t,size_t,bufpos,bufpos,bufpos) {}
0149 virtual void end_gsto() {}
0150 /////////////////////////////////////////////////////////////////
0151 /////////////////////////////////////////////////////////////////
0152 /////////////////////////////////////////////////////////////////
0153 virtual sg::render_manager& render_manager() {return m_mgr;}
0154 public:
0155 zb_action(zb_manager& a_mgr,std::ostream& a_out,unsigned int a_ww,unsigned int a_wh)
0156 :parent(a_out,a_ww,a_wh)
0157 ,m_mgr(a_mgr)
0158 ,m_pv(get_me())
0159 ,m_light_color(colorf_white())
0160 ,m_light_ambient(colorf_black())
0161 ,m_light_direction(vec3f(0,0,-1))
0162 ,m_normal(0,0,1)
0163
0164 ,m_ccw(true)
0165 ,m_POLYGON_OFFSET_FILL(false)
0166 ,m_CULL_FACE(true)
0167 ,m_POINT_SMOOTH(false)
0168 ,m_LINE_SMOOTH(false)
0169 ,m_line_width(1)
0170 ,m_point_size(1)
0171 ,m_light_on(false)
0172 ,m_DEPTH_TEST(true)
0173 ,m_blend(false)
0174 {
0175 m_vp_mtx.set_identity();
0176 m_vp_mtx.mul_translate(float(m_ww)/2,float(m_wh)/2,0);
0177 m_vp_mtx.mul_scale(float(m_ww)/2,float(m_wh)/2,1);
0178
0179 m_zb.change_size(a_ww,a_wh);
0180
0181 m_proj.set_identity();
0182 m_model.set_identity();
0183 m_normal_matrix.set_identity();
0184 }
0185 virtual ~zb_action(){}
0186 protected:
0187 zb_action(const zb_action& a_from)
0188 :parent(a_from)
0189 ,m_mgr(a_from.m_mgr)
0190 ,m_vp_mtx(a_from.m_vp_mtx)
0191 ,m_pv(a_from.m_pv)
0192 ,m_light_color(a_from.m_light_color)
0193 ,m_light_ambient(a_from.m_light_ambient)
0194 ,m_light_direction(a_from.m_light_direction)
0195 ,m_normal(a_from.m_normal)
0196
0197 ,m_proj(a_from.m_proj)
0198 ,m_model(a_from.m_model)
0199 ,m_normal_matrix(a_from.m_normal_matrix)
0200 ,m_rgba(a_from.m_rgba)
0201 ,m_ccw(a_from.m_ccw)
0202 ,m_POLYGON_OFFSET_FILL(a_from.m_POLYGON_OFFSET_FILL)
0203 ,m_CULL_FACE(a_from.m_CULL_FACE)
0204 ,m_POINT_SMOOTH(a_from.m_POINT_SMOOTH)
0205 ,m_LINE_SMOOTH(a_from.m_LINE_SMOOTH)
0206 ,m_line_width(a_from.m_line_width)
0207 ,m_point_size(a_from.m_point_size)
0208 ,m_light_on(a_from.m_light_on)
0209 ,m_DEPTH_TEST(a_from.m_DEPTH_TEST)
0210 ,m_blend(a_from.m_blend)
0211 {}
0212 zb_action& operator=(const zb_action& a_from){
0213 parent::operator=(a_from);
0214 m_vp_mtx = a_from.m_vp_mtx;
0215 m_pv = a_from.m_pv;
0216 m_light_color = a_from.m_light_color;
0217 m_light_ambient = a_from.m_light_ambient;
0218 m_light_direction = a_from.m_light_direction;
0219 m_normal = a_from.m_normal;
0220
0221 m_proj = a_from.m_proj;
0222 m_model = a_from.m_model;
0223 m_normal_matrix = a_from.m_normal_matrix;
0224 m_rgba = a_from.m_rgba;
0225 m_ccw = a_from.m_ccw;
0226 m_POLYGON_OFFSET_FILL = a_from.m_POLYGON_OFFSET_FILL;
0227 m_CULL_FACE = a_from.m_CULL_FACE;
0228 m_POINT_SMOOTH = a_from.m_POINT_SMOOTH;
0229 m_LINE_SMOOTH = a_from.m_LINE_SMOOTH;
0230 m_line_width = a_from.m_line_width;
0231 m_point_size = a_from.m_point_size;
0232 m_light_on = a_from.m_light_on;
0233 m_DEPTH_TEST = a_from.m_DEPTH_TEST;
0234 m_blend = a_from.m_blend;
0235 return *this;
0236 }
0237 public:
0238 void clear_color_buffer(float a_r,float a_g,float a_b,float a_a){
0239 clear_color(a_r,a_g,a_b,a_a);
0240 }
0241 void clear_color_buffer(const colorf& a_color){
0242 clear_color(a_color.r(),a_color.g(),a_color.b(),a_color.a());
0243 }
0244
0245 void clear_depth_buffer() {m_zb.clear_depth_buffer();}
0246 protected:
0247 typedef unsigned char uchar;
0248 protected:
0249 static void color2pix(const colorf& a_rgba,zb::buffer::ZPixel& a_pix) {
0250 zb::buffer::rgba2pix(a_rgba.r(),a_rgba.g(),a_rgba.b(),a_rgba.a(),a_pix);
0251 }
0252 public:
0253 zb::buffer::ZPixel* get_color_buffer(unsigned int& a_width,unsigned int& a_height) const {return m_zb.get_color_buffer(a_width,a_height);}
0254
0255 bool get_rgbs(bool a_top_to_bottom,std::vector<uchar>& a_buffer) {
0256 a_buffer.clear();
0257 if(!m_ww || !m_wh) return false;
0258 size_t sz = 3 * m_ww * m_wh;
0259 a_buffer.resize(sz);
0260 uchar* pos = a_buffer.data();
0261 zb::buffer::ZPixel pix;
0262 uchar* _pix = 0;
0263 for(unsigned int row=0;row<m_wh;row++) {
0264 for(unsigned int col=0;col<m_ww;col++) {
0265 if(!m_zb.get_clipped_pixel(col,a_top_to_bottom?row:m_wh-1-row,pix)){
0266 m_out << "tools::sg::zb_action::get_rgbs : can't get zbuffer pixel" << std::endl;
0267 *pos = 0xFF;pos++;
0268 *pos = 0x00;pos++;
0269 *pos = 0x00;pos++;
0270 } else {
0271 _pix = (uchar*)&pix;
0272 *pos = *_pix;_pix++;pos++;
0273 *pos = *_pix;_pix++;pos++;
0274 *pos = *_pix;_pix++;pos++;
0275 }
0276 }
0277 }
0278 return true;
0279 }
0280
0281 bool get_rgbas(bool a_top_to_bottom,std::vector<uchar>& a_buffer) {
0282 a_buffer.clear();
0283 if(!m_ww || !m_wh) return false;
0284 size_t sz = 4 * m_ww * m_wh;
0285 a_buffer.resize(sz);
0286 if(a_top_to_bottom) {
0287 ::memcpy(a_buffer.data(),m_zb.zimage(),sz);
0288 return true;
0289 }
0290 size_t stride = m_ww*4;
0291 uchar* zpos = ((uchar*)m_zb.zimage())+sz-stride;
0292 uchar* pos = a_buffer.data();
0293 for(unsigned int row=0;row<m_wh;row++,pos+=stride,zpos-=stride) ::memcpy(pos,zpos,stride);
0294 return true;
0295 }
0296 bool get_rgbas_cocoa(unsigned int a_factor,std::vector<uchar>& a_buffer) {
0297 a_buffer.clear();
0298 if(!m_ww || !m_wh) return false;
0299 if(!a_factor) return false;
0300 size_t bpp = 4;
0301 a_buffer.resize(a_factor* m_ww * a_factor * m_wh * bpp);
0302 uchar* zbuffer = (uchar*)m_zb.zimage();
0303 uchar* abuffer = a_buffer.data();
0304 size_t zstride = m_ww*bpp;
0305 size_t astride = a_factor*m_ww*bpp;
0306 size_t i,j,ar,ac,ipix;
0307 uchar* zpos;uchar* apos;
0308 for(j=0;j<m_wh;j++) {
0309 for(i=0;i<m_ww;i++) {
0310 //position in the original image.
0311 zpos = zbuffer + (m_wh-1-j) * zstride + i*bpp; //top_to_bottom.
0312
0313 for(ar=0;ar<a_factor;ar++) {
0314 for(ac=0;ac<a_factor;ac++) {
0315 //position in the new image.
0316 apos = abuffer + (j*a_factor+ar) * astride + (i*a_factor+ac)*bpp;
0317 for(ipix=0;ipix<bpp;ipix++) {
0318 *(apos+ipix) = *(zpos+ipix);
0319 }
0320 }
0321 }
0322
0323 }
0324 }
0325
0326 return true;
0327 }
0328
0329 bool get_bgras(bool a_top_to_bottom,std::vector<uchar>& a_buffer) {
0330 a_buffer.clear();
0331 if(!m_ww || !m_wh) return false;
0332 size_t sz = 4 * m_ww * m_wh;
0333 a_buffer.resize(sz);
0334 if(a_top_to_bottom) {
0335 uchar* pos = a_buffer.data();
0336 uchar* zpos = ((uchar*)m_zb.zimage());
0337 for(size_t count=0;count<sz;count+=4,pos+=4,zpos+=4) {
0338 *(pos+0) = *(zpos+2);
0339 *(pos+1) = *(zpos+1);
0340 *(pos+2) = *(zpos+0);
0341 *(pos+3) = *(zpos+3);
0342 }
0343 } else {
0344 size_t stride = m_ww*4;
0345 uchar* pos_line = a_buffer.data();
0346 uchar* zpos_line = ((uchar*)m_zb.zimage())+sz-stride;
0347 uchar* pos;
0348 uchar* zpos;
0349 size_t count;
0350 for(unsigned int row=0;row<m_wh;row++,pos_line+=stride,zpos_line-=stride) {
0351 pos = pos_line;
0352 zpos = zpos_line;
0353 for(count=0;count<m_ww;count++,pos+=4,zpos+=4) {
0354 *(pos+0) = *(zpos+2);
0355 *(pos+1) = *(zpos+1);
0356 *(pos+2) = *(zpos+0);
0357 *(pos+3) = *(zpos+3);
0358 }
0359 }
0360 }
0361 return true;
0362 }
0363 public:
0364 static bool get_rgb(void* a_tag,unsigned int a_col,unsigned int a_row,float& a_r,float& a_g,float& a_b){
0365 //used with wps.
0366 zb_action* rzb = (zb_action*)a_tag;
0367 zb::buffer::ZPixel pix;
0368 if(!rzb->m_zb.get_clipped_pixel(a_col,rzb->wh()-1-a_row,pix)){
0369 rzb->out() << "tools::sg;:zb_action::get_rgb: can't get zbuffer pixel" << std::endl;
0370 a_r = 1;
0371 a_g = 0;
0372 a_b = 0;
0373 return false;
0374 }
0375 float a;
0376 zb::buffer::pix2rgba(pix,a_r,a_g,a_b,a);
0377 return true;
0378 }
0379 protected:
0380 void set_normal_matrix() {
0381 mat4f tmp(m_model);
0382 tmp.no_translate();
0383 if(!tmp.invert(m_normal_matrix)) {
0384 m_out << "tools::sg::zb_action::set_normal_matrix : can't invert model matrix." << std::endl;
0385 }
0386 m_normal_matrix.transpose();
0387 }
0388
0389 bool project_point(float& a_x,float& a_y,float& a_z,float& a_w) {
0390 a_w = 1;
0391 m_model.mul_4f_opt(a_x,a_y,a_z,a_w,m_tmp);
0392 m_proj.mul_4f_opt(a_x,a_y,a_z,a_w,m_tmp);
0393 if(a_w==0) return false;
0394 a_x /= a_w;
0395 a_y /= a_w;
0396 a_z /= a_w;
0397 return true;
0398 }
0399
0400 class primvis : public primitive_visitor {
0401 protected:
0402 virtual bool project(float& a_x,float& a_y,float& a_z,float& a_w) {
0403 return m_this.project_point(a_x,a_y,a_z,a_w);
0404 }
0405 virtual bool add_point(float a_x,float a_y,float a_z,float) {
0406 return _add_point(a_x,a_y,a_z,m_this.m_rgba.r(),m_this.m_rgba.g(),m_this.m_rgba.b(),m_this.m_rgba.a());
0407 }
0408
0409 virtual bool add_point(float a_x,float a_y,float a_z,float,
0410 float a_r,float a_g,float a_b,float a_a) {
0411 return _add_point(a_x,a_y,a_z,a_r,a_g,a_b,a_a);
0412 }
0413
0414 virtual bool add_line(float a_bx,float a_by,float a_bz,float,
0415 float a_ex,float a_ey,float a_ez,float) {
0416 m_this.m_vp_mtx.mul_3f_opt(a_bx,a_by,a_bz,m_tmp);
0417 m_this.m_vp_mtx.mul_3f_opt(a_ex,a_ey,a_ez,m_tmp);
0418 a_bz *= -1;
0419 a_ez *= -1;
0420
0421 zb::point beg;
0422 zinit(beg,a_bx,a_by,a_bz);
0423
0424 zb::point end;
0425 zinit(end,a_ex,a_ey,a_ez);
0426
0427 m_this.m_zb.set_depth_test(m_this.m_DEPTH_TEST);
0428 m_this.m_zb.set_blend(m_this.m_blend);
0429
0430 zb::buffer::ZPixel pix;
0431 color2pix(m_this.m_rgba,pix);
0432 m_this.m_zb.draw_line(beg,end,pix,npix(m_this.m_line_width));
0433
0434 return true;
0435 }
0436
0437 virtual bool add_line(float a_bx,float a_by,float a_bz,float,
0438 float a_br,float a_bg,float a_bb,float a_ba,
0439 float a_ex,float a_ey,float a_ez,float,
0440 float,float,float,float) {
0441 m_this.m_vp_mtx.mul_3f_opt(a_bx,a_by,a_bz,m_tmp);
0442 m_this.m_vp_mtx.mul_3f_opt(a_ex,a_ey,a_ez,m_tmp);
0443 a_bz *= -1;
0444 a_ez *= -1;
0445
0446 zb::point beg;
0447 zinit(beg,a_bx,a_by,a_bz);
0448
0449 zb::point end;
0450 zinit(end,a_ex,a_ey,a_ez);
0451
0452 m_this.m_zb.set_depth_test(m_this.m_DEPTH_TEST);
0453 m_this.m_zb.set_blend(m_this.m_blend);
0454
0455 // interpolate color with beg,end ?
0456 zb::buffer::ZPixel pix;
0457 zb::buffer::rgba2pix(a_br,a_bg,a_bb,a_ba,pix);
0458 m_this.m_zb.draw_line(beg,end,pix,npix(m_this.m_line_width));
0459
0460 return true;
0461 }
0462
0463 virtual bool add_triangle(float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0464 float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0465 float a_p3x,float a_p3y,float a_p3z,float a_p3w){
0466 return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0467 m_this.m_normal.x(),
0468 m_this.m_normal.y(),
0469 m_this.m_normal.z(),
0470 a_p2x,a_p2y,a_p2z,a_p2w,
0471 m_this.m_normal.x(),
0472 m_this.m_normal.y(),
0473 m_this.m_normal.z(),
0474 a_p3x,a_p3y,a_p3z,a_p3w,
0475 m_this.m_normal.x(),
0476 m_this.m_normal.y(),
0477 m_this.m_normal.z(),
0478 m_this.m_rgba);
0479 }
0480
0481 virtual bool add_triangle(
0482 float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0483 float a_r1,float a_g1,float a_b1,float a_a1,
0484 float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0485 float a_r2,float a_g2,float a_b2,float a_a2,
0486 float a_p3x,float a_p3y,float a_p3z,float a_p3w,
0487 float a_r3,float a_g3,float a_b3,float a_a3){
0488
0489 float r = (a_r1+a_r2+a_r3)/3.0f;
0490 float g = (a_g1+a_g2+a_g3)/3.0f;
0491 float b = (a_b1+a_b2+a_b3)/3.0f;
0492 float a = (a_a1+a_a2+a_a3)/3.0f;
0493 colorf col(r,g,b,a);
0494
0495 return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0496 m_this.m_normal.x(),
0497 m_this.m_normal.y(),
0498 m_this.m_normal.z(),
0499 a_p2x,a_p2y,a_p2z,a_p2w,
0500 m_this.m_normal.x(),
0501 m_this.m_normal.y(),
0502 m_this.m_normal.z(),
0503 a_p3x,a_p3y,a_p3z,a_p3w,
0504 m_this.m_normal.x(),
0505 m_this.m_normal.y(),
0506 m_this.m_normal.z(),
0507 col);
0508 }
0509
0510 virtual bool project_normal(float&,float&,float&) {
0511 return true;
0512 }
0513 virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w,
0514 float /*a_nx*/,float /*a_ny*/,float /*a_nz*/) {
0515 add_point(a_x,a_y,a_z,a_w);
0516 return true;
0517 }
0518 virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w,
0519 float /*a_nx*/,float /*a_ny*/,float /*a_nz*/,
0520 float a_r,float a_g,float a_b,float a_a) {
0521 add_point(a_x,a_y,a_z,a_w,a_r,a_g,a_b,a_a);
0522 return true;
0523 }
0524 virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw,
0525 float /*a_bnx*/,float /*a_bny*/,float /*a_bnz*/,
0526 float a_ex,float a_ey,float a_ez,float a_ew,
0527 float /*a_enx*/,float /*a_eny*/,float /*a_enz*/) {
0528 add_line(a_bx,a_by,a_bz,a_bw, a_ex,a_ey,a_ez,a_ew);
0529 return true;
0530 }
0531 virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw,
0532 float /*a_bnx*/,float /*a_bny*/,float /*a_bnz*/,
0533 float a_br,float a_bg,float a_bb,float a_ba,
0534 float a_ex,float a_ey,float a_ez,float a_ew,
0535 float /*a_enx*/,float /*a_eny*/,float /*a_enz*/,
0536 float a_er,float a_eg,float a_eb,float a_ea){
0537 add_line(a_bx,a_by,a_bz,a_bw, a_br,a_bg,a_bb,a_ba, a_ex,a_ey,a_ez,a_ew, a_er,a_eg,a_eb,a_ea);
0538 return true;
0539 }
0540 virtual bool add_triangle_normal(
0541 float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0542 float a_n1x,float a_n1y,float a_n1z,
0543 float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0544 float a_n2x,float a_n2y,float a_n2z,
0545 float a_p3x,float a_p3y,float a_p3z,float a_p3w,
0546 float a_n3x,float a_n3y,float a_n3z) {
0547
0548 return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0549 a_n1x,a_n1y,a_n1z,
0550 a_p2x,a_p2y,a_p2z,a_p2w,
0551 a_n2x,a_n2y,a_n2z,
0552 a_p3x,a_p3y,a_p3z,a_p3w,
0553 a_n3x,a_n3y,a_n3z,
0554 m_this.m_rgba);
0555 return true;
0556 }
0557 virtual bool add_triangle_normal(
0558 float a_p1x,float a_p1y,float a_p1z,float a_p1w,
0559 float a_n1x,float a_n1y,float a_n1z,
0560 float a_r1,float a_g1,float a_b1,float a_a1,
0561 float a_p2x,float a_p2y,float a_p2z,float a_p2w,
0562 float a_n2x,float a_n2y,float a_n2z,
0563 float a_r2,float a_g2,float a_b2,float a_a2,
0564 float a_p3x,float a_p3y,float a_p3z,float a_p3w,
0565 float a_n3x,float a_n3y,float a_n3z,
0566 float a_r3,float a_g3,float a_b3,float a_a3){
0567
0568 float r = (a_r1+a_r2+a_r3)/3.0f;
0569 float g = (a_g1+a_g2+a_g3)/3.0f;
0570 float b = (a_b1+a_b2+a_b3)/3.0f;
0571 float a = (a_a1+a_a2+a_a3)/3.0f;
0572 colorf col(r,g,b,a);
0573
0574 return _add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
0575 a_n1x,a_n1y,a_n1z,
0576 a_p2x,a_p2y,a_p2z,a_p2w,
0577 a_n2x,a_n2y,a_n2z,
0578 a_p3x,a_p3y,a_p3z,a_p3w,
0579 a_n3x,a_n3y,a_n3z,
0580 col);
0581 return true;
0582 }
0583 public:
0584 primvis(zb_action& a_zb):m_this(a_zb){}
0585 virtual ~primvis(){}
0586 public:
0587 primvis(const primvis& a_from)
0588 :primitive_visitor(a_from)
0589 ,m_this(a_from.m_this)
0590 {}
0591 primvis& operator=(const primvis& a_from){
0592 primitive_visitor::operator=(a_from);
0593 return *this;
0594 }
0595 protected:
0596 static void zinit(zb::point& a_p,float a_x,float a_y,float a_z) {
0597 a_p.x = fround(a_x); //float -> int
0598 a_p.y = fround(a_y); //float -> int
0599 a_p.z = (zb::ZZ)a_z; //float -> double
0600 }
0601
0602 unsigned int npix(float a_size) {
0603 // 0 -> 0
0604 // 1 -> 0
0605 // 2 -> 1 3x3
0606 // 3 -> 1 3x3
0607 // 4 -> 2 5x5
0608 // 5 -> 2 5x5
0609 // 6 -> 3 7x7
0610 unsigned int num = (unsigned int)a_size;
0611 unsigned int num_2 = num/2;
0612 if(2*num_2==num) {num++;num_2 = num/2;}
0613 return num_2;
0614 }
0615
0616 bool _add_point(float a_x,float a_y,float a_z,float a_r,float a_g,float a_b,float a_a){
0617 m_this.m_zb.set_depth_test(m_this.m_DEPTH_TEST);
0618 m_this.m_zb.set_blend(m_this.m_blend);
0619
0620 m_this.m_vp_mtx.mul_3f_opt(a_x,a_y,a_z,m_tmp);
0621 a_z *= -1;
0622
0623 zb::point p;
0624 zinit(p,a_x,a_y,a_z);
0625
0626 zb::buffer::ZPixel pix;
0627 zb::buffer::rgba2pix(a_r,a_g,a_b,a_a,pix);
0628 m_this.m_zb.draw_point(p,pix,npix(m_this.m_point_size));
0629
0630 return true;
0631 }
0632
0633 bool _add_triangle(float a_p1x,float a_p1y,float a_p1z,float /*a_p1w*/,
0634 float a_n1x,float a_n1y,float a_n1z,
0635 float a_p2x,float a_p2y,float a_p2z,float /*a_p2w*/,
0636 float a_n2x,float a_n2y,float a_n2z,
0637 float a_p3x,float a_p3y,float a_p3z,float /*a_p3w*/,
0638 float a_n3x,float a_n3y,float a_n3z,
0639 const colorf& a_color){
0640
0641 float p1x = a_p1x;float p1y = a_p1y;float p1z = a_p1z;//float p1w = a_p1w;
0642 float p2x = a_p2x;float p2y = a_p2y;float p2z = a_p2z;//float p2w = a_p2w;
0643 float p3x = a_p3x;float p3y = a_p3y;float p3z = a_p3z;//float p3w = a_p3w;
0644
0645 m_this.m_vp_mtx.mul_3f_opt(p1x,p1y,p1z,m_tmp);
0646 m_this.m_vp_mtx.mul_3f_opt(p2x,p2y,p2z,m_tmp);
0647 m_this.m_vp_mtx.mul_3f_opt(p3x,p3y,p3z,m_tmp);
0648 p1z *= -1;
0649 p2z *= -1;
0650 p3z *= -1;
0651
0652 if(m_this.m_POLYGON_OFFSET_FILL){
0653 //note : gopaw pawex9,14,15,21 with "lego" (drawing cubes) are sensitive to the below epsil.
0654 // zs are in [-1,1]
0655 float epsil = 1e-4f;
0656 p1z -= epsil;
0657 p2z -= epsil;
0658 p3z -= epsil;
0659 }
0660
0661 typedef zb::ZZ ZZ; //double
0662
0663 plane<vec3d> pn(
0664 vec3<ZZ>(p1x,p1y,p1z),
0665 vec3<ZZ>(p2x,p2y,p2z),
0666 vec3<ZZ>(p3x,p3y,p3z)
0667 );
0668 if(!pn.is_valid()) return true;
0669
0670 ZZ C = pn.normal()[2];
0671
0672 if(m_this.m_CULL_FACE){
0673 if(m_this.m_ccw) {
0674 if(C<=0) return true;
0675 } else {
0676 if(C>=0) return true;
0677 }
0678 }
0679
0680 ZZ A = pn.normal()[0];
0681 ZZ B = pn.normal()[1];
0682 ZZ D = -pn.distance_from_origin();
0683
0684 zb::point list[3];
0685 zinit(list[0],p1x,p1y,p1z);
0686 zinit(list[1],p2x,p2y,p2z);
0687 zinit(list[2],p3x,p3y,p3z);
0688
0689 m_this.m_zb.set_depth_test(m_this.m_DEPTH_TEST);
0690 m_this.m_zb.set_blend(m_this.m_blend);
0691
0692 colorf frag_color = a_color;
0693
0694 if(m_this.m_light_on) { // same logic as toolx/wasm/webgl.js:
0695
0696 float nx = (a_n1x+a_n2x+a_n3x)/3.0f;
0697 float ny = (a_n1y+a_n2y+a_n3y)/3.0f;
0698 float nz = (a_n1z+a_n2z+a_n3z)/3.0f;
0699
0700 m_this.m_normal_matrix.mul_dir_3f_opt(nx,ny,nz,m_tmp);
0701
0702 vec3f _normal(nx,ny,nz);_normal.normalize();
0703
0704 float _dot = _normal.dot(m_this.m_light_direction);
0705
0706 if(_dot<0.0f) {
0707 _dot *= -1.0f;
0708
0709 colorf _tmp = m_this.m_light_color;
0710 _tmp *= _dot;
0711 _tmp += m_this.m_light_ambient;
0712
0713 frag_color *= _tmp;
0714
0715 } else {
0716 frag_color *= m_this.m_light_ambient;
0717 }
0718
0719 frag_color.clamp();
0720 frag_color.set_a(a_color.a());
0721
0722 }
0723
0724 zb::buffer::ZPixel pix;
0725 color2pix(frag_color,pix);
0726 m_this.m_zb.draw_polygon(3,list,A,B,C,D,pix);
0727
0728 return true;
0729 }
0730 protected:
0731 zb_action& m_this;
0732 private: //optimize:
0733 float m_tmp[3];
0734 };
0735
0736 protected:
0737 zb_manager& m_mgr;
0738 mat4f m_vp_mtx;
0739 zb::buffer m_zb;
0740 primvis m_pv;
0741 colorf m_light_color;
0742 colorf m_light_ambient;
0743 vec3f m_light_direction;
0744 vec3f m_normal;
0745
0746 // to be restored in restore_state() :
0747 mat4f m_proj;
0748 mat4f m_model;
0749 mat4f m_normal_matrix;
0750 colorf m_rgba;
0751 bool m_ccw;
0752 bool m_POLYGON_OFFSET_FILL;
0753 bool m_CULL_FACE;
0754 bool m_POINT_SMOOTH;
0755 bool m_LINE_SMOOTH;
0756 float m_line_width;
0757 float m_point_size;
0758 bool m_light_on;
0759 bool m_DEPTH_TEST;
0760 bool m_blend;
0761 private: //optimize:
0762 float m_tmp[4];
0763 };
0764
0765 }}
0766
0767 #endif