- Timestamp:
- Mar 6, 2012, 3:05:04 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/packages/vizservers/nanovis/VolumeRenderer.cpp
r2798 r2804 18 18 #include <time.h> 19 19 #include <sys/time.h> 20 #include "nanovis.h" 20 21 21 #include <R2/R2string.h> 22 22 #include <R2/R2FilePath.h> 23 24 #include "nanovis.h" 25 23 26 #include "VolumeRenderer.h" 24 27 #include "VolumeInterpolator.h" … … 29 32 #define NUMDIGITS 6 30 33 31 VolumeRenderer::VolumeRenderer() :34 VolumeRenderer::VolumeRenderer() : 32 35 slice_mode(false), 33 36 volume_mode(true) … … 77 80 int volume_id; 78 81 int slice_id; 79 SortElement(float _z, int _v, int _s): 80 z(_z), volume_id(_v), slice_id(_s){} 82 SortElement(float _z, int _v, int _s) : 83 z(_z), volume_id(_v), slice_id(_s) 84 {} 81 85 }; 82 86 83 87 int slice_sort(const void* a, const void* b){ 84 if((*((SortElement*)a)).z > (*((SortElement*)b)).z) 85 return 1; 86 else 87 return -1; 88 } 89 88 if((*((SortElement*)a)).z > (*((SortElement*)b)).z) 89 return 1; 90 else 91 return -1; 92 } 90 93 91 94 void … … 102 105 } 103 106 // Determine the volumes that are to be rendered. 104 vector<Volume *> volumes;107 std::vector<Volume *> volumes; 105 108 Tcl_HashEntry *hPtr; 106 109 Tcl_HashSearch iter; … … 109 112 Volume* volPtr; 110 113 volPtr = (Volume *)Tcl_GetHashValue(hPtr); 111 if (!volPtr->visible()) {114 if (!volPtr->visible()) { 112 115 continue; // Skip this volume 113 116 } … … 139 142 n_slices <<= 1; 140 143 } 141 144 142 145 //volume start location 143 146 Vector3 loc = volPtr->location(); 144 147 Vector4 shift_4d(loc.x, loc.y, loc.z, 0); 145 148 146 149 double x0 = 0; 147 150 double y0 = 0; 148 151 double z0 = 0; 149 152 150 153 Mat4x4 model_view_no_trans, model_view_trans; 151 154 Mat4x4 model_view_no_trans_inverse, model_view_trans_inverse; 152 155 153 156 double zNear, zFar; 154 157 155 158 //initialize volume plane with world coordinates 156 159 Plane volume_planes[6]; … … 161 164 volume_planes[4].set_coeffs( 0, 0, 1, -z0); 162 165 volume_planes[5].set_coeffs( 0, 0, -1, z0+1); 163 166 164 167 //get modelview matrix with no translation 165 168 glPushMatrix(); … … 167 170 volPtr->aspect_ratio_height, 168 171 volPtr->aspect_ratio_depth); 169 172 170 173 glEnable(GL_DEPTH_TEST); 171 174 172 175 GLfloat mv_no_trans[16]; 173 176 glGetFloatv(GL_MODELVIEW_MATRIX, mv_no_trans); 174 177 175 178 model_view_no_trans = Mat4x4(mv_no_trans); 176 179 model_view_no_trans_inverse = model_view_no_trans.inverse(); 177 180 178 181 glPopMatrix(); 179 182 180 183 //get modelview matrix with translation 181 184 glPushMatrix(); … … 186 189 GLfloat mv_trans[16]; 187 190 glGetFloatv(GL_MODELVIEW_MATRIX, mv_trans); 188 191 189 192 model_view_trans = Mat4x4(mv_trans); 190 193 model_view_trans_inverse = model_view_trans.inverse(); 191 194 192 195 //draw volume bounding box with translation (the correct location in 193 196 //space) … … 200 203 } 201 204 glPopMatrix(); 202 205 203 206 //draw labels 204 207 glPushMatrix(); … … 208 211 } 209 212 glPopMatrix(); 210 213 211 214 //transform volume_planes to eye coordinates. 212 for (size_t j = 0; j < 6; j++) {215 for (size_t j = 0; j < 6; j++) { 213 216 volume_planes[j].transform(model_view_no_trans); 214 217 } 215 218 get_near_far_z(mv_no_trans, zNear, zFar); 216 219 217 220 //compute actual rendering slices 218 221 float z_step = fabs(zNear-zFar)/n_slices; 219 222 size_t n_actual_slices; 220 223 221 224 if (volPtr->data_enabled()) { 222 225 n_actual_slices = (int)(fabs(zNear-zFar)/z_step + 1); … … 227 230 } 228 231 actual_slices[i] = n_actual_slices; 229 232 230 233 Vector4 vert1 = (Vector4(-10, -10, -0.5, 1)); 231 234 Vector4 vert2 = (Vector4(-10, +10, -0.5, 1)); 232 235 Vector4 vert3 = (Vector4(+10, +10, -0.5, 1)); 233 236 Vector4 vert4 = (Vector4(+10, -10, -0.5, 1)); 234 235 237 236 238 // Render cutplanes first with depth test enabled. They will mark the 237 239 // image with their depth values. Then we render other volume slices. … … 240 242 241 243 ConvexPolygon static_poly; 242 for (int j = 0; j < volPtr->get_cutplane_count(); j++) {243 if (!volPtr->cutplane_is_enabled(j)) {244 for (int j = 0; j < volPtr->get_cutplane_count(); j++) { 245 if (!volPtr->cutplane_is_enabled(j)) { 244 246 continue; 245 247 } … … 247 249 int axis = volPtr->get_cutplane(j)->orient; 248 250 249 if (axis==3){251 if (axis == 3) { 250 252 vert1 = Vector4(-10, -10, offset, 1); 251 253 vert2 = Vector4(-10, +10, offset, 1); … … 253 255 vert4 = Vector4(+10, -10, offset, 1); 254 256 //continue; 255 } else if (axis==1){257 } else if (axis == 1) { 256 258 vert1 = Vector4(offset, -10, -10, 1); 257 259 vert2 = Vector4(offset, +10, -10, 1); … … 259 261 vert4 = Vector4(offset, -10, +10, 1); 260 262 //continue; 261 } else if (axis==2){263 } else if (axis == 2) { 262 264 vert1 = Vector4(-10, offset, -10, 1); 263 265 vert2 = Vector4(+10, offset, -10, 1); … … 266 268 //continue; 267 269 } 268 270 269 271 vert1 = model_view_no_trans.transform(vert1); 270 272 vert2 = model_view_no_trans.transform(vert2); 271 273 vert3 = model_view_no_trans.transform(vert3); 272 274 vert4 = model_view_no_trans.transform(vert4); 273 275 274 276 ConvexPolygon* p = &static_poly; 275 277 p->vertices.clear(); 276 278 277 279 p->append_vertex(vert1); 278 280 p->append_vertex(vert2); 279 281 p->append_vertex(vert3); 280 282 p->append_vertex(vert4); 281 282 for (size_t k = 0; k < 6; k++){283 284 for (size_t k = 0; k < 6; k++) { 283 285 p->clip(volume_planes[k], true); 284 286 } 285 287 286 288 p->transform(model_view_no_trans_inverse); 287 289 p->transform(model_view_trans); 288 290 289 291 glPushMatrix(); 290 292 glScalef(volPtr->aspect_ratio_width, volPtr->aspect_ratio_height, 291 293 volPtr->aspect_ratio_depth); 292 294 293 295 activate_volume_shader(volPtr, true); 294 296 glPopMatrix(); 295 297 296 298 glEnable(GL_DEPTH_TEST); 297 299 glDisable(GL_BLEND); 298 300 299 301 glBegin(GL_POLYGON); 300 302 p->Emit(true); 301 303 glEnd(); 302 304 glDisable(GL_DEPTH_TEST); 303 305 304 306 deactivate_volume_shader(); 305 307 } //done cutplanes 306 308 307 308 309 //Now do volume rendering 309 310 310 311 vert1 = (Vector4(-10, -10, -0.5, 1)); 311 312 vert2 = (Vector4(-10, +10, -0.5, 1)); 312 313 vert3 = (Vector4(+10, +10, -0.5, 1)); 313 314 vert4 = (Vector4(+10, -10, -0.5, 1)); 314 315 315 316 size_t counter = 0; 316 317 317 318 //transform slices and store them 318 319 float slice_z; 319 320 for (size_t j = 0; j < n_actual_slices; j++) { 320 321 slice_z = zFar + j * z_step; //back to front 321 322 322 323 ConvexPolygon *poly = new ConvexPolygon(); 323 324 polys[i][counter] = poly; 324 325 counter++; 325 326 326 327 poly->vertices.clear(); 327 328 poly->set_id(i); 328 329 329 330 //Setting Z-coordinate 330 331 vert1.z = slice_z; … … 332 333 vert3.z = slice_z; 333 334 vert4.z = slice_z; 334 335 335 336 poly->append_vertex(vert1); 336 337 poly->append_vertex(vert2); 337 338 poly->append_vertex(vert3); 338 339 poly->append_vertex(vert4); 339 340 for (size_t k = 0; k < 6; k++) {340 341 for (size_t k = 0; k < 6; k++) { 341 342 poly->clip(volume_planes[k], true); 342 343 } 343 344 344 345 poly->transform(model_view_no_trans_inverse); 345 346 poly->transform(model_view_trans); 346 347 if (poly->vertices.size()>=3)348 total_rendered_slices++; 347 348 if (poly->vertices.size() >= 3) 349 total_rendered_slices++; 349 350 } 350 351 351 } //iterate all volumes 352 352 TRACE("end loop\n"); 353 353 354 354 // We sort all the polygons according to their eye-space depth, from 355 355 // farthest to the closest. This step is critical for correct blending 356 356 357 357 SortElement* slices = (SortElement*) 358 358 malloc(sizeof(SortElement) * total_rendered_slices); 359 359 360 360 size_t counter = 0; 361 for (size_t i = 0; i < volumes.size(); i++) {362 for (size_t j = 0; j < actual_slices[i]; j++) {363 if (polys[i][j]->vertices.size() >= 3){361 for (size_t i = 0; i < volumes.size(); i++) { 362 for (size_t j = 0; j < actual_slices[i]; j++) { 363 if (polys[i][j]->vertices.size() >= 3) { 364 364 slices[counter] = SortElement(polys[i][j]->vertices[0].z, i, j); 365 365 counter++; … … 367 367 } 368 368 } 369 369 370 370 //sort them 371 371 qsort(slices, total_rendered_slices, sizeof(SortElement), slice_sort); 372 372 373 373 //Now we are ready to render all the slices from back to front 374 374 glEnable(GL_DEPTH_TEST); 375 375 glEnable(GL_BLEND); 376 377 for (size_t i = 0; i < total_rendered_slices; i++){376 377 for (size_t i = 0; i < total_rendered_slices; i++) { 378 378 Volume* volPtr; 379 379 … … 381 381 int slice_index = slices[i].slice_id; 382 382 ConvexPolygon* cur = polys[volume_index][slice_index]; 383 383 384 384 volPtr = volumes[volume_index]; 385 385 glPushMatrix(); 386 386 glScalef(volPtr->aspect_ratio_width, volPtr->aspect_ratio_height, 387 387 volPtr->aspect_ratio_depth); 388 388 389 389 #ifdef notdef 390 390 TRACE("shading slice: volume %s addr=%x slice=%d, volume=%d\n", … … 393 393 activate_volume_shader(volPtr, false); 394 394 glPopMatrix(); 395 395 396 396 glBegin(GL_POLYGON); 397 cur->Emit(true); 397 cur->Emit(true); 398 398 glEnd(); 399 399 400 400 deactivate_volume_shader(); 401 401 } 402 402 403 403 glDisable(GL_DEPTH_TEST); 404 404 glDisable(GL_BLEND); 405 405 406 406 //Deallocate all the memory used 407 for (size_t i = 0; i < volumes.size(); i++){408 for (size_t j=0; j <actual_slices[i]; j++){407 for (size_t i = 0; i < volumes.size(); i++) { 408 for (size_t j = 0; j <actual_slices[i]; j++) { 409 409 delete polys[i][j]; 410 410 } … … 431 431 glColor4d(r, g, b, 1.0); 432 432 glLineWidth(line_width); 433 433 434 434 glBegin(GL_LINE_LOOP); 435 435 { … … 440 440 } 441 441 glEnd(); 442 442 443 443 glBegin(GL_LINE_LOOP); 444 444 { … … 449 449 } 450 450 glEnd(); 451 452 451 453 452 glBegin(GL_LINE_LOOP); … … 459 458 } 460 459 glEnd(); 461 460 462 461 glBegin(GL_LINE_LOOP); 463 462 { … … 538 537 } 539 538 540 541 542 539 void 543 540 VolumeRenderer::activate_volume_shader(Volume* volPtr, bool slice_mode) … … 552 549 } 553 550 } 554 555 551 556 552 void VolumeRenderer::deactivate_volume_shader() … … 561 557 } 562 558 563 564 559 void VolumeRenderer::get_near_far_z(Mat4x4 mv, double &zNear, double &zFar) 565 560 { 566 567 561 double x0 = 0; 568 562 double y0 = 0; … … 587 581 vertex[7][0]=x1; vertex[7][1]=y1; vertex[7][2]=z1; vertex[7][3]=1.0; 588 582 589 for (int i=0;i<8;i++) {583 for (int i = 0; i < 8; i++) { 590 584 Vector4 tmp = mv.transform(Vector4(vertex[i][0], vertex[i][1], vertex[i][2], vertex[i][3])); 591 585 tmp.perspective_devide(); … … 603 597 void VolumeRenderer::switch_slice_mode() { slice_mode = (!slice_mode); } 604 598 void VolumeRenderer::switch_volume_mode() { volume_mode = (!volume_mode); } 605 606 599 607 600 bool … … 624 617 return false; 625 618 } 626 619 627 620 if (fread(&bfType, sizeof(short int), 1, f) != 1) { 628 621 ERROR("can't read %lu bytes from font file \"%s\"\n", … … 630 623 goto error; 631 624 } 632 625 633 626 /* check if file is a bitmap */ 634 627 if (bfType != 19778) { … … 636 629 goto error; 637 630 } 638 631 639 632 /* get the file size */ 640 633 /* skip file size and reserved fields of bitmap file header */ 641 634 fseek(f, 8, SEEK_CUR); 642 635 643 636 /* get the position of the actual bitmap data */ 644 637 if (fread(&bfOffBits, sizeof(int), 1, f) != 1) { … … 647 640 } 648 641 //TRACE("Data at Offset: %ld\n", bfOffBits); 649 642 650 643 /* skip size of bitmap info header */ 651 644 fseek(f, 4, SEEK_CUR); 652 645 653 646 /* get the width of the bitmap */ 654 647 if (fread(&width, sizeof(int), 1, f) != 1) { … … 657 650 } 658 651 //TRACE("Width of Bitmap: %d\n", texture->width); 659 652 660 653 /* get the height of the bitmap */ 661 654 if (fread(&height, sizeof(int), 1, f) != 1) { … … 664 657 } 665 658 //TRACE("Height of Bitmap: %d\n", texture->height); 666 659 667 660 /* get the number of planes (must be set to 1) */ 668 661 if (fread(&biPlanes, sizeof(short int), 1, f) != 1) { … … 674 667 goto error; 675 668 } 676 669 677 670 /* get the number of bits per pixel */ 678 671 if (fread(&biBitCount, sizeof(short int), 1, f) != 1) { … … 680 673 goto error; 681 674 } 682 675 683 676 //TRACE("Bits per Pixel: %d\n", biBitCount); 684 677 if (biBitCount != 24) { … … 686 679 goto error; 687 680 } 688 689 681 690 682 /* calculate the size of the image in bytes */ … … 715 707 data_with_alpha = (unsigned char*) 716 708 malloc(width*height*4*sizeof(unsigned char)); 717 for (int i=0; i<height; i++){718 for (int j=0; j<width; j++){709 for (int i = 0; i < height; i++) { 710 for (int j = 0; j < width; j++) { 719 711 unsigned char r, g, b, a; 720 712 r = data[3*(i*width+j)]; 721 713 g = data[3*(i*width+j)+1]; 722 714 b = data[3*(i*width+j)+2]; 723 724 if (r==0 && g==0 && b==0)715 716 if (r==0 && g==0 && b==0) 725 717 a = 0; 726 718 else 727 719 a = 255; 728 720 729 721 data_with_alpha[4*(i*width+j)] = r; 730 722 data_with_alpha[4*(i*width+j) + 1] = g; 731 723 data_with_alpha[4*(i*width+j) + 2] = b; 732 724 data_with_alpha[4*(i*width+j) + 3] = a; 733 734 725 } 735 726 } 736 727 free(data); 737 728 738 729 //create opengl texture 739 730 glGenTextures(1, &font_texture); … … 755 746 } 756 747 757 758 759 748 void 760 749 VolumeRenderer::draw_label(Volume* vol) 761 750 { 762 763 751 //glEnable(GL_TEXTURE_2D); 764 752 glDisable(GL_TEXTURE_2D); 765 753 glEnable(GL_DEPTH_TEST); 766 754 767 755 //x 768 756 glColor3f(0.5, 0.5, 0.5); 769 757 770 758 int length = vol->label[0].size(); 771 759 glPushMatrix(); 772 760 773 761 glTranslatef(.5*vol->aspect_ratio_width, vol->aspect_ratio_height, 774 762 -0.1*vol->aspect_ratio_depth); 775 763 glRotatef(180, 0, 0, 1); 776 764 glRotatef(90, 1, 0, 0); 777 765 778 766 glScalef(0.0008, 0.0008, 0.0008); 779 767 for(int i=0; i<length; i++){ … … 782 770 } 783 771 glPopMatrix(); 784 772 785 773 //y 786 774 length = vol->label[1].size(); … … 796 784 } 797 785 glPopMatrix(); 798 799 786 800 787 //z 801 788 length = vol->label[2].size(); … … 803 790 glTranslatef(0., 1.*vol->aspect_ratio_height, 0.5*vol->aspect_ratio_depth); 804 791 glRotatef(90, 0, 1, 0); 805 792 806 793 glScalef(0.0008, 0.0008, 0.0008); 807 794 for(int i=0; i<length; i++){ … … 810 797 } 811 798 glPopMatrix(); 812 799 813 800 glDisable(GL_TEXTURE_2D); 814 801 } 815 816 817 802 818 803 void … … 841 826 } 842 827 843 void 828 void 844 829 VolumeRenderer::glPrint(char* string, int set) 845 830 { 846 if (set>1) {831 if (set > 1) { 847 832 set=1; 848 833 } … … 851 836 glCallLists(strlen(string), GL_BYTE, string); 852 837 } 853
Note: See TracChangeset
for help on using the changeset viewer.