Changeset 12912 for OpenSceneGraph/trunk/src/osg/Image.cpp
- Timestamp:
- 01/24/12 15:34:02 (16 months ago)
- Files:
-
- 1 modified
-
OpenSceneGraph/trunk/src/osg/Image.cpp (modified) (29 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osg/Image.cpp
r12842 r12912 49 49 } 50 50 51 Image::DataIterator::DataIterator(const Image* image): 52 _image(image), 53 _rowNum(0), 54 _imageNum(0), 55 _mipmapNum(0), 56 _currentPtr(0), 57 _currentSize(0) 58 { 59 assign(); 60 } 61 62 Image::DataIterator::DataIterator(const DataIterator& ri): 63 _image(ri._image), 64 _rowNum(ri._rowNum), 65 _imageNum(ri._imageNum), 66 _mipmapNum(ri._mipmapNum), 67 _currentPtr(0), 68 _currentSize(0) 69 { 70 assign(); 71 } 72 73 void Image::DataIterator::operator ++ () 74 { 75 if (!_image || _image->isDataContiguous()) 76 { 77 // for contiguous image data we never need more than one block of data 78 _currentPtr = 0; 79 _currentSize = 0; 80 return; 81 } 82 83 if (_image->isMipmap()) 84 { 85 // advance to next row 86 ++_rowNum; 87 88 if (_rowNum>=_image->t()) 89 { 90 // moved over end of current image so move to next 91 _rowNum = 0; 92 ++_imageNum; 93 94 if (_imageNum>=_image->r()) 95 { 96 // move to next mipmap 97 _imageNum = 0; 98 ++_mipmapNum; 99 100 if (_mipmapNum>=_image->getNumMipmapLevels()) 101 { 102 _currentPtr = 0; 103 _currentSize = 0; 104 return; 105 } 106 } 107 } 108 } 109 else 110 { 111 // advance to next row 112 ++_rowNum; 113 114 if (_rowNum>=_image->t()) 115 { 116 // moved over end of current image so move to next 117 _rowNum = 0; 118 ++_imageNum; 119 120 if (_imageNum>=_image->r()) 121 { 122 // we've moved off the end of the osg::Image so reset to null 123 _currentPtr = 0; 124 _currentSize = 0; 125 return; 126 } 127 } 128 } 129 130 assign(); 131 } 132 133 void Image::DataIterator::assign() 134 { 135 //OSG_NOTICE<<"DataIterator::assign A"<<std::endl; 136 if (!_image) 137 { 138 _currentPtr = 0; 139 _currentSize = 0; 140 return; 141 } 142 143 //OSG_NOTICE<<"DataIterator::assign B"<<std::endl; 144 145 if (_image->isDataContiguous()) 146 { 147 _currentPtr = _image->data(); 148 _currentSize = _image->getTotalSizeInBytesIncludingMipmaps(); 149 150 //OSG_NOTICE<<" _currentPtr="<<(void*)_currentPtr<<std::endl; 151 //OSG_NOTICE<<" _currentSize="<<_currentSize<<std::endl; 152 153 return; 154 } 155 156 //OSG_NOTICE<<"DataIterator::assign C"<<std::endl; 157 158 if (_image->isMipmap()) 159 { 160 //OSG_NOTICE<<"DataIterator::assign D"<<std::endl; 161 162 if (_mipmapNum>=_image->getNumMipmapLevels()) 163 { 164 _currentPtr = 0; 165 _currentSize = 0; 166 return; 167 } 168 const unsigned char* ptr = _image->getMipmapData(_mipmapNum); 169 170 int rowLength = _image->getRowLength()>>_mipmapNum; 171 if (rowLength==0) rowLength = 1; 172 173 int imageHeight = _image->t()>>_mipmapNum; 174 if (imageHeight==0) imageHeight = 1; 175 176 unsigned int rowWidthInBytes = Image::computeRowWidthInBytes(rowLength,_image->getPixelFormat(),_image->getDataType(),_image->getPacking()); 177 unsigned int imageSizeInBytes = rowWidthInBytes*imageHeight; 178 179 _currentPtr = ptr + rowWidthInBytes*_rowNum + imageSizeInBytes*_imageNum; 180 _currentSize = rowWidthInBytes; 181 } 182 else 183 { 184 //OSG_NOTICE<<"DataIterator::assign E"<<std::endl; 185 186 if (_imageNum>=_image->r() || _rowNum>=_image->t()) 187 { 188 _currentPtr = 0; 189 _currentSize = 0; 190 return; 191 } 192 193 //OSG_NOTICE<<"DataIterator::assign F"<<std::endl; 194 195 _currentPtr = _image->data(0, _rowNum, _imageNum); 196 _currentSize = _image->getRowSizeInBytes(); 197 return; 198 } 199 } 200 201 51 202 Image::Image() 52 203 :BufferData(), … … 55 206 _origin(BOTTOM_LEFT), 56 207 _s(0), _t(0), _r(0), 208 _rowLength(0), 57 209 _internalTextureFormat(0), 58 210 _pixelFormat(0), … … 72 224 _origin(image._origin), 73 225 _s(image._s), _t(image._t), _r(image._r), 226 _rowLength(0), 74 227 _internalTextureFormat(image._internalTextureFormat), 75 228 _pixelFormat(image._pixelFormat), … … 85 238 int size = image.getTotalSizeInBytesIncludingMipmaps(); 86 239 setData(new unsigned char [size],USE_NEW_DELETE); 87 memcpy(_data,image._data,size); 240 unsigned char* dest_ptr = _data; 241 for(DataIterator itr(&image); itr.valid(); ++itr) 242 { 243 memcpy(dest_ptr, itr.data(), itr.size()); 244 dest_ptr += itr.size(); 245 } 88 246 } 89 247 } … … 511 669 } 512 670 671 unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing) 672 { 673 switch(pixelFormat) 674 { 675 case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): 676 case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): 677 return osg::maximum(8u,packing); // block size of 8 678 case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): 679 case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): 680 case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): 681 case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): 682 case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): 683 case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): 684 case(GL_ETC1_RGB8_OES): 685 return osg::maximum(16u,packing); // block size of 16 686 case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): 687 case(GL_COMPRESSED_RED_RGTC1_EXT): 688 return osg::maximum(8u,packing); // block size of 8 689 break; 690 case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): 691 case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): 692 return osg::maximum(16u,packing); // block size of 16 693 default: 694 break; 695 } 696 return packing; 697 } 698 513 699 unsigned int Image::computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing) 514 700 { … … 518 704 //OSG_INFO << "width="<<width<<" pixelSize="<<pixelSize<<" width in bit="<<widthInBits<<" packingInBits="<<packingInBits<<" widthInBits%packingInBits="<<widthInBits%packingInBits<<std::endl; 519 705 return (widthInBits/packingInBits + ((widthInBits%packingInBits)?1:0))*packing; 706 } 707 708 unsigned int Image::computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat,GLenum type,int packing) 709 { 710 if (width==0 || height==0 || depth==0) return 0; 711 712 return osg::maximum( 713 Image::computeRowWidthInBytes(width,pixelFormat,type,packing)*height*depth, 714 computeBlockSize(pixelFormat, packing) 715 ); 520 716 } 521 717 … … 582 778 int t = _t; 583 779 int r = _r; 584 585 unsigned int maxValue = 0; 586 for(unsigned int i=0;i<_mipmapData.size() && _mipmapData[i];++i) 587 { 780 unsigned int totalSize = 0; 781 for(unsigned int i=0;i<_mipmapData.size()+1;++i) 782 { 783 totalSize += computeImageSizeInBytes(s, t, r, _pixelFormat, _dataType, _packing); 784 588 785 s >>= 1; 589 786 t >>= 1; 590 787 r >>= 1; 591 maxValue = maximum(maxValue,_mipmapData[i]); 788 789 if (s<1) s=1; 790 if (t<1) t=1; 791 if (r<1) r=1; 592 792 } 593 594 if (s==0) s=1; 595 if (t==0) t=1; 596 if (r==0) r=1; 597 598 unsigned int sizeOfLastMipMap = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing)* r*t; 599 switch(_pixelFormat) 600 { 601 case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): 602 case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): 603 sizeOfLastMipMap = maximum(sizeOfLastMipMap, 8u); // block size of 8 604 break; 605 case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): 606 case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): 607 case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): 608 case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): 609 case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): 610 case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): 611 case(GL_ETC1_RGB8_OES): 612 sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 16 613 break; 614 case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): 615 case(GL_COMPRESSED_RED_RGTC1_EXT): 616 sizeOfLastMipMap = maximum(sizeOfLastMipMap, 8u); // block size of 8 617 break; 618 case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): 619 case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): 620 sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 8 621 break; 622 default: break; 623 } 624 625 // OSG_INFO<<"sizeOfLastMipMap="<<sizeOfLastMipMap<<"\ts="<<s<<"\tt="<<t<<"\tr"<<r<<std::endl; 626 627 return maxValue+sizeOfLastMipMap; 628 793 794 return totalSize; 629 795 } 630 796 … … 686 852 _dataType = type; 687 853 _packing = packing; 854 _rowLength = 0; 688 855 689 856 // preserve internalTextureFormat if already set, otherwise … … 701 868 _dataType = 0; 702 869 _packing = 0; 870 _rowLength = 0; 703 871 704 872 // commenting out reset of _internalTextureFormat as we are changing … … 715 883 unsigned char *data, 716 884 AllocationMode mode, 717 int packing) 885 int packing, 886 int rowLength) 718 887 { 719 888 _mipmapData.clear(); … … 730 899 731 900 _packing = packing; 901 _rowLength = rowLength; 732 902 733 903 dirty(); … … 741 911 742 912 glPixelStorei(GL_PACK_ALIGNMENT,_packing); 913 glPixelStorei(GL_PACK_ROW_LENGTH,_rowLength); 743 914 744 915 glReadPixels(x,y,width,height,format,type,_data); … … 776 947 GLint depth; 777 948 GLint packing; 949 GLint rowLength; 778 950 779 951 GLint numMipMaps = 0; … … 857 1029 glGetIntegerv(GL_UNPACK_ALIGNMENT, &packing); 858 1030 glPixelStorei(GL_PACK_ALIGNMENT, packing); 1031 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength); 1032 glPixelStorei(GL_PACK_ROW_LENGTH, rowLength); 859 1033 860 1034 _data = data; … … 869 1043 _allocationMode=USE_NEW_DELETE; 870 1044 _packing = packing; 871 1045 _rowLength = rowLength; 1046 872 1047 for(i=0;i<numMipMaps;++i) 873 1048 { … … 887 1062 glGetIntegerv(GL_UNPACK_ALIGNMENT, &packing); 888 1063 glPixelStorei(GL_PACK_ALIGNMENT, packing); 1064 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength); 1065 glPixelStorei(GL_PACK_ROW_LENGTH, rowLength); 889 1066 890 1067 unsigned int total_size = 0; … … 928 1105 _allocationMode=USE_NEW_DELETE; 929 1106 _packing = packing; 1107 _rowLength = rowLength; 930 1108 931 1109 for(i=0;i<numMipMaps;++i) … … 970 1148 PixelStorageModes psm; 971 1149 psm.pack_alignment = _packing; 1150 psm.pack_row_length = _rowLength; 972 1151 psm.unpack_alignment = _packing; 973 1152 … … 988 1167 _s = s; 989 1168 _t = t; 1169 _rowLength = 0; 990 1170 _dataType = newDataType; 991 1171 setData(newData,USE_NEW_DELETE); … … 1035 1215 PixelStorageModes psm; 1036 1216 psm.pack_alignment = _packing; 1037 psm.pack_row_length = _s; 1038 psm.unpack_alignment = _packing; 1217 psm.pack_row_length = _rowLength!=0 ? _rowLength : _s; 1218 psm.unpack_alignment = source->getPacking(); 1219 psm.unpack_row_length = source->getRowLength(); 1039 1220 1040 1221 GLint status = gluScaleImage(&psm, _pixelFormat, … … 1048 1229 data_destination); 1049 1230 1050 glPixelStorei(GL_PACK_ROW_LENGTH,0);1051 1052 1231 if (status!=0) 1053 1232 { … … 1068 1247 if (_mipmapData.empty()) 1069 1248 { 1070 1249 unsigned int rowStepInBytes = getRowStepInBytes(); 1250 unsigned int imageStepInBytes = getImageStepInBytes(); 1251 1071 1252 for(int r=0;r<_r;++r) 1072 1253 { 1073 1254 for (int t=0; t<_t; ++t) 1074 1255 { 1075 unsigned char* rowData = _data +t*getRowSizeInBytes()+r*getImageSizeInBytes();1256 unsigned char* rowData = _data + t*rowStepInBytes + r*imageStepInBytes; 1076 1257 unsigned char* left = rowData ; 1077 1258 unsigned char* right = rowData + ((_s-1)*getPixelSizeInBits())/8; … … 1098 1279 } 1099 1280 1100 void flipImageVertical(unsigned char* top, unsigned char* bottom, unsigned int rowSize )1281 void flipImageVertical(unsigned char* top, unsigned char* bottom, unsigned int rowSize, unsigned int rowStep) 1101 1282 { 1102 1283 while(top<bottom) 1103 1284 { 1104 for(unsigned int i=0;i<rowSize;++i, ++top,++bottom) 1105 { 1106 unsigned char temp=*top; 1107 *top = *bottom; 1108 *bottom = temp; 1109 } 1110 bottom -= 2*rowSize; 1285 unsigned char* t = top; 1286 unsigned char* b = bottom; 1287 for(unsigned int i=0;i<rowSize;++i, ++t,++b) 1288 { 1289 unsigned char temp=*t; 1290 *t = *b; 1291 *b = temp; 1292 } 1293 top += rowStep; 1294 bottom -= rowStep; 1111 1295 } 1112 1296 } … … 1126 1310 return; 1127 1311 } 1312 1313 unsigned int rowSize = getRowSizeInBytes(); 1314 unsigned int rowStep = getRowStepInBytes(); 1128 1315 1129 1316 if (_mipmapData.empty()) … … 1136 1323 { 1137 1324 // its not a compressed image, so implement flip oursleves. 1138 1139 unsigned int rowSize = computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing);1140 1325 unsigned char* top = data(0,0,r); 1141 unsigned char* bottom = top + (_t-1)*rowS ize;1326 unsigned char* bottom = top + (_t-1)*rowStep; 1142 1327 1143 flipImageVertical(top, bottom, rowSize );1328 flipImageVertical(top, bottom, rowSize, rowStep); 1144 1329 } 1145 1330 } … … 1150 1335 { 1151 1336 // its not a compressed image, so implement flip oursleves. 1152 unsigned int rowSize = computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing);1153 1337 unsigned char* top = data(0,0,0); 1154 unsigned char* bottom = top + (_t-1)*rowS ize;1155 1156 flipImageVertical(top, bottom, rowSize );1338 unsigned char* bottom = top + (_t-1)*rowStep; 1339 1340 flipImageVertical(top, bottom, rowSize, rowStep); 1157 1341 } 1158 1342 … … 1170 1354 { 1171 1355 // its not a compressed image, so implement flip oursleves. 1172 unsigned int rowSize = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing);1173 1356 unsigned char* top = _data+_mipmapData[i]; 1174 unsigned char* bottom = top + (t-1)*rowS ize;1175 1176 flipImageVertical(top, bottom, rowSize );1357 unsigned char* bottom = top + (t-1)*rowStep; 1358 1359 flipImageVertical(top, bottom, rowSize, rowStep); 1177 1360 } 1178 1361 } … … 1201 1384 } 1202 1385 1203 unsigned int sizeOfSlice = getImageSizeInBytes(); 1204 1205 int r_top = 0; 1206 int r_bottom = _r-1; 1207 for(; r_top<r_bottom; ++r_top,--r_bottom) 1208 { 1209 unsigned char* top_slice = data(0,0,r_top); 1210 unsigned char* bottom_slice = data(0,0,r_bottom); 1211 for(unsigned int i=0; i<sizeOfSlice; ++i, ++top_slice, ++bottom_slice) 1212 { 1213 std::swap(*top_slice, *bottom_slice); 1386 unsigned int sizeOfRow = getRowSizeInBytes(); 1387 1388 int r_front = 0; 1389 int r_back = _r-1; 1390 for(; r_front<r_back; ++r_front,--r_back) 1391 { 1392 for(int row=0; row<_t; ++row) 1393 { 1394 unsigned char* front = data(0, row, r_front); 1395 unsigned char* back = data(0, row, r_back); 1396 for(unsigned int i=0; i<sizeOfRow; ++i, ++front, ++back) 1397 { 1398 std::swap(*front, *back); 1399 } 1214 1400 } 1215 1401 } … … 1426 1612 dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); 1427 1613 1428 // set up the geoset. 1614 // set up the geoset. unsigned int rowSize = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing); 1615 1429 1616 Geometry* geom = new Geometry; 1430 1617 geom->setStateSet(dstate);
