| | 460 | struct ScaleOperator |
| | 461 | { |
| | 462 | ScaleOperator():_scale(1.0f) {} |
| | 463 | ScaleOperator(float scale):_scale(scale) {} |
| | 464 | ScaleOperator(const ScaleOperator& so):_scale(so._scale) {} |
| | 465 | |
| | 466 | ScaleOperator& operator = (const ScaleOperator& so) { _scale = so._scale; return *this; } |
| | 467 | |
| | 468 | float _scale; |
| | 469 | |
| | 470 | inline void luminance(float& l) const { l*= _scale; } |
| | 471 | inline void alpha(float& a) const { a*= _scale; } |
| | 472 | inline void luminance_alpha(float& l,float& a) const { l*= _scale; a*= _scale; } |
| | 473 | inline void rgb(float& r,float& g,float& b) const { r*= _scale; g*=_scale; b*=_scale; } |
| | 474 | inline void rgba(float& r,float& g,float& b,float& a) const { r*= _scale; g*=_scale; b*=_scale; a*=_scale; } |
| | 475 | }; |
| | 476 | |
| | 477 | struct RecordRowOperator |
| | 478 | { |
| | 479 | RecordRowOperator(unsigned int num):_colours(num),_pos(0) {} |
| | 480 | |
| | 481 | mutable std::vector<osg::Vec4> _colours; |
| | 482 | mutable unsigned int _pos; |
| | 483 | |
| | 484 | inline void luminance(float l) const { rgba(l,l,l,1.0f); } |
| | 485 | inline void alpha(float a) const { rgba(1.0f,1.0f,1.0f,a); } |
| | 486 | inline void luminance_alpha(float l,float a) const { rgba(l,l,l,a); } |
| | 487 | inline void rgb(float r,float g,float b) const { rgba(r,g,b,1.0f); } |
| | 488 | inline void rgba(float r,float g,float b,float a) const { _colours[_pos++].set(r,g,b,a); } |
| | 489 | }; |
| | 490 | |
| | 491 | struct WriteRowOperator |
| | 492 | { |
| | 493 | WriteRowOperator():_pos(0) {} |
| | 494 | WriteRowOperator(unsigned int num):_colours(num),_pos(0) {} |
| | 495 | |
| | 496 | std::vector<osg::Vec4> _colours; |
| | 497 | mutable unsigned int _pos; |
| | 498 | |
| | 499 | inline void luminance(float& l) const { l = _colours[_pos++].r(); } |
| | 500 | inline void alpha(float& a) const { a = _colours[_pos++].a(); } |
| | 501 | inline void luminance_alpha(float& l,float& a) const { l = _colours[_pos].r(); a = _colours[_pos++].a(); } |
| | 502 | inline void rgb(float& r,float& g,float& b) const { r = _colours[_pos].r(); g = _colours[_pos].g(); b = _colours[_pos].b(); } |
| | 503 | inline void rgba(float& r,float& g,float& b,float& a) const { r = _colours[_pos].r(); g = _colours[_pos].g(); b = _colours[_pos].b(); a = _colours[_pos++].a(); } |
| | 504 | }; |
| | 505 | |
| | 506 | osg::Image* readRaw(int sizeX, int sizeY, int sizeZ, int numberBytesPerComponent, int numberOfComponents, const std::string& endian, const std::string& raw_filename) |
| | 507 | { |
| | 508 | osgDB::ifstream fin(raw_filename.c_str(), std::ifstream::binary); |
| | 509 | if (!fin) return 0; |
| | 510 | |
| | 511 | GLenum pixelFormat; |
| | 512 | switch(numberOfComponents) |
| | 513 | { |
| | 514 | case 1 : pixelFormat = GL_LUMINANCE; break; |
| | 515 | case 2 : pixelFormat = GL_LUMINANCE_ALPHA; break; |
| | 516 | case 3 : pixelFormat = GL_RGB; break; |
| | 517 | case 4 : pixelFormat = GL_RGBA; break; |
| | 518 | default : |
| | 519 | osg::notify(osg::NOTICE)<<"Error: numberOfComponents="<<numberOfComponents<<" not supported, only 1,2,3 or 4 are supported."<<std::endl; |
| | 520 | return 0; |
| | 521 | } |
| | 522 | |
| | 523 | |
| | 524 | GLenum dataType; |
| | 525 | switch(numberBytesPerComponent) |
| | 526 | { |
| | 527 | case 1 : dataType = GL_UNSIGNED_BYTE; break; |
| | 528 | case 2 : dataType = GL_UNSIGNED_SHORT; break; |
| | 529 | case 4 : dataType = GL_UNSIGNED_INT; break; |
| | 530 | default : |
| | 531 | osg::notify(osg::NOTICE)<<"Error: numberBytesPerComponent="<<numberBytesPerComponent<<" not supported, only 1,2 or 4 are supported."<<std::endl; |
| | 532 | return 0; |
| | 533 | } |
| | 534 | |
| | 535 | int s_maximumTextureSize=256, t_maximumTextureSize=256, r_maximumTextureSize=256; |
| | 536 | |
| | 537 | int sizeS = sizeX; |
| | 538 | int sizeT = sizeY; |
| | 539 | int sizeR = sizeZ; |
| | 540 | clampToNearestValidPowerOfTwo(sizeS, sizeT, sizeR, s_maximumTextureSize, t_maximumTextureSize, r_maximumTextureSize); |
| | 541 | |
| | 542 | osg::ref_ptr<osg::Image> image = new osg::Image; |
| | 543 | image->allocateImage(sizeS, sizeT, sizeR, pixelFormat, dataType); |
| | 544 | |
| | 545 | |
| | 546 | bool endianSwap = (osg::getCpuByteOrder()==osg::BigEndian) ? (endian!="big") : (endian=="big"); |
| | 547 | |
| | 548 | unsigned int r_offset = (sizeZ<sizeR) ? sizeR/2 - sizeZ/2 : 0; |
| | 549 | |
| | 550 | int offset = endianSwap ? numberBytesPerComponent : 0; |
| | 551 | int delta = endianSwap ? -1 : 1; |
| | 552 | for(int r=0;r<sizeZ;++r) |
| | 553 | { |
| | 554 | for(int t=0;t<sizeY;++t) |
| | 555 | { |
| | 556 | char* data = (char*) image->data(0,t,r+r_offset); |
| | 557 | for(int s=0;s<sizeX;++s) |
| | 558 | { |
| | 559 | if (!fin) return 0; |
| | 560 | |
| | 561 | for(int c=0;c<numberOfComponents;++c) |
| | 562 | { |
| | 563 | char* ptr = data+offset; |
| | 564 | for(int b=0;b<numberBytesPerComponent;++b) |
| | 565 | { |
| | 566 | fin.read((char*)ptr, 1); |
| | 567 | ptr += delta; |
| | 568 | } |
| | 569 | data += numberBytesPerComponent; |
| | 570 | } |
| | 571 | } |
| | 572 | } |
| | 573 | } |
| | 574 | |
| | 575 | |
| | 576 | // normalise texture |
| | 577 | { |
| | 578 | // compute range of values |
| | 579 | osg::Vec4 minValue, maxValue; |
| | 580 | osg::computeMinMax(image.get(), minValue, maxValue); |
| | 581 | osg::modifyImage(image.get(),ScaleOperator(1.0f/maxValue.r())); |
| | 582 | } |
| | 583 | |
| | 584 | |
| | 585 | fin.close(); |
| | 586 | |
| | 587 | if (dataType!=GL_UNSIGNED_BYTE) |
| | 588 | { |
| | 589 | // need to convert to ubyte |
| | 590 | |
| | 591 | osg::ref_ptr<osg::Image> new_image = new osg::Image; |
| | 592 | new_image->allocateImage(sizeS, sizeT, sizeR, pixelFormat, GL_UNSIGNED_BYTE); |
| | 593 | |
| | 594 | RecordRowOperator readOp(sizeS); |
| | 595 | WriteRowOperator writeOp; |
| | 596 | |
| | 597 | for(int r=0;r<sizeR;++r) |
| | 598 | { |
| | 599 | for(int t=0;t<sizeT;++t) |
| | 600 | { |
| | 601 | // reset the indices to beginning |
| | 602 | readOp._pos = 0; |
| | 603 | writeOp._pos = 0; |
| | 604 | |
| | 605 | // read the pixels into readOp's _colour array |
| | 606 | osg::readRow(sizeS, pixelFormat, dataType, image->data(0,t,r), readOp); |
| | 607 | |
| | 608 | // pass readOp's _colour array contents over to writeOp (note this is just a pointer swap). |
| | 609 | writeOp._colours.swap(readOp._colours); |
| | 610 | |
| | 611 | osg::modifyRow(sizeS, pixelFormat, GL_UNSIGNED_BYTE, new_image->data(0,t,r), writeOp); |
| | 612 | |
| | 613 | // return readOp's _colour array contents back to its rightful owner. |
| | 614 | writeOp._colours.swap(readOp._colours); |
| | 615 | } |
| | 616 | } |
| | 617 | |
| | 618 | image = new_image; |
| | 619 | } |
| | 620 | |
| | 621 | return image.release(); |
| | 622 | |
| | 623 | |
| | 624 | } |
| | 625 | |
| | 626 | enum ColourSpaceOperation |
| | 627 | { |
| | 628 | NO_COLOUR_SPACE_OPERATION, |
| | 629 | MODULATE_ALPHA_BY_LUMINANCE, |
| | 630 | MODULATE_ALPHA_BY_COLOUR, |
| | 631 | REPLACE_ALPHA_WITH_LUMINANACE, |
| | 632 | REPLACE_RGB_WITH_LUMINANCE |
| | 633 | }; |
| | 634 | |
| | 635 | struct ModulateAlphaByLuminanceOperator |
| | 636 | { |
| | 637 | ModulateAlphaByLuminanceOperator() {} |
| | 638 | |
| | 639 | inline void luminance(float&) const {} |
| | 640 | inline void alpha(float&) const {} |
| | 641 | inline void luminance_alpha(float& l,float& a) const { a*= l; } |
| | 642 | inline void rgb(float&,float&,float&) const {} |
| | 643 | inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a *= l;} |
| | 644 | }; |
| | 645 | |
| | 646 | struct ModulateAlphaByColourOperator |
| | 647 | { |
| | 648 | ModulateAlphaByColourOperator(const osg::Vec4& colour):_colour(colour) { _lum = _colour.length(); } |
| | 649 | |
| | 650 | osg::Vec4 _colour; |
| | 651 | float _lum; |
| | 652 | |
| | 653 | inline void luminance(float&) const {} |
| | 654 | inline void alpha(float&) const {} |
| | 655 | inline void luminance_alpha(float& l,float& a) const { a*= l*_lum; } |
| | 656 | inline void rgb(float&,float&,float&) const {} |
| | 657 | inline void rgba(float& r,float& g,float& b,float& a) const { a = (r*_colour.r()+g*_colour.g()+b*_colour.b()+a*_colour.a()); } |
| | 658 | }; |
| | 659 | |
| | 660 | struct ReplaceAlphaWithLuminanceOperator |
| | 661 | { |
| | 662 | ReplaceAlphaWithLuminanceOperator() {} |
| | 663 | |
| | 664 | inline void luminance(float&) const {} |
| | 665 | inline void alpha(float&) const {} |
| | 666 | inline void luminance_alpha(float& l,float& a) const { a= l; } |
| | 667 | inline void rgb(float&,float&,float&) const { } |
| | 668 | inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a = l; } |
| | 669 | }; |
| | 670 | |
| | 671 | osg::Image* doColourSpaceConversion(ColourSpaceOperation op, osg::Image* image, osg::Vec4& colour) |
| | 672 | { |
| | 673 | switch(op) |
| | 674 | { |
| | 675 | case (MODULATE_ALPHA_BY_LUMINANCE): |
| | 676 | { |
| | 677 | std::cout<<"doing conversion MODULATE_ALPHA_BY_LUMINANCE"<<std::endl; |
| | 678 | osg::modifyImage(image,ModulateAlphaByLuminanceOperator()); |
| | 679 | return image; |
| | 680 | } |
| | 681 | case (MODULATE_ALPHA_BY_COLOUR): |
| | 682 | { |
| | 683 | std::cout<<"doing conversion MODULATE_ALPHA_BY_COLOUR"<<std::endl; |
| | 684 | osg::modifyImage(image,ModulateAlphaByColourOperator(colour)); |
| | 685 | return image; |
| | 686 | } |
| | 687 | case (REPLACE_ALPHA_WITH_LUMINANACE): |
| | 688 | { |
| | 689 | std::cout<<"doing conversion REPLACE_ALPHA_WITH_LUMINANACE"<<std::endl; |
| | 690 | osg::modifyImage(image,ReplaceAlphaWithLuminanceOperator()); |
| | 691 | return image; |
| | 692 | } |
| | 693 | case (REPLACE_RGB_WITH_LUMINANCE): |
| | 694 | { |
| | 695 | std::cout<<"doing conversion REPLACE_ALPHA_WITH_LUMINANACE"<<std::endl; |
| | 696 | osg::Image* newImage = new osg::Image; |
| | 697 | newImage->allocateImage(image->s(), image->t(), image->r(), GL_LUMINANCE, image->getDataType()); |
| | 698 | osg::copyImage(image, 0, 0, 0, image->s(), image->t(), image->r(), |
| | 699 | newImage, 0, 0, 0, false); |
| | 700 | return newImage; |
| | 701 | } |
| | 702 | default: |
| | 703 | return image; |
| | 704 | } |
| | 705 | } |
| | 706 | |
| | 707 | |
| | 708 | osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename) |
| | 709 | { |
| | 710 | std::string foundFile = osgDB::findDataFile(filename); |
| | 711 | if (foundFile.empty()) |
| | 712 | { |
| | 713 | std::cout<<"Error: could not find transfer function file : "<<filename<<std::endl; |
| | 714 | return 0; |
| | 715 | } |
| | 716 | |
| | 717 | std::cout<<"Reading transfer function "<<filename<<std::endl; |
| | 718 | |
| | 719 | osg::TransferFunction1D::ValueMap valueMap; |
| | 720 | osgDB::ifstream fin(foundFile.c_str()); |
| | 721 | while(fin) |
| | 722 | { |
| | 723 | float value, red, green, blue, alpha; |
| | 724 | fin >> value >> red >> green >> blue >> alpha; |
| | 725 | if (fin) |
| | 726 | { |
| | 727 | std::cout<<"value = "<<value<<" ("<<red<<", "<<green<<", "<<blue<<", "<<alpha<<")"<<std::endl; |
| | 728 | valueMap[value] = osg::Vec4(red,green,blue,alpha); |
| | 729 | } |
| | 730 | } |
| | 731 | |
| | 732 | if (valueMap.empty()) |
| | 733 | { |
| | 734 | std::cout<<"Error: No values read from transfer function file: "<<filename<<std::endl; |
| | 735 | return 0; |
| | 736 | } |
| | 737 | |
| | 738 | osg::TransferFunction1D* tf = new osg::TransferFunction1D; |
| | 739 | tf->assign(valueMap, true); |
| | 740 | |
| | 741 | return tf; |
| | 742 | } |
| | 743 | |
| | 744 | |
| 567 | | |
| 568 | | struct ScaleOperator |
| 569 | | { |
| 570 | | ScaleOperator():_scale(1.0f) {} |
| 571 | | ScaleOperator(float scale):_scale(scale) {} |
| 572 | | ScaleOperator(const ScaleOperator& so):_scale(so._scale) {} |
| 573 | | |
| 574 | | ScaleOperator& operator = (const ScaleOperator& so) { _scale = so._scale; return *this; } |
| 575 | | |
| 576 | | float _scale; |
| 577 | | |
| 578 | | inline void luminance(float& l) const { l*= _scale; } |
| 579 | | inline void alpha(float& a) const { a*= _scale; } |
| 580 | | inline void luminance_alpha(float& l,float& a) const { l*= _scale; a*= _scale; } |
| 581 | | inline void rgb(float& r,float& g,float& b) const { r*= _scale; g*=_scale; b*=_scale; } |
| 582 | | inline void rgba(float& r,float& g,float& b,float& a) const { r*= _scale; g*=_scale; b*=_scale; a*=_scale; } |
| 583 | | }; |
| 584 | | |
| 585 | | struct RecordRowOperator |
| 586 | | { |
| 587 | | RecordRowOperator(unsigned int num):_colours(num),_pos(0) {} |
| 588 | | |
| 589 | | mutable std::vector<osg::Vec4> _colours; |
| 590 | | mutable unsigned int _pos; |
| 591 | | |
| 592 | | inline void luminance(float l) const { rgba(l,l,l,1.0f); } |
| 593 | | inline void alpha(float a) const { rgba(1.0f,1.0f,1.0f,a); } |
| 594 | | inline void luminance_alpha(float l,float a) const { rgba(l,l,l,a); } |
| 595 | | inline void rgb(float r,float g,float b) const { rgba(r,g,b,1.0f); } |
| 596 | | inline void rgba(float r,float g,float b,float a) const { _colours[_pos++].set(r,g,b,a); } |
| 597 | | }; |
| 598 | | |
| 599 | | struct WriteRowOperator |
| 600 | | { |
| 601 | | WriteRowOperator():_pos(0) {} |
| 602 | | WriteRowOperator(unsigned int num):_colours(num),_pos(0) {} |
| 603 | | |
| 604 | | std::vector<osg::Vec4> _colours; |
| 605 | | mutable unsigned int _pos; |
| 606 | | |
| 607 | | inline void luminance(float& l) const { l = _colours[_pos++].r(); } |
| 608 | | inline void alpha(float& a) const { a = _colours[_pos++].a(); } |
| 609 | | inline void luminance_alpha(float& l,float& a) const { l = _colours[_pos].r(); a = _colours[_pos++].a(); } |
| 610 | | inline void rgb(float& r,float& g,float& b) const { r = _colours[_pos].r(); g = _colours[_pos].g(); b = _colours[_pos].b(); } |
| 611 | | inline void rgba(float& r,float& g,float& b,float& a) const { r = _colours[_pos].r(); g = _colours[_pos].g(); b = _colours[_pos].b(); a = _colours[_pos++].a(); } |
| 612 | | }; |
| 613 | | |
| 614 | | osg::Image* readRaw(int sizeX, int sizeY, int sizeZ, int numberBytesPerComponent, int numberOfComponents, const std::string& endian, const std::string& raw_filename) |
| 615 | | { |
| 616 | | osgDB::ifstream fin(raw_filename.c_str(), std::ifstream::binary); |
| 617 | | if (!fin) return 0; |
| 618 | | |
| 619 | | GLenum pixelFormat; |
| 620 | | switch(numberOfComponents) |
| 621 | | { |
| 622 | | case 1 : pixelFormat = GL_LUMINANCE; break; |
| 623 | | case 2 : pixelFormat = GL_LUMINANCE_ALPHA; break; |
| 624 | | case 3 : pixelFormat = GL_RGB; break; |
| 625 | | case 4 : pixelFormat = GL_RGBA; break; |
| 626 | | default : |
| 627 | | osg::notify(osg::NOTICE)<<"Error: numberOfComponents="<<numberOfComponents<<" not supported, only 1,2,3 or 4 are supported."<<std::endl; |
| 628 | | return 0; |
| 629 | | } |
| 630 | | |
| 631 | | |
| 632 | | GLenum dataType; |
| 633 | | switch(numberBytesPerComponent) |
| 634 | | { |
| 635 | | case 1 : dataType = GL_UNSIGNED_BYTE; break; |
| 636 | | case 2 : dataType = GL_UNSIGNED_SHORT; break; |
| 637 | | case 4 : dataType = GL_UNSIGNED_INT; break; |
| 638 | | default : |
| 639 | | osg::notify(osg::NOTICE)<<"Error: numberBytesPerComponent="<<numberBytesPerComponent<<" not supported, only 1,2 or 4 are supported."<<std::endl; |
| 640 | | return 0; |
| 641 | | } |
| 642 | | |
| 643 | | int s_maximumTextureSize=256, t_maximumTextureSize=256, r_maximumTextureSize=256; |
| 644 | | |
| 645 | | int sizeS = sizeX; |
| 646 | | int sizeT = sizeY; |
| 647 | | int sizeR = sizeZ; |
| 648 | | clampToNearestValidPowerOfTwo(sizeS, sizeT, sizeR, s_maximumTextureSize, t_maximumTextureSize, r_maximumTextureSize); |
| 649 | | |
| 650 | | osg::ref_ptr<osg::Image> image = new osg::Image; |
| 651 | | image->allocateImage(sizeS, sizeT, sizeR, pixelFormat, dataType); |
| 652 | | |
| 653 | | |
| 654 | | bool endianSwap = (osg::getCpuByteOrder()==osg::BigEndian) ? (endian!="big") : (endian=="big"); |
| 655 | | |
| 656 | | unsigned int r_offset = (sizeZ<sizeR) ? sizeR/2 - sizeZ/2 : 0; |
| 657 | | |
| 658 | | int offset = endianSwap ? numberBytesPerComponent : 0; |
| 659 | | int delta = endianSwap ? -1 : 1; |
| 660 | | for(int r=0;r<sizeZ;++r) |
| 661 | | { |
| 662 | | for(int t=0;t<sizeY;++t) |
| 663 | | { |
| 664 | | char* data = (char*) image->data(0,t,r+r_offset); |
| 665 | | for(int s=0;s<sizeX;++s) |
| 666 | | { |
| 667 | | if (!fin) return 0; |
| 668 | | |
| 669 | | for(int c=0;c<numberOfComponents;++c) |
| 670 | | { |
| 671 | | char* ptr = data+offset; |
| 672 | | for(int b=0;b<numberBytesPerComponent;++b) |
| 673 | | { |
| 674 | | fin.read((char*)ptr, 1); |
| 675 | | ptr += delta; |
| 676 | | } |
| 677 | | data += numberBytesPerComponent; |
| 678 | | } |
| 679 | | } |
| 680 | | } |
| 681 | | } |
| 682 | | |
| 683 | | |
| 684 | | // normalise texture |
| 685 | | { |
| 686 | | // compute range of values |
| 687 | | osg::Vec4 minValue, maxValue; |
| 688 | | osg::computeMinMax(image.get(), minValue, maxValue); |
| 689 | | osg::modifyImage(image.get(),ScaleOperator(1.0f/maxValue.r())); |
| 690 | | } |
| 691 | | |
| 692 | | |
| 693 | | fin.close(); |
| 694 | | |
| 695 | | if (dataType!=GL_UNSIGNED_BYTE) |
| 696 | | { |
| 697 | | // need to convert to ubyte |
| 698 | | |
| 699 | | osg::ref_ptr<osg::Image> new_image = new osg::Image; |
| 700 | | new_image->allocateImage(sizeS, sizeT, sizeR, pixelFormat, GL_UNSIGNED_BYTE); |
| 701 | | |
| 702 | | RecordRowOperator readOp(sizeS); |
| 703 | | WriteRowOperator writeOp; |
| 704 | | |
| 705 | | for(int r=0;r<sizeR;++r) |
| 706 | | { |
| 707 | | for(int t=0;t<sizeT;++t) |
| 708 | | { |
| 709 | | // reset the indices to beginning |
| 710 | | readOp._pos = 0; |
| 711 | | writeOp._pos = 0; |
| 712 | | |
| 713 | | // read the pixels into readOp's _colour array |
| 714 | | osg::readRow(sizeS, pixelFormat, dataType, image->data(0,t,r), readOp); |
| 715 | | |
| 716 | | // pass readOp's _colour array contents over to writeOp (note this is just a pointer swap). |
| 717 | | writeOp._colours.swap(readOp._colours); |
| 718 | | |
| 719 | | osg::modifyRow(sizeS, pixelFormat, GL_UNSIGNED_BYTE, new_image->data(0,t,r), writeOp); |
| 720 | | |
| 721 | | // return readOp's _colour array contents back to its rightful owner. |
| 722 | | writeOp._colours.swap(readOp._colours); |
| 723 | | } |
| 724 | | } |
| 725 | | |
| 726 | | image = new_image; |
| 727 | | } |
| 728 | | |
| 729 | | return image.release(); |
| 730 | | |
| 731 | | |
| 732 | | } |
| 733 | | |
| 734 | | enum ColourSpaceOperation |
| 735 | | { |
| 736 | | NO_COLOUR_SPACE_OPERATION, |
| 737 | | MODULATE_ALPHA_BY_LUMINANCE, |
| 738 | | MODULATE_ALPHA_BY_COLOUR, |
| 739 | | REPLACE_ALPHA_WITH_LUMINANACE, |
| 740 | | REPLACE_RGB_WITH_LUMINANCE |
| 741 | | }; |
| 742 | | |
| 743 | | struct ModulateAlphaByLuminanceOperator |
| 744 | | { |
| 745 | | ModulateAlphaByLuminanceOperator() {} |
| 746 | | |
| 747 | | inline void luminance(float&) const {} |
| 748 | | inline void alpha(float&) const {} |
| 749 | | inline void luminance_alpha(float& l,float& a) const { a*= l; } |
| 750 | | inline void rgb(float&,float&,float&) const {} |
| 751 | | inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a *= l;} |
| 752 | | }; |
| 753 | | |
| 754 | | struct ModulateAlphaByColourOperator |
| 755 | | { |
| 756 | | ModulateAlphaByColourOperator(const osg::Vec4& colour):_colour(colour) { _lum = _colour.length(); } |
| 757 | | |
| 758 | | osg::Vec4 _colour; |
| 759 | | float _lum; |
| 760 | | |
| 761 | | inline void luminance(float&) const {} |
| 762 | | inline void alpha(float&) const {} |
| 763 | | inline void luminance_alpha(float& l,float& a) const { a*= l*_lum; } |
| 764 | | inline void rgb(float&,float&,float&) const {} |
| 765 | | inline void rgba(float& r,float& g,float& b,float& a) const { a = (r*_colour.r()+g*_colour.g()+b*_colour.b()+a*_colour.a()); } |
| 766 | | }; |
| 767 | | |
| 768 | | struct ReplaceAlphaWithLuminanceOperator |
| 769 | | { |
| 770 | | ReplaceAlphaWithLuminanceOperator() {} |
| 771 | | |
| 772 | | inline void luminance(float&) const {} |
| 773 | | inline void alpha(float&) const {} |
| 774 | | inline void luminance_alpha(float& l,float& a) const { a= l; } |
| 775 | | inline void rgb(float&,float&,float&) const { } |
| 776 | | inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a = l; } |
| 777 | | }; |
| 778 | | |
| 779 | | osg::Image* doColourSpaceConversion(ColourSpaceOperation op, osg::Image* image, osg::Vec4& colour) |
| 780 | | { |
| 781 | | switch(op) |
| 782 | | { |
| 783 | | case (MODULATE_ALPHA_BY_LUMINANCE): |
| 784 | | { |
| 785 | | std::cout<<"doing conversion MODULATE_ALPHA_BY_LUMINANCE"<<std::endl; |
| 786 | | osg::modifyImage(image,ModulateAlphaByLuminanceOperator()); |
| 787 | | return image; |
| 788 | | } |
| 789 | | case (MODULATE_ALPHA_BY_COLOUR): |
| 790 | | { |
| 791 | | std::cout<<"doing conversion MODULATE_ALPHA_BY_COLOUR"<<std::endl; |
| 792 | | osg::modifyImage(image,ModulateAlphaByColourOperator(colour)); |
| 793 | | return image; |
| 794 | | } |
| 795 | | case (REPLACE_ALPHA_WITH_LUMINANACE): |
| 796 | | { |
| 797 | | std::cout<<"doing conversion REPLACE_ALPHA_WITH_LUMINANACE"<<std::endl; |
| 798 | | osg::modifyImage(image,ReplaceAlphaWithLuminanceOperator()); |
| 799 | | return image; |
| 800 | | } |
| 801 | | case (REPLACE_RGB_WITH_LUMINANCE): |
| 802 | | { |
| 803 | | std::cout<<"doing conversion REPLACE_ALPHA_WITH_LUMINANACE"<<std::endl; |
| 804 | | osg::Image* newImage = new osg::Image; |
| 805 | | newImage->allocateImage(image->s(), image->t(), image->r(), GL_LUMINANCE, image->getDataType()); |
| 806 | | osg::copyImage(image, 0, 0, 0, image->s(), image->t(), image->r(), |
| 807 | | newImage, 0, 0, 0, false); |
| 808 | | return newImage; |
| 809 | | } |
| 810 | | default: |
| 811 | | return image; |
| 812 | | } |
| 813 | | } |
| 814 | | |
| 815 | | |
| 816 | | osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename) |
| 817 | | { |
| 818 | | std::string foundFile = osgDB::findDataFile(filename); |
| 819 | | if (foundFile.empty()) |
| 820 | | { |
| 821 | | std::cout<<"Error: could not find transfer function file : "<<filename<<std::endl; |
| 822 | | return 0; |
| 823 | | } |
| 824 | | |
| 825 | | std::cout<<"Reading transfer function "<<filename<<std::endl; |
| 826 | | |
| 827 | | osg::TransferFunction1D::ValueMap valueMap; |
| 828 | | osgDB::ifstream fin(foundFile.c_str()); |
| 829 | | while(fin) |
| 830 | | { |
| 831 | | float value, red, green, blue, alpha; |
| 832 | | fin >> value >> red >> green >> blue >> alpha; |
| 833 | | if (fin) |
| 834 | | { |
| 835 | | std::cout<<"value = "<<value<<" ("<<red<<", "<<green<<", "<<blue<<", "<<alpha<<")"<<std::endl; |
| 836 | | valueMap[value] = osg::Vec4(red,green,blue,alpha); |
| 837 | | } |
| 838 | | } |
| 839 | | |
| 840 | | if (valueMap.empty()) |
| 841 | | { |
| 842 | | std::cout<<"Error: No values read from transfer function file: "<<filename<<std::endl; |
| 843 | | return 0; |
| 844 | | } |
| 845 | | |
| 846 | | osg::TransferFunction1D* tf = new osg::TransferFunction1D; |
| 847 | | tf->assign(valueMap, true); |
| 848 | | |
| 849 | | return tf; |
| 850 | | } |