00001 #include "color_id_texture.H"
00002 #include "ref_image.H"
00003
00004 using namespace mlib;
00005
00006 HASH RefImage::_hash(16);
00007 HASH RefImage2::_hash(16);
00008 HASH IDRefImage::_hash(16);
00009 HASH TexMemRefImage::_hash(16);
00010
00011 uint IDRefImage::_red_bits = 0;
00012 uint IDRefImage::_green_bits = 0;
00013 uint IDRefImage::_blue_bits = 0;
00014 uint IDRefImage::_alpha_bits = 0;
00015
00016 bool IDRefImage::_nonstandard_bits = false;
00017
00018 IDRefImage* IDRefImage::_instance = 0;
00019
00020
00021
00022
00023 RefImage*
00024 RefImage::lookup(CVIEWptr& v)
00025 {
00026 if (!v) {
00027 err_msg( "RefImage::lookup: error -- view is nil");
00028 return 0;
00029 }
00030 if (!v->impl()) {
00031 err_msg( "RefImage::lookup: error -- view->impl() is nil");
00032 return 0;
00033 }
00034
00035
00036 long key = (long)v->impl();
00037 RefImage* ret = (RefImage*) _hash.find(key);
00038 if (!ret && (ret = new RefImage(v)))
00039 _hash.add(key, (void *)ret);
00040 return ret;
00041 }
00042
00043 void
00044 RefImage::draw_FB() const
00045 {
00046
00047
00048
00049 glMatrixMode(GL_MODELVIEW);
00050 glPushMatrix();
00051 glLoadIdentity();
00052 glMatrixMode(GL_PROJECTION);
00053 glPushMatrix();
00054 glLoadMatrixd(VIEW::peek()->pix_proj().transpose().matrix());
00055
00056 glRasterPos2i(0,0);
00057
00058 glPushAttrib(GL_ENABLE_BIT);
00059 glDisable(GL_BLEND);
00060
00061 glDrawPixels(_width,_height,_format,_type,_values);
00062
00063 glPopAttrib();
00064
00065 glPopMatrix();
00066 glMatrixMode(GL_MODELVIEW);
00067 glPopMatrix();
00068 }
00069
00070 int
00071 RefImage::read_file(char* file)
00072 {
00073
00074
00075
00076
00077 Image img;
00078
00079
00080 if (!img.load_file(file)) {
00081 err_msg( "RefImage::read_file: can't read file %s", file);
00082 return 0;
00083 }
00084
00085
00086 resize(img.width(), img.height());
00087
00088
00089
00090
00091 uchar* data = img.data();
00092 uint i=0;
00093 switch(img.bpp()) {
00094 case 4:
00095
00096 for (i=0; i<max(); i++) {
00097 val(i) = build_rgba(data[0], data[1], data[2], data[3]);
00098 data += 4;
00099 }
00100 break;
00101 case 3:
00102
00103 for (i=0; i<max(); i++) {
00104 val(i) = build_rgba(data[0], data[1], data[2]);
00105 data += 3;
00106 }
00107 break;
00108 case 2:
00109
00110 for (i=0; i<max(); i++) {
00111 val(i) = build_rgba(data[0], data[0], data[0], data[1]);
00112 data += 2;
00113 }
00114 break;
00115 case 1:
00116
00117 for (i=0; i<max(); i++) {
00118 val(i) = build_rgba(data[0], data[0], data[0]);
00119 data += 1;
00120 }
00121 break;
00122 default:
00123
00124 err_msg( "RefImage::read_file: unknown bits per pixel (%d) in image", img.bpp());
00125 return 0;
00126 }
00127
00128
00129 return 1;
00130 }
00131
00132 void
00133 RefImage::fill(uint fill_color)
00134 {
00135 for (uint i=0; i<_max; i++) {
00136 val(i) = fill_color;
00137 }
00138 }
00139
00140 int
00141 RefImage::write_file(char* file)
00142 {
00143 if (_format != GL_RGBA && _format != GL_RGB) {
00144 err_msg( "RefImage::write_file: unsupported format (%x)", _format);
00145 return 0;
00146 }
00147
00148 return Image::write_png(
00149 _width,
00150 _height,
00151 (_format==GL_RGBA) ? 4 : 3,
00152 (GLubyte*)_values,
00153 str_ptr(file)
00154 );
00155 }
00156
00157 int
00158 RefImage::copy_rgb(Image& img) const
00159 {
00160
00161
00162
00163
00164 if (!img.resize(_width,_height,3)) {
00165 err_msg( "RefImage::copy_rgb_image: can't resize image");
00166 return 0;
00167 }
00168
00169
00170 uchar* d = img.data();
00171 for (uint i=0; i<_max; i++) {
00172 uint v = val(i);
00173 *d++ = rgba_to_r(v);
00174 *d++ = rgba_to_g(v);
00175 *d++ = rgba_to_b(v);
00176 }
00177
00178 return 1;
00179 }
00180
00181 inline void
00182 set_default_gl_state()
00183 {
00184 glLineWidth(1.0);
00185 glDepthMask(GL_TRUE);
00186 glDepthFunc(GL_LESS);
00187 glEnable(GL_DEPTH_TEST);
00188 glDisable(GL_NORMALIZE);
00189 glDisable(GL_BLEND);
00190 glEnable(GL_CULL_FACE);
00191 }
00192
00193 void
00194 RefImage::update()
00195 {
00196 glDrawBuffer(GL_BACK);
00197 glReadBuffer(GL_BACK);
00198
00199 VIEWptr view = VIEW::peek();
00200
00201
00202 view->setup_lights();
00203
00204 glPushAttrib(GL_ENABLE_BIT);
00205
00206
00207 set_default_gl_state();
00208
00209 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00210 glEnable(GL_COLOR_MATERIAL);
00211 glShadeModel(GL_SMOOTH);
00212
00213 glViewport(0,0,_width,_height);
00214
00215 glClearColor(1,1,1,1);
00216 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00217
00218 draw_objects(view->drawn());
00219
00220 glReadPixels(0,0,_width,_height,_format,_type,_values);
00221
00222 glPopAttrib();
00223
00224 int w, h;
00225 VIEW_SIZE(w,h);
00226 glViewport(0,0,w,h);
00227 }
00228
00229 void
00230 RefImage::draw_objects(CGELlist& drawn) const
00231 {
00232 VIEWptr view = VIEW::peek();
00233
00234
00235 glMatrixMode(GL_PROJECTION);
00236 glLoadMatrixd(view->cam()->projection_xform().transpose().matrix());
00237
00238
00239 Wtransf mat = view->cam()->xform().transpose();
00240
00241 glMatrixMode(GL_MODELVIEW);
00242 for (int i=0; i < drawn.num(); i++) {
00243 glLoadMatrixd(mat.matrix());
00244 drawn[i]->draw_ref_img(_ref_img_type);
00245 }
00246 }
00247
00248 bool
00249 RefImage::find_val_in_box(uint v, Cpoint2i& center, uint rad) const
00250 {
00251
00252
00253
00254
00255
00256 uint min_x = (uint) ::max(center[0] - rad, uint(0));
00257 uint max_x = (uint) ::min(center[0] + rad, uint(_width-1));
00258 uint min_y = (uint) ::max(center[1] - rad, uint(0));
00259 uint max_y = (uint) ::min(center[1] + rad, uint(_height-1));
00260
00261 for (uint y=min_y; y<=max_y; y++) {
00262 uint d = y * _width;
00263 for (uint x=min_x; x<=max_x; x++)
00264 if (val(d + x) == v)
00265 return true;
00266 }
00267 return false;
00268 }
00269
00270 bool
00271 RefImage::find_val_in_box(uint v, uint mask , Cpoint2i& center, uint rad, int nbr) const
00272 {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 uint min_x = (uint) ::max(center[0] - rad, uint(0));
00283 uint max_x = (uint) ::min(center[0] + rad, uint(_width-1));
00284 uint min_y = (uint) ::max(center[1] - rad, uint(0));
00285 uint max_y = (uint) ::min(center[1] + rad, uint(_height-1));
00286
00287 for (uint y=min_y; y<=max_y; y++) {
00288 uint d = y * _width;
00289 for (uint x=min_x; x<=max_x; x++)
00290 if ( (val(d + x) & mask) == (v & mask)) {
00291
00292
00293
00294 int found_l = (int)(val(d+x)& 0x000000ff);
00295 int target_l = (int)(v & 0x000000ff);
00296 if ( abs( found_l - target_l ) <= nbr ) {
00297 return true;
00298 }
00299 }
00300 }
00301 return false;
00302 }
00303
00304
00305
00306
00307 RefImage2*
00308 RefImage2::lookup(CVIEWptr& v)
00309 {
00310 if (!v) {
00311 err_msg( "RefImage2::lookup: error -- view is nil");
00312 return 0;
00313 }
00314 if (!v->impl()) {
00315 err_msg( "RefImage2::lookup: error -- view->impl() is nil");
00316 return 0;
00317 }
00318
00319
00320 long key = (long)v->impl();
00321 RefImage2* ret = (RefImage2*) _hash.find(key);
00322 if (!ret && (ret = new RefImage2(v)))
00323 _hash.add(key, (void *)ret);
00324 return ret;
00325 }
00326
00327
00328
00329
00330 IDRefImage*
00331 IDRefImage::lookup(CVIEWptr& v)
00332 {
00333 if (!v) {
00334 err_msg( "IDRefImage::lookup: error -- view is nil");
00335 return 0;
00336 }
00337 if (!v->impl()) {
00338 err_msg( "IDRefImage::lookup: error -- view->impl() is nil");
00339 return 0;
00340 }
00341
00342
00343 long key = (long)v->impl();
00344 IDRefImage* ret = (IDRefImage*) _hash.find(key);
00345 if (!ret && (ret = new IDRefImage(v)))
00346 _hash.add(key, (void *)ret);
00347 return ret;
00348 }
00349
00350 IDRefImage::IDRefImage(CVIEWptr& v) :
00351 RefImage(v, RCOLOR_ID)
00352 {
00353 _ref_img_type = RefImageClient::REF_IMG_ID;
00354 setup_bits(v);
00355 }
00356
00357 void
00358 IDRefImage::setup_bits(CVIEWptr& view)
00359 {
00360 if (!view)
00361 return;
00362
00363
00364 if (_red_bits || _green_bits || _blue_bits) {
00365
00366 if (view->win()->red_bits() != _red_bits ||
00367 view->win()->green_bits() != _green_bits ||
00368 view->win()->blue_bits() != _blue_bits ||
00369 view->win()->alpha_bits() != _alpha_bits)
00370 err_msg( "IDRefImage::setup_bits: Error: mismatch of bits");
00371 return;
00372 }
00373 _red_bits = view->win()->red_bits();
00374 _green_bits = view->win()->green_bits();
00375 _blue_bits = view->win()->blue_bits();
00376 _alpha_bits = view->win()->alpha_bits();
00377
00378
00379 _nonstandard_bits = (
00380 (_red_bits != 8) ||
00381 (_green_bits != 8) ||
00382 (_blue_bits != 8)
00383 );
00384
00385 uint r,g,b,a,s,d;
00386
00387 r = view->win()->accum_red_bits();
00388 g = view->win()->accum_green_bits();
00389 b = view->win()->accum_blue_bits();
00390 a = view->win()->accum_alpha_bits();
00391 s = view->win()->stencil_bits();
00392 d = view->win()->depth_bits();
00393
00394 err_msg( "");
00395
00396 err_msg( "GL Vendor: %s", glGetString(GL_VENDOR));
00397 err_msg( "GL Renderer: %s", glGetString(GL_RENDERER));
00398 err_msg( "GL Version: %s", glGetString(GL_VERSION));
00399
00400 err_msg( "GL Color RGBA: %u,%u,%u,%u",
00401 _red_bits, _green_bits, _blue_bits, _alpha_bits);
00402 err_msg( "GL Accum RGBA: %u,%u,%u,%u", r,g,b,a);
00403 err_msg( "GL Stencil Bits: %u", s);
00404 err_msg( "GL Depth Bits: %u", d);
00405
00406 GLint num_units=0;
00407 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num_units);
00408 err_msg( "Texture units: %d", num_units);
00409
00410 err_msg( "");
00411
00412 }
00413
00414 void
00415 IDRefImage::draw_objects(CGELlist& drawn) const
00416 {
00417 int i;
00418
00419 VIEWptr view = VIEW::peek();
00420
00421
00422 glMatrixMode(GL_PROJECTION);
00423 glLoadMatrixd(view->cam()->projection_xform().transpose().matrix());
00424
00425
00426 Wtransf mat = view->cam()->xform().transpose();
00427
00428
00429 glMatrixMode(GL_MODELVIEW);
00430
00431
00432
00433
00434
00435
00436
00437
00438 for (i=0; i < drawn.num(); i++) {
00439 glLoadMatrixd(mat.matrix());
00440 drawn[i]->draw_ref_img(RefImageClient::REF_IMG_ID_PRE1);
00441 }
00442
00443
00444 glClear(GL_DEPTH_BUFFER_BIT);
00445
00446
00447 for (i=0; i < drawn.num(); i++) {
00448 glLoadMatrixd(mat.matrix());
00449 drawn[i]->draw_ref_img(RefImageClient::REF_IMG_ID_PRE2);
00450 }
00451
00452
00453 glClear(GL_DEPTH_BUFFER_BIT);
00454 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
00455
00456
00457 for (i=0; i < drawn.num(); i++) {
00458 glLoadMatrixd(mat.matrix());
00459 drawn[i]->draw_ref_img(RefImageClient::REF_IMG_ID_PRE3);
00460 }
00461
00462
00463 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00464
00465
00466 for (i=0; i < drawn.num(); i++) {
00467 glLoadMatrixd(mat.matrix());
00468 drawn[i]->draw_ref_img(RefImageClient::REF_IMG_ID_PRE4);
00469 }
00470
00471
00472 for (i=0; i < drawn.num(); i++) {
00473 glLoadMatrixd(mat.matrix());
00474 drawn[i]->draw_ref_img(RefImageClient::REF_IMG_ID);
00475 }
00476 }
00477
00478 bool
00479 IDRefImage::search(
00480 CNDCpt& c,
00481 double screen_pix_rad,
00482 CSimplexFilter& filt,
00483 Point2i& hit
00484 )
00485 {
00486
00487
00488
00489
00490
00491
00492 screen_pix_rad = ::max(0.0, screen_pix_rad);
00493
00494
00495 double ndc_rad = VIEW::pix_to_ndc_scale() * screen_pix_rad;
00496
00497
00498 double R = _half_min_dim * ndc_rad;
00499
00500
00501 Point2i center = ndc_to_pix(c);
00502 int min_x = ::max(center[0] - int(ceil(R)), 0);
00503 int max_x = ::min(center[0] + int(ceil(R)), int(_width-1));
00504 int min_y = ::max(center[1] - int(ceil(R)), 0);
00505 int max_y = ::min(center[1] + int(ceil(R)), int(_height-1));
00506
00507 bool ret = 0;
00508 double min_dist = 0, d;
00509 for (int y = min_y; y <= max_y; y++) {
00510 for (int x = min_x; x <= max_x; x++) {
00511 Point2i cur(x,y);
00512 if ((d = cur.dist(center)) < R &&
00513 filt.accept(simplex(cur)) &&
00514 (!ret || d < min_dist)) {
00515 ret = true;
00516 hit = cur;
00517 min_dist = d;
00518 }
00519 }
00520 }
00521 return ret;
00522 }
00523
00524 Bsimplex*
00525 IDRefImage::find_near_simplex(
00526 CNDCpt& c,
00527 double screen_pix_rad,
00528 CSimplexFilter& filt
00529 )
00530 {
00531 Point2i hit;
00532
00533 if (search(c, screen_pix_rad, filt, hit))
00534 return simplex(hit);
00535 return 0;
00536 }
00537
00538 Bedge*
00539 IDRefImage::find_neighbor(CNDCpt& p, Bedge* current, int radius) const
00540 {
00541
00542 Point2i center = ndc_to_pix(p);
00543 Bedge* temp = 0;
00544 Point2i check;
00545 for (int rad = 0; rad <= radius; rad++) {
00546 for (int i = -rad; i <= rad; i++) {
00547 for (int j = -rad; j <= rad; j++) {
00548 if ((abs(i)==rad) || (abs(j)==rad)) {
00549 check = Point2i(center[0]+i, center[1]+j);
00550 if (pix_in_range(check) &&
00551 (temp = edge(check)) &&
00552 (temp != current)
00553 && (temp->patch() == current->patch()) && (temp->is_sil()))
00554 return temp;
00555 }
00556 }
00557 }
00558 }
00559
00560 return 0;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 ARRAY<Bedge*>
00598 IDRefImage::find_all_neighbors(CNDCpt& p, Patch* patch, int radius) const
00599 {
00600 Point2i center = ndc_to_pix(p);
00601
00602 return find_all_neighbors(center, patch, radius);
00603 }
00604
00605 ARRAY<Bedge*>
00606 IDRefImage::find_all_neighbors(Cpoint2i& center, Patch* patch, int radius) const
00607 {
00608 static ARRAY<Bedge*> neighbors(radius*radius);
00609 neighbors.clear();
00610
00611 Bedge* temp = 0;
00612 Point2i check;
00613 for (int i = -radius; i <= radius; i++) {
00614 for (int j = -radius; j <= radius; j++) {
00615 check = center + Vec2i(i,j);
00616 if (!pix_in_range(check))
00617 continue;
00618 temp = edge(check);
00619 if (!temp)
00620 continue;
00621 if ((temp->patch() == patch) && (temp->is_sil()))
00622 neighbors.add_uniquely(temp);
00623 }
00624 }
00625
00626 return neighbors;
00627 }
00628
00629 bool
00630 IDRefImage::is_simplex_near(CNDCpt& p, const Bsimplex* simp, int radius) const
00631 {
00632
00633 Point2i center = ndc_to_pix(p);
00634 Bsimplex* temp = 0;
00635 Point2i check;
00636 for (int rad = 0; rad <= radius; rad++) {
00637 for (int i = -rad; i <= rad; i++) {
00638 for (int j = -rad; j <= rad; j++) {
00639 if ((abs(i)==rad) || (abs(j)==rad)) {
00640 check = Point2i(center[0]+i, center[1]+j);
00641 if (pix_in_range(check) &&
00642 (temp = simplex(check)) &&
00643 (temp == simp))
00644 return true;
00645 }
00646 }
00647 }
00648 }
00649
00650 return false;
00651 }
00652
00653 bool
00654 IDRefImage::is_patch_sil_edge_near(
00655 CNDCpt& ndc,
00656 const Patch* patch,
00657 int radius
00658 ) const
00659 {
00660
00661 Point2i center = ndc_to_pix(ndc);
00662 Point2i check;
00663 for (int rad = 0; rad <= radius; rad++) {
00664 for (int i = -rad; i <= rad; i++) {
00665 for (int j = -rad; j <= rad; j++) {
00666 if ((abs(i)==rad) || (abs(j)==rad)) {
00667 check = Point2i(center[0]+i, center[1]+j);
00668 if (is_patch_sil_edge(check, patch)) return true;
00669 }
00670 }
00671 }
00672 }
00673 return false;
00674 }
00675
00676 Bface*
00677 VisRefImage::get_face(CNDCpt& cur, double screen_rad)
00678 {
00679
00680
00681
00682 Bface* ret = (Bface*)get_simplex(cur, screen_rad, FrontFacingBfaceFilter());
00683 return ret ? ret : (Bface*)get_simplex(cur, screen_rad, BfaceFilter());
00684 }
00685
00686 Bface_list
00687 VisRefImage::get_faces(const PIXEL_list& pix, double screen_rad)
00688 {
00689
00690
00691 Bface_list ret;
00692 for (int i=0; i<pix.num(); i++) {
00693 Bface* f = get_face(pix[i], screen_rad);
00694 if (f)
00695 ret.add_uniquely(f);
00696 }
00697 return ret;
00698 }
00699
00700
00701 Bface*
00702 VisRefImage::get_face_bc (
00703 Wvec& bc,
00704 CNDCpt& ndc,
00705 double rad
00706 )
00707 {
00708
00709
00710
00711 Bface* f = get_face(ndc, rad);
00712
00713
00714
00715 if (f)
00716 f->near_pt(ndc, bc);
00717
00718 return f;
00719 }
00720
00721 Bface*
00722 VisRefImage::get_sub_face(
00723 int level,
00724 Wvec& bc,
00725 CNDCpt& ndc,
00726 double rad
00727 )
00728 {
00729 Bface* f = get_face_bc(bc, ndc, rad);
00730
00731 if (level == 0)
00732 return f;
00733 else if (f && LMESH::isa(f->mesh()))
00734 return ((Lface*)f)->bc_to_level(level, bc);
00735 else
00736 return 0;
00737 }
00738
00739 Bface*
00740 VisRefImage::get_edit_face(
00741 Wvec& bc,
00742 CNDCpt& ndc,
00743 double rad
00744 )
00745 {
00746 Bface* f = get_face_bc(bc, ndc, rad);
00747
00748 if (f && LMESH::isa(f->mesh()))
00749 return ((Lface*)f)->bc_to_edit_level(bc);
00750 else
00751 return 0;
00752 }
00753
00754 void
00755 IDRefImage::update()
00756 {
00757 glDrawBuffer(GL_BACK);
00758 glReadBuffer(GL_BACK);
00759
00760
00761 glDisable(GL_LIGHTING);
00762 glDisable(GL_LIGHT0);
00763 glDisable(GL_LIGHT1);
00764
00765
00766 set_default_gl_state();
00767
00768 glDisable(GL_COLOR_MATERIAL);
00769 glShadeModel(GL_FLAT);
00770
00771 glViewport(0,0,_width,_height);
00772
00773 glClearColor(0,0,0,0);
00774 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00775
00776 draw_objects(VIEW::peek()->drawn());
00777
00778 glReadPixels(0,0,_width,_height,_format,_type,_values);
00779
00780 int w, h;
00781 VIEW_SIZE(w,h);
00782 glViewport(0,0,w,h);
00783 }
00784
00785
00786
00787
00788
00789
00790 class VisRefImageFactory : public BaseVisRefImageFactory {
00791 public:
00792 virtual BaseVisRefImage* produce(CVIEWptr& v) { return new VisRefImage(v); }
00793 };
00794
00795 VisRefImage::VisRefImage(CVIEWptr& v) :
00796 IDRefImage(v)
00797 {
00798 reset();
00799 observe();
00800 }
00801
00802 void
00803 VisRefImage::init()
00804 {
00805 if (!BaseVisRefImage::_factory)
00806 BaseVisRefImage::_factory = new VisRefImageFactory;
00807 }
00808
00809 bool
00810 VisRefImage::need_update()
00811 {
00812
00813
00814
00815
00816 int w, h;
00817 _view->get_size(w,h);
00818 double scale = 1.0;
00819 int ref_w = 256, ref_h = 256;
00820 int min_side = min(w,h);
00821 if (min_side <= 256) {
00822 ref_w = w;
00823 ref_h = h;
00824 } else {
00825 scale = min_side / 256.0;
00826 if (w > h)
00827 ref_w = (int)round(w/scale);
00828 else
00829 ref_h = (int)round(h/scale);
00830 }
00831
00832 return (resize(ref_w,ref_h) || _dirty);
00833 }
00834
00835 void
00836 VisRefImage::debug(CNDCpt& p) const
00837 {
00838 cerr << "VisRefImage::debug: ndc: " << p;
00839 uint id = ndc_to_uint(p);
00840 cerr << ", uint: " << id;
00841 GLuint v = val(id);
00842 cerr << ", val: " << v;
00843 uint key = rgba_to_key(v);
00844 cerr << ", key: " << key;
00845 Bsimplex* s = Bsimplex::lookup(key);
00846 cerr << ", simplex: " << s;
00847 cerr << endl;
00848 }
00849
00850 void
00851 VisRefImage::draw_objects(CGELlist& drawn) const
00852 {
00853 VIEWptr view = VIEW::peek();
00854
00855
00856 glMatrixMode(GL_PROJECTION);
00857 glLoadMatrixd(view->cam()->projection_xform().transpose().matrix());
00858
00859
00860 Wtransf mat = view->cam()->xform().transpose();
00861
00862 glMatrixMode(GL_MODELVIEW);
00863 for (int i=0; i < drawn.num(); i++) {
00864 glLoadMatrixd(mat.matrix());
00865 drawn[i]->draw_vis_ref();
00866 }
00867 }
00868
00869 void
00870 VisRefImage::observe()
00871 {
00872 if (_view) {
00873
00874 subscribe_all_mesh_notifications();
00875
00876
00877 _view->cam()->data()->add_cb(this);
00878
00879
00880 disp_obs();
00881
00882
00883 exist_obs();
00884
00885
00886 xform_obs();
00887
00888
00889 WORLD::get_world()->schedule(this);
00890 }
00891 }
00892
00893 void
00894 VisRefImage::unobserve()
00895 {
00896 if (_view) {
00897
00898 unsubscribe_all_mesh_notifications();
00899
00900
00901 _view->cam()->data()->rem_cb(this);
00902
00903
00904 unobs_display();
00905
00906
00907 unobs_exist();
00908
00909
00910 unobs_xform();
00911
00912
00913 WORLD::get_world()->unschedule(this);
00914 }
00915 }
00916
00917 int
00918 VisRefImage::tick()
00919 {
00920 if (_countup++ > 4 && _dirty)
00921 update();
00922 return 1;
00923 }
00924
00925 uint
00926 IDRefImage::key_to_rgba2(uint key)
00927 {
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 #if defined(WIN32) || defined(i386)
00943
00944
00945 if (_nonstandard_bits) {
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 static uint mask_r = ((1<<_red_bits) - 1);
00969 static uint mask_g = ((1<<_green_bits) - 1) << (_red_bits);
00970 static uint mask_b = ((1<<_blue_bits) - 1) << (_red_bits + _green_bits);
00971
00972
00973
00974 static int shift_r = 8 - _red_bits;
00975 static int shift_g = 16 - _red_bits - _green_bits;
00976 static int shift_b = 24 - _red_bits - _green_bits - _blue_bits;
00977
00978 return (((key & mask_r) << shift_r) |
00979 ((key & mask_g) << shift_g) |
00980 ((key & mask_b) << shift_b));
00981 }
00982
00983
00984
00985 return key;
00986
00987 #else
00988
00989
00990
00991
00992
00993
00994 return ((key << 8) | 0xff);
00995
00996 #endif
00997 }
00998
00999 uint
01000 IDRefImage::rgba_to_key2(uint rgba)
01001 {
01002
01003
01004 #if defined(WIN32) || defined(i386)
01005 if (_nonstandard_bits) {
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024 static uint mask_r = ((1<<_red_bits) -1) << ( 8 - _red_bits);
01025 static uint mask_g = ((1<<_green_bits)-1) << (16 - _green_bits);
01026 static uint mask_b = ((1<<_blue_bits) -1) << (24 - _blue_bits);
01027
01028
01029
01030 static int shift_r = 8 - _red_bits;
01031 static int shift_g = 16 - _red_bits - _green_bits;
01032 static int shift_b = 24 - _red_bits - _green_bits - _blue_bits;
01033
01034 return (((rgba & mask_r) >> shift_r) |
01035 ((rgba & mask_g) >> shift_g) |
01036 ((rgba & mask_b) >> shift_b));
01037
01038 }
01039
01040
01041
01042
01043
01044 if (_alpha_bits == 8)
01045 return rgba;
01046 else
01047 return (rgba & 0xffffff);
01048
01049 #else
01050
01051
01052
01053
01054
01055 return (rgba >> 8);
01056 #endif
01057 }
01058
01059
01060
01061
01062 static bool debug_tmri = Config::get_var_bool("DEBUG_TEX_MEM_REF_IMAGE",false);
01063
01064 TexMemRefImage::TexMemRefImage(
01065 CVIEWptr& v,
01066 RefImageClient::ref_img_t img_type) :
01067 _view(v),
01068 _ref_img_type(img_type),
01069 _texture(0)
01070 {
01071 _texture = new TEXTUREgl();
01072 assert(_texture);
01073
01074
01075 _texture->set_expand_image(false);
01076
01077 _texture->set_tex_unit(TexUnit::REF_IMG + GL_TEXTURE0);
01078 _texture->set_mipmap(false);
01079 _texture->set_tex_fn(GL_REPLACE);
01080 }
01081
01082 bool
01083 TexMemRefImage::resize(const Point2i& dims)
01084 {
01085
01086 assert(_texture);
01087
01088
01089
01090 const Image& img = _texture->image();
01091 if (debug_tmri && (static_cast<int>(img.width()) != dims[0] ||
01092 static_cast<int>(img.height()) != dims[1])) {
01093 cerr << "TexMemRefImage::resize: changing size from"
01094 << img.width() << "x" << img.height() << " to "
01095 << dims[0] << "x" << dims[1] << endl;
01096 }
01097 return _texture->image().resize(dims[0],dims[1]);
01098 }
01099
01100 TexMemRefImage*
01101 TexMemRefImage::lookup(CVIEWptr& v)
01102 {
01103 if (!v) {
01104 err_msg( "TexMemRefImage::lookup: error -- view is nil");
01105 return 0;
01106 }
01107 if (!v->impl()) {
01108 err_msg( "TexMemRefImage::lookup: error -- view->impl() is nil");
01109 return 0;
01110 }
01111
01112
01113 long key = (long)v->impl();
01114 TexMemRefImage* ret = (TexMemRefImage*) _hash.find(key);
01115 if (!ret && (ret = new TexMemRefImage(v)))
01116 _hash.add(key, (void *)ret);
01117 return ret;
01118 }
01119
01120 void
01121 TexMemRefImage::update()
01122 {
01123 glDrawBuffer(GL_BACK);
01124 glReadBuffer(GL_BACK);
01125
01126 VIEWptr view = VIEW::peek();
01127
01128 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
01129
01130
01131 view->setup_lights();
01132
01133
01134 set_default_gl_state();
01135
01136 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
01137 glEnable(GL_COLOR_MATERIAL);
01138 glShadeModel(GL_SMOOTH);
01139
01140 glClearColor(1,1,1,1);
01141 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01142
01143 draw_objects(view->drawn());
01144
01145 read_FB();
01146
01147 glPopAttrib();
01148 }
01149
01150 inline bool
01151 is_proper_3d_object(CGELptr& gel)
01152 {
01153 return gel && gel->bbox().valid();
01154 }
01155
01156 void
01157 TexMemRefImage::draw_objects(CGELlist& drawn) const
01158 {
01159 assert(_view);
01160
01161
01162 GELlist _blended;
01163 _blended.clear();
01164 GELlist _opaque;
01165 _opaque.clear();
01166
01167 for (int i=0; i < drawn.num(); i++ ) {
01168 if (!drawn[i]->is_3D()) {
01169 ;
01170 } else if (drawn[i]->can_do_halo() && GEOM::do_halo_ref()) {
01171 _blended += drawn[i];
01172 } else {
01173 _opaque += drawn[i];
01174 }
01175 }
01176
01177 _blended.sort(GL_VIEW::depth_compare);
01178
01179
01180 glMatrixMode(GL_PROJECTION);
01181 glPushMatrix();
01182 glLoadMatrixd(_view->cam()->projection_xform().transpose().matrix());
01183
01184 glMatrixMode(GL_MODELVIEW);
01185 glPushMatrix();
01186
01187
01188
01189
01190 Wtransf mat = _view->cam()->xform().transpose();
01191
01192 for (int i=0; i < _opaque.num(); i++) {
01193 glLoadMatrixd(mat.matrix());
01194 _opaque[i]->draw_ref_img(_ref_img_type);
01195 }
01196
01197 glEnable(GL_BLEND);
01198 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01199 for (int i=0; i < _blended.num(); i++) {
01200 glLoadMatrixd(mat.matrix());
01201 _blended[i]->draw_ref_img(_ref_img_type);
01202 }
01203
01204
01205 glMatrixMode(GL_PROJECTION);
01206 glPopMatrix();
01207
01208
01209 glMatrixMode(GL_MODELVIEW);
01210 glPopMatrix();
01211 }
01212
01213 void
01214 TexMemRefImage::read_FB()
01215 {
01216
01217 resize(_view->cur_size());
01218
01219 glPushAttrib(GL_ENABLE_BIT);
01220
01221
01222 _texture->apply_texture();
01223
01224 glReadBuffer(GL_BACK);
01225
01226 const Image& img = _texture->image();
01227
01228
01229 glCopyTexImage2D(
01230 GL_TEXTURE_2D,
01231 0,
01232 GL_RGBA,
01233 0,
01234 0,
01235 img.width(),
01236 img.height(),
01237 0);
01238
01239 glPopAttrib();
01240 }
01241
01242 void
01243 TexMemRefImage::draw_FB()
01244 {
01245
01246 glMatrixMode(GL_MODELVIEW);
01247 glPushMatrix();
01248 glLoadIdentity();
01249
01250
01251 glMatrixMode(GL_PROJECTION);
01252 glPushMatrix();
01253 glLoadMatrixd(VIEW::peek()->xypt_proj().transpose().matrix());
01254
01255
01256 glPushAttrib(GL_ENABLE_BIT);
01257 glDisable(GL_LIGHTING);
01258 glDisable(GL_DEPTH_TEST);
01259 glDisable(GL_BLEND);
01260
01261
01262 _texture->apply_texture();
01263
01264 GLfloat t = 1;
01265 glColor4f(1, 1, 1, 1);
01266 glBegin(GL_QUADS);
01267
01268 GLenum unit = _texture->get_tex_unit();
01269 glMultiTexCoord2f(unit, 0, 0); glVertex2f(-t, -t);
01270 glMultiTexCoord2f(unit, 1, 0); glVertex2f( t, -t);
01271 glMultiTexCoord2f(unit, 1, 1); glVertex2f( t, t);
01272 glMultiTexCoord2f(unit, 0, 1); glVertex2f(-t, t);
01273 glEnd();
01274
01275
01276 glPopAttrib();
01277
01278
01279 glMatrixMode(GL_PROJECTION);
01280 glPopMatrix();
01281
01282
01283 glMatrixMode(GL_MODELVIEW);
01284 glPopMatrix();
01285 }
01286
01287