Hello! It's been a year and still no movement on this issue.
To recap, OSG-3.4 on armhf/armel is compiled against GLESv2 and not GL like on other archs. The reason for this is because the osgQt plugin links against Qt that is compiled against GLESv2. This was in order to fix compilation errors that would not exist had Qt be compiled against GL instead. OSG-3.4 only has one reverse dependancy: OpenMW OpenMW doesn't support GLESv2 (and likely never will), so it can't be shipped on armhf/armhf which is a pity because it does run just fine on a Raspberry Pi using Stretch with a custom OSG-3.4 that is linked to GL. [1] [2] In addition to this, in OSG-3.6 (to be released), they've removed the osgQt plugin anyway. To fix this, all we need to do is remove any armhf/armel related issues in debian/control and debian/rules and remove a build dependency on libqt5. Then OSG-3.4 builds without osgQt, against GL and OpenMW works again on armhf/armel. Not only in Debian, but also Ubuntu, Raspbian and any other downstream distros based on Debian. A huge win all around. I've rebased my patch, including s3tc fix (which is backported from OSG-3.6 but required for armhf/armel support of rendering s3tc textures) and attached it to help. Cheers, Bret Curtis [1] https://forum.openmw.org/viewtopic.php?f=2&t=5057 [2] https://www.dropbox.com/s/6r3saos1n4dhtci/openmw_debs.zip?dl=0
diff --git debian/control debian/control index 545a8bbff..bf6fd04b1 100644 --- debian/control +++ debian/control @@ -21,17 +21,13 @@ Build-Depends: debhelper (>= 9), libgdal-dev, libx11-dev, libxmu-dev, - freeglut3-dev [!armel !armhf], - libgl1-mesa-dev [!armel !armhf] | libgl-dev [!armel !armhf], - libegl1-mesa-dev [armel armhf], - libgles2-mesa-dev [armel armhf], + freeglut3-dev, + libgl1-mesa-dev | libgl-dev, libxine2-dev, libavcodec-dev, libswscale-dev, libavdevice-dev, libavresample-dev, - qtbase5-dev, - libqt5opengl5-dev, librsvg2-dev, libpoppler-glib-dev, liblua5.2-dev, @@ -46,8 +42,7 @@ Architecture: any Section: libdevel Depends: ${misc:Depends}, libopenthreads-dev, - libgl1-mesa-dev [!armel !armhf] | libgl-dev [!armel !armhf], - libgles2-mesa-dev [armel armhf], + libgl1-mesa-dev | libgl-dev, libglu-dev, libopenscenegraph-3.4-131 (= ${binary:Version}) Suggests: openscenegraph-doc, diff --git debian/libopenscenegraph-3.4-131.lintian-overrides debian/libopenscenegraph-3.4-131.lintian-overrides index 70731b276..1f17e24f3 100644 --- debian/libopenscenegraph-3.4-131.lintian-overrides +++ debian/libopenscenegraph-3.4-131.lintian-overrides @@ -1 +1 @@ -package-name-doesnt-match-sonames libosg131 libosgAnimation131 libosgDB131 libosgFX131 libosgGA131 libosgManipulator131 libosgParticle131 libosgPresentation131 libosgQt131 libosgShadow131 libosgSim131 libosgTerrain131 libosgText131 libosgUI131 libosgUtil131 libosgViewer131 libosgVolume131 libosgWidget131 +package-name-doesnt-match-sonames libosg131 libosgAnimation131 libosgDB131 libosgFX131 libosgGA131 libosgManipulator131 libosgParticle131 libosgPresentation131 libosgShadow131 libosgSim131 libosgTerrain131 libosgText131 libosgUI131 libosgUtil131 libosgViewer131 libosgVolume131 libosgWidget131 diff --git debian/patches/s3tc.patch debian/patches/s3tc.patch new file mode 100644 index 000000000..b85acafa0 --- /dev/null +++ debian/patches/s3tc.patch @@ -0,0 +1,602 @@ +From b6ec7bb7a4cd06ae95bda087d48c0fb7d5ca0abf Mon Sep 17 00:00:00 2001 +From: Laurens Voerman <l.voer...@rug.nl> +Date: Thu, 12 Oct 2017 13:49:57 +0200 +Subject: [PATCH] added dxtc support in Image::getColor, enhanced + Image::isImageTranslucent to test opacity of dxt3 and dxt5 images + +cherrypick note: will allow running OpenMW on systems not supporting S3TC like Raspberry PI (if combined with a commit in OpenMW that uses the new getColor functionality) +--- + src/osg/Image.cpp | 8 +- + src/osg/dxtctool.cpp | 447 +++++++++++++++++++++++++++++++++++++++++++++++++-- + src/osg/dxtctool.h | 24 ++- + 3 files changed, 462 insertions(+), 17 deletions(-) + +diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp +index 4fe84746e4c..4f06d7521c6 100644 +--- a/src/osg/Image.cpp ++++ b/src/osg/Image.cpp +@@ -1718,7 +1718,7 @@ bool Image::isImageTranslucent() const + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): +- return dxtc_tool::CompressedImageTranslucent(_s, _t, _pixelFormat, _data); ++ return dxtc_tool::isCompressedImageTranslucent(_s, _t, _pixelFormat, _data); + default: + return false; + } +@@ -1918,6 +1918,12 @@ Vec4 _readColor(GLenum pixelFormat, T* data,float scale) + + Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const + { ++ if (dxtc_tool::isDXTC(_pixelFormat)) { ++ unsigned char color[4]; ++ if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) { ++ return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.0f ); ++ } ++ } + const unsigned char* ptr = data(s,t,r); + + switch(_dataType) +diff --git a/src/osg/dxtctool.cpp b/src/osg/dxtctool.cpp +index 7e486972add..b8f9ed2b653 100644 +--- a/src/osg/dxtctool.cpp ++++ b/src/osg/dxtctool.cpp +@@ -166,11 +166,28 @@ struct DXT1TexelsBlock + unsigned short color_1; // extreme + unsigned int texels4x4; // interpolated colors (2 bits per texel) + }; ++struct DXT3TexelsBlock ++{ ++ unsigned short alpha4[4]; // alpha values (4 bits per texel) - 64 bits ++ unsigned short color_0; // colors at their ++ unsigned short color_1; // extreme ++ unsigned int texels4x4; // interpolated colors (2 bits per texel) ++}; + +-bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData) ++struct DXT5TexelsBlock + { +- // OSG_NOTICE<<"CompressedImageTranslucent("<<width<<", "<<height<<", "<<format<<", "<<imageData<<")"<<std::endl; ++ unsigned char alpha_0; // alpha at their ++ unsigned char alpha_1; // extreme ++ unsigned char alpha3[6]; // alpha index values (3 bits per texel) ++ unsigned short color_0; // colors at their ++ unsigned short color_1; // extreme ++ unsigned int texels4x4; // interpolated colors (2 bits per texel) ++}; + ++bool isCompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData) ++{ ++ // OSG_NOTICE<<"isCompressedImageTranslucent("<<width<<", "<<height<<", "<<format<<", "<<imageData<<")"<<std::endl; ++ int blockCount = ((width + 3) >> 2) * ((height + 3) >> 2); + switch(format) + { + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): +@@ -182,9 +199,8 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void + + // Only do the check on the first mipmap level, and stop when we + // see the first alpha texel +- int i = (width*height)/16; +- bool foundAlpha = false; +- while ((!foundAlpha) && (i>0)) ++ int i = blockCount; ++ while (i>0) + { + // See if this block might contain transparent texels + if (texelsBlock->color_0<=texelsBlock->color_1) +@@ -192,7 +208,7 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void + // Scan the texels block for the '11' bit pattern that + // indicates a transparent texel + int j = 0; +- while ((!foundAlpha) && (j < 32)) ++ while (j < 32) + { + // Check for the '11' bit pattern on this texel + if ( ((texelsBlock->texels4x4 >> j) & 0x03) == 0x03) +@@ -214,11 +230,67 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void + } + + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): +- return true; +- ++ { ++ const DXT3TexelsBlock *texelsBlock = reinterpret_cast<const DXT3TexelsBlock*>(imageData); ++ // Only do the check on the first mipmap level, and stop when we see the first alpha texel ++ int i = blockCount; ++ while (i>0) ++ { ++ for (int j =0; j < 4; ++j) ++ if ( texelsBlock->alpha4[j] != 0xFFFF) //4 pixels at once ++ return true; //not fully opaque ++ // Next block ++ --i; ++ ++texelsBlock; ++ } ++ return false; ++ } + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): +- return true; ++ { ++ const DXT5TexelsBlock *texelsBlock = reinterpret_cast<const DXT5TexelsBlock*>(imageData); ++ // Only do the check on the first mipmap level, and stop when we see the first alpha texel ++ int i = blockCount; ++ unsigned char alphaBlock[8]; ++ while (i>0) ++ { ++ bool eightStep = texelsBlock->alpha_0 > texelsBlock->alpha_1; ++ alphaBlock[0] = texelsBlock->alpha_0; ++ alphaBlock[1] = texelsBlock->alpha_1; ++ if (eightStep) { ++ if (texelsBlock->alpha_0 < 255) return true; //not fully opaque ++ alphaBlock[2] = (6 * alphaBlock[0] + 1 * alphaBlock[1] + 3) / 7; // bit code 010 ++ alphaBlock[3] = (5 * alphaBlock[0] + 2 * alphaBlock[1] + 3) / 7; // bit code 011 ++ alphaBlock[4] = (4 * alphaBlock[0] + 3 * alphaBlock[1] + 3) / 7; // bit code 100 ++ alphaBlock[5] = (3 * alphaBlock[0] + 4 * alphaBlock[1] + 3) / 7; // bit code 101 ++ alphaBlock[6] = (2 * alphaBlock[0] + 5 * alphaBlock[1] + 3) / 7; // bit code 110 ++ alphaBlock[7] = (1 * alphaBlock[0] + 6 * alphaBlock[1] + 3) / 7; // bit code 111 ++ } else { ++ alphaBlock[2] = (4 * alphaBlock[0] + 1 * alphaBlock[1] + 2) / 5; // bit code 010 ++ alphaBlock[3] = (3 * alphaBlock[0] + 2 * alphaBlock[1] + 2) / 5; // bit code 011 ++ alphaBlock[4] = (2 * alphaBlock[0] + 3 * alphaBlock[1] + 2) / 5; // bit code 100 ++ alphaBlock[5] = (1 * alphaBlock[0] + 4 * alphaBlock[1] + 2) / 5; // bit code 101 ++ alphaBlock[6] = 0; // bit code 110 ++ alphaBlock[7] = 255; // bit code 111 ++ } + ++ int last_added_byte = 1; ++ unsigned short running_a_index = texelsBlock->alpha3[0] + (((unsigned short)texelsBlock->alpha3[last_added_byte]) << 8); ++ for (int j = 0; j < 16; ++j) { ++ unsigned char alphaIndex = running_a_index & 0x7; ++ if (alphaBlock[alphaIndex] < 255) return true; //not fully opaque ++ running_a_index >>= 3; ++ if ((3 * j / 8) == last_added_byte) { ++ ++last_added_byte; ++ //(&texelsBlock->alpha3[0]) to avoid gcc warning: array subscript is above array bounds [-Warray-bounds] ++ running_a_index += (((unsigned short)(&(texelsBlock->alpha3[0]))[last_added_byte]) << (8 - (3 * j & 0x7))); ++ } ++ } ++ // Next block ++ --i; ++ ++texelsBlock; ++ } ++ return false; ++ } + default: + break; + } +@@ -226,4 +298,361 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void + return false; + } + ++unsigned short interpolateColors21(unsigned short color1, unsigned short color2) { ++ unsigned short result = (((color1 >> 11) * 2 + (color2 >> 11) + 1) / 3) << 11; ++ result += (((color1 >> 5 & 0x3F) * 2 + (color2 >> 5 & 0x3F) + 1) / 3) << 5; ++ result += (((color1 & 0x1F) * 2 + (color2 & 0x1F) + 1) / 3); ++ return result; ++} ++unsigned short interpolateColors11(unsigned short color1, unsigned short color2) { ++ unsigned short result = (((color1 >> 11) + (color2 >> 11) ) / 2) << 11; ++ result += (((color1 >> 5 & 0x3F) + (color2 >> 5 & 0x3F)) / 2) << 5; ++ result += (((color1 & 0x1F) + (color2 & 0x1F) ) / 2); ++ return result; ++} ++ ++bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData) ++{ ++ unsigned short color16 = 0;//RGB 5:6:5 format ++ ++ ++ unsigned int slab4Count = (depth & ~0x3); //4*floor(d/4) ++ unsigned int col = (s >> 2);//(floor(x/4) ++ unsigned int row = (t >> 2);//(floor(y/4) ++ unsigned int blockWidth = (width + 3) >> 2;//ceil(w/4) ++ unsigned int blockHeight = (height + 3) >> 2;//ceil(h/4) ++ int blockNumber = col + blockWidth * row ; // block to jump to ++ ++ if (depth > 1) { ++// https://www.opengl.org/registry/specs/NV/texture_compression_vtc.txt ++// if (z >= 4*floor(d/4)) { ++// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * (z-4*floor(d/4)) )); ++// } else { ++// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4))); ++// } ++// note floor(a/4) = (a >> 2) ++// note 4*floor(a/4) = a & ~0x3 ++// note ceil(a/4) = ((a + 3) >> 2) ++// ++// rewrite: this describes the final blocks as consecutive 4x4x1 blocks - and thats not in the wording of the specs ++// if (r >= slab4Count) { ++// blockNumber = (blockWidth * blockHeight * slab4Count + col + blockWidth * (row + blockHeight * (r-slab4Count) )); ++// } else { ++// blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ); ++// } ++ ++// or in the version of the openGL specs: ++// if (z >= 4*floor(d/4)) { ++// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + (z - 4*floor(d/4)) * ( (floor(x/4) + ceil(w/4) * (floor(y/4) ); ++// } else { ++// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4))); ++// } ++ ++ unsigned int sub_r = r & 0x3;//(r-slab4Count) ++ if (r >= slab4Count) { //slice number beyond 4x4x4 slabs ++ unsigned int blockDepth = depth & 0x3;// equals: depth - slab4Count;//depth of this final block: 1/2/3 in case of 4x4x1; 4x4x2 or 4x4x3 bricks ++ blockNumber = (blockWidth * blockHeight * slab4Count //jump full 4x4x4 slabs ++ + blockDepth * ( col + blockWidth * row ) ++ + sub_r); ++ } else { ++ blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ) + sub_r; ++ } ++ } ++ ++ int sub_s = s & 0x3; ++ int sub_t = t & 0x3; ++ switch (format) ++ { ++ case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : ++ case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : ++ { ++ const DXT1TexelsBlock *texelsBlock = reinterpret_cast<const DXT1TexelsBlock*>(imageData); ++ texelsBlock += blockNumber; //jump to block ++ char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" ++ color[3] = 255; ++ switch (index) { ++ case 0: ++ color16 = texelsBlock->color_0; ++ break; ++ case 1: ++ color16 = texelsBlock->color_1; ++ break; ++ case 2: ++ if (texelsBlock->color_0 > texelsBlock->color_1) { ++ color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); ++ } ++ else { ++ color16 = interpolateColors11(texelsBlock->color_0, texelsBlock->color_1); ++ } ++ break; ++ case 3: ++ if (texelsBlock->color_0 > texelsBlock->color_1) { ++ color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); ++ } ++ else { ++ color16 = 0;//black ++ if (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) color[3] = 0;//transparent ++ } ++ break; ++ } ++ break; ++ } ++ case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : ++ { ++ const DXT3TexelsBlock *texelsBlock = reinterpret_cast<const DXT3TexelsBlock*>(imageData); ++ texelsBlock += blockNumber; //jump to block ++ color[3] = 17 * (texelsBlock->alpha4[sub_t] >> 4 * sub_s & 0xF); ++ char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" ++ switch (index) { ++ case 0: ++ color16 = texelsBlock->color_0; ++ break; ++ case 1: ++ color16 = texelsBlock->color_1; ++ break; ++ case 2: ++ color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); ++ break; ++ case 3: ++ color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); ++ break; ++ } ++ break; ++ } ++ case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : ++ { ++ const DXT5TexelsBlock *texelsBlock = reinterpret_cast<const DXT5TexelsBlock*>(imageData); ++ texelsBlock += blockNumber; //jump to block ++ char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" ++ switch (index) { ++ case 0: ++ color16 = texelsBlock->color_0; ++ break; ++ case 1: ++ color16 = texelsBlock->color_1; ++ break; ++ case 2: ++ color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); ++ break; ++ case 3: ++ color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); ++ break; ++ } ++ char pixel = sub_s + 4 * sub_t;//pixel number in block: 0 - 15 ++ char firstBit = 3 * pixel;//least significant bit: range 0 - 45 ++ unsigned char alpha_index; ++ if ((firstBit & 0x7) < 6) { ++ alpha_index = texelsBlock->alpha3[firstBit >> 3] >> (firstBit & 0x7) & 0x7;//grab byte containing least significant bit; shift and get 3 bits ++ } else { ++ alpha_index = texelsBlock->alpha3[firstBit >> 3] >> (firstBit & 0x7); ++ alpha_index |= texelsBlock->alpha3[1 + (firstBit >> 3)] << (8 - (firstBit & 0x7)); ++ alpha_index &= 0x7; ++ } ++ if (alpha_index == 0) { ++ color[3] = texelsBlock->alpha_0; ++ } else { ++ if (alpha_index == 1) { ++ color[3] = texelsBlock->alpha_1; ++ } else { ++ if (texelsBlock->alpha_0 > texelsBlock->alpha_1) { ++ color[3] = ((unsigned short)texelsBlock->alpha_0 * (8 - alpha_index) + (unsigned short)texelsBlock->alpha_1 * (alpha_index - 1) + 3) / 7; ++ } else { ++ if (alpha_index < 6) { ++ color[3] = ((unsigned short)texelsBlock->alpha_0 * (6 - alpha_index) + (unsigned short)texelsBlock->alpha_1 * (alpha_index - 1) + 3) / 5; ++ } else { ++ if (alpha_index == 6) { ++ color[3] = 0; ++ } else { ++ color[3] = 255; ++ } ++ } ++ } ++ } ++ } ++ break; ++ } ++ default: ++ return false; ++ } ++ unsigned short colorChannel = color16 >> 11;//red - 5 bits ++ color[0] = colorChannel << 3 | colorChannel >> 2 ; ++ colorChannel = color16 >> 5 & 0x3F;//green - 6 bits ++ color[1] = colorChannel << 2 | colorChannel >> 3; ++ colorChannel = color16 & 0x1F;//blue - 5 bits ++ color[2] = colorChannel << 3 | colorChannel >> 2; ++ return true; ++} ++void compressedBlockOrientationConversion(const GLenum format, const unsigned char *src_block, unsigned char *dst_block, const osg::Vec3i& srcOrigin, const osg::Vec3i& rowDelta, const osg::Vec3i& columnDelta) ++{ ++ unsigned int src_texels4x4; ++ unsigned int *dst_texels4x4 = NULL; ++ switch (format) ++ { ++ case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : ++ case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : ++ { ++ const DXT1TexelsBlock *src_texelsBlock = reinterpret_cast<const DXT1TexelsBlock*>(src_block); ++ //make a copy as source might be equal to destination ++ src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) ++ DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast<DXT1TexelsBlock*>(dst_block); ++ dst_texels4x4 = &dst_texelsBlock->texels4x4; ++ ++ break; ++ } ++ case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : ++ { ++ const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast<const DXT3TexelsBlock*>(src_block); ++ //make a copy as source might be equal to destination ++ src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) ++ DXT3TexelsBlock *dst_texelsBlock = reinterpret_cast<DXT3TexelsBlock*>(dst_block); ++ dst_texels4x4 = &dst_texelsBlock->texels4x4; ++ unsigned short src_alpha4[4]; // alpha values (4 bits per texel) - 64 bits ++ ++ memcpy(src_alpha4, src_texelsBlock->alpha4, 4 * sizeof(unsigned short));//make a copy as source might be equal to destination ++ ++ memset(dst_texelsBlock->alpha4, 0, 4 * sizeof(unsigned short)); //clear ++ osg::Vec3i source_pixel(srcOrigin); ++ for (int r = 0; r<4; r++)//rows ++ { ++ for (int c = 0; c<4; c++)//columns ++ { ++ int sub_s = source_pixel.x() & 0x3; ++ int sub_t = source_pixel.y() & 0x3; ++ int shiftBits = 4 * sub_s; ++ unsigned int alpha_value = src_alpha4[sub_t] >> shiftBits & 0xf; //four bit alpha values ++ ++ shiftBits = 4 * c;//destination ++ alpha_value <<= shiftBits; ++ dst_texelsBlock->alpha4[r] |= alpha_value; ++ ++ source_pixel = source_pixel + rowDelta; ++ } ++ source_pixel = source_pixel + columnDelta; ++ } ++ break; ++ } ++ case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : ++ { ++ const DXT5TexelsBlock *src_texelsBlock = reinterpret_cast<const DXT5TexelsBlock*>(src_block); ++ //make a copy as source might be equal to destination ++ src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) ++ DXT5TexelsBlock *dst_texelsBlock = reinterpret_cast<DXT5TexelsBlock*>(dst_block); ++ dst_texels4x4 = &dst_texelsBlock->texels4x4; ++ ++ unsigned char src_alpha3[6]; // alpha index values (3 bits per texel) ++ ++ memcpy(src_alpha3, src_texelsBlock->alpha3, 6 * sizeof(unsigned char));//make a copy as source might be equal to destination ++ ++ memset(dst_texelsBlock->alpha3, 0, 6 * sizeof(unsigned char)); //clear ++ osg::Vec3i source_pixel(srcOrigin); ++ unsigned int last_added_byte = 1; ++ unsigned short running_a_index = src_texelsBlock->alpha3[0] + (((unsigned short)src_texelsBlock->alpha3[last_added_byte]) << 8); ++ unsigned int j = 0; ++ for (int r = 0; r<4; r++)//rows ++ { ++ for (int c = 0; c<4; c++)//columns ++ { ++ int sub_s = source_pixel.x() & 0x3; ++ int sub_t = source_pixel.y() & 0x3; ++ ++ unsigned char alphaIndex = running_a_index & 0x7; ++ //store alphaIndex in output position: ++ int shiftBits = 3 * sub_s + 12 * sub_t;//LSB ++ dst_texelsBlock->alpha3[shiftBits >> 3] |= alphaIndex << (shiftBits & 0x7); ++ if ((shiftBits & 0x7) > 5) { ++ dst_texelsBlock->alpha3[1 + (shiftBits >> 3)] |= alphaIndex >> (8 - (shiftBits & 0x7)); ++ } ++ ++ running_a_index >>= 3; ++ if ((3 * ++j / 8) == last_added_byte) { ++ ++last_added_byte; ++ //(&texelsBlock->alpha3[0]) to avoid gcc warning: array subscript is above array bounds [-Warray-bounds] ++ running_a_index += (((unsigned short)(&(src_texelsBlock->alpha3[0]))[last_added_byte]) << (8 - (3 * j & 0x7))); ++ } ++ source_pixel = source_pixel + rowDelta; ++ } ++ source_pixel = source_pixel + columnDelta; ++ } ++ break; ++ } ++ default: ++ return; ++ }//switch ++ ++ //all formats: rearrange the colors ++ *dst_texels4x4 = 0;//clear ++ osg::Vec3i source_pixel(srcOrigin); ++ for (int r = 0; r<4; r++)//rows ++ { ++ for (int c = 0; c<4; c++)//columns ++ { ++ int sub_s = source_pixel.x() & 0x3; ++ int sub_t = source_pixel.y() & 0x3; ++ int shiftBits = 2 * sub_s + 8 * sub_t; ++ unsigned int index = (src_texels4x4 >> (shiftBits)) & 0x3; //two bit "index value" ++ ++ shiftBits = 2 * c + 8 * r;//destination ++ index <<= shiftBits; ++ *dst_texels4x4 |= index; ++ ++ source_pixel = source_pixel + rowDelta; ++ } ++ source_pixel = source_pixel + columnDelta; ++ } ++} ++ ++void compressedBlockStripAlhpa(const GLenum format, const unsigned char *src_block, unsigned char *dst_block) { ++ unsigned int src_texels4x4; ++ char reshuffle[4] = { 1, 0, 3, 2 }; ++ switch (format) ++ { ++ default: ++ case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : ++ case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : ++ { ++ const DXT1TexelsBlock *src_texelsBlock = reinterpret_cast<const DXT1TexelsBlock*>(src_block); ++ //make a copy as source might be equal to destination ++ src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) ++ DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast<DXT1TexelsBlock*>(dst_block); ++ if (src_texelsBlock->color_0 > src_texelsBlock->color_1) { ++ // Four-color block ++ memcpy(dst_texelsBlock, src_texelsBlock, sizeof(DXT1TexelsBlock)); ++ } else { ++ dst_texelsBlock->color_0 = src_texelsBlock->color_1; ++ dst_texelsBlock->color_1 = src_texelsBlock->color_0; ++ dst_texelsBlock->texels4x4 = 0; ++ for (unsigned int shiftBits = 0; shiftBits < 32; shiftBits += 2) { ++ unsigned char index = src_texels4x4 >> shiftBits & 0x3; //two bit "index value" ++ dst_texelsBlock->texels4x4 |= reshuffle[index] << shiftBits; ++ } ++ ++ } ++ break; ++ } ++ case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : ++ case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : ++ { ++ const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast<const DXT3TexelsBlock*>(src_block); ++ //make a copy as source might be equal to destination ++ src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) ++ DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast<DXT1TexelsBlock*>(dst_block); ++ if (src_texelsBlock->color_0 > src_texelsBlock->color_1) { ++ // Four-color block ++ memcpy(dst_texelsBlock, src_texelsBlock, sizeof(DXT3TexelsBlock)); ++ } ++ else { ++ dst_texelsBlock->color_0 = src_texelsBlock->color_1; ++ dst_texelsBlock->color_1 = src_texelsBlock->color_0; ++ dst_texelsBlock->texels4x4 = 0; ++ for (unsigned int shiftBits = 0; shiftBits < 32; shiftBits += 2) { ++ unsigned char index = src_texels4x4 >> shiftBits & 0x3; //two bit "index value" ++ dst_texelsBlock->texels4x4 |= reshuffle[index] << shiftBits; ++ ++ } ++ ++ } ++ break; ++ } ++ } ++} + } // namespace dxtc_tool +diff --git a/src/osg/dxtctool.h b/src/osg/dxtctool.h +index f24cf9c9037..304399d9934 100644 +--- a/src/osg/dxtctool.h ++++ b/src/osg/dxtctool.h +@@ -31,17 +31,18 @@ + // Current version: 1.00 BETA 1 (27/08/2002) + // + // Comment: Only works with DXTC mode supported by OpenGL. +-// (currently: DXT1/DXT3/DXT5) ++// (currently: DXT1/DXT3/DXT5) + // + // History: - + // + ////////////////////////////////////////////////////////////////////// + + #ifndef DXTCTOOL_H +-#define DXTCTOOL_H ++#define DXTCTOOL_H + + #include <osg/GL> + #include <osg/Texture> ++#include <osg/Vec3i> + + #if defined(_MSC_VER) + +@@ -78,10 +79,19 @@ bool isDXTC(GLenum pixelFormat); + + bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels); + +-bool CompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels); ++bool isCompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels); + ++//interpolate RGB565 colors with 2/3 part color1 and 1/3 part color2 ++unsigned short interpolateColors21(unsigned short color1, unsigned short color2); ++//interpolate RGB565 colors with equal weights ++unsigned short interpolateColors11(unsigned short color1, unsigned short color2); + +-// Class holding reference to DXTC image pixels ++bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData); ++ ++void compressedBlockOrientationConversion(const GLenum format, const unsigned char *src_block, unsigned char *dst_block, const osg::Vec3i& srcOrigin, const osg::Vec3i& rowDelta, const osg::Vec3i& columnDelta); ++ ++void compressedBlockStripAlhpa(const GLenum format, const unsigned char *src_block, unsigned char *dst_block); ++// Class holding reference to DXTC image pixels + class dxtc_pixels + { + public: +@@ -102,7 +112,7 @@ class dxtc_pixels + inline bool SupportedFormat() const; + + // Vertical flipping functions +- void VFlip_DXT1() const; ++ void VFlip_DXT1() const; + void VFlip_DXT3() const; + void VFlip_DXT5() const; + +@@ -116,7 +126,7 @@ class dxtc_pixels + inline void BVF_Alpha_DXT5_H2(void * const pBlock) const; // V. flip one alpha (DXT5) block with its virtual height == 2 + inline void BVF_Alpha_DXT5_H4(void * const pBlock) const; // V. flip one alpha (DXT5) block with its virtual height == 4 + inline void BVF_Alpha_DXT5(void * const pBlock1, void * const pBlock2) const; // V. flip and swap two alpha (DXT5) blocks, with their virtual height == 4 +- ++ + // Block localization functions + inline void * GetBlock(size_t i, size_t j, size_t BlockSize) const; + +@@ -155,7 +165,7 @@ inline bool isDXTC(GLenum pixelFormat) + } + + inline bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels) { +- return (dxtc_pixels(Width, Height, Format, pPixels)).VFlip(); ++ return (dxtc_pixels(Width, Height, Format, pPixels)).VFlip(); + } + + diff --git debian/patches/series debian/patches/series index 13d6d5527..3e707aaf5 100644 --- debian/patches/series +++ debian/patches/series @@ -2,3 +2,4 @@ disable-zip-plugin-with-embedded-zlib.patch no-xine-malloc-aligned.diff 0006-Occlusion-Queries-Stuttering-fix-from-upstream.patch 0007-Explicit-signed-char-type-for-portability-base64.patch +s3tc.patch diff --git debian/rules debian/rules index ec4cf21c0..c13ba4217 100755 --- debian/rules +++ debian/rules @@ -23,27 +23,6 @@ CXXFLAGS := ${CXXFLAGS} ${ARCH_CXX_FLAGS} LDFLAGS += -Wl,--as-needed -ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH),armel armhf)) - -ifeq (armhf, $(findstring $(DEB_HOST_ARCH), armhf)) - ARM_FP_SUFFIX := hf -endif - -ARM_DEFINES=-DOSG_GL1_AVAILABLE:BOOL=OFF \ - -DOSG_GL2_AVAILABLE:BOOL=OFF \ - -DOSG_GL3_AVAILABLE:BOOL=OFF \ - -DOSG_GLES1_AVAILABLE:BOOL=OFF \ - -DOSG_GLES2_AVAILABLE:BOOL=ON \ - -DOSG_GL_DISPLAYLISTS_AVAILABLE:BOOL=OFF \ - -DOSG_GL_MATRICES_AVAILABLE:BOOL=OFF \ - -DOSG_GL_VERTEX_FUNCS_AVAILABLE:BOOL=OFF \ - -DOSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE:BOOL=OFF \ - -DOSG_GL_FIXED_FUNCTION_AVAILABLE:BOOL=OFF \ - -DOSG_CPP_EXCEPTIONS_AVAILABLE:BOOL=OFF \ - -DOPENGL_gl_LIBRARY:STRING=/usr/lib/arm-linux-gnueabi$(ARM_FP_SUFFIX)/libGLESv2.so \ - -DOPENGL_egl_LIBRARY:STRING=/usr/lib/arm-linux-gnueabi$(ARM_FP_SUFFIX)/libEGL.so -endif - # # Shared libraries version numbers # @@ -295,8 +274,6 @@ MANEXAMPLES = \ osgwidgettable.1 \ osgwidgetwindow.1 \ osgwindows.1 \ - osgQtBrowser.1 \ - osgQtWidgets.1 \ osganalysis.1 \ osganimationeasemotion.1 \ osganimationmorph.1 \ @@ -318,12 +295,10 @@ MANEXAMPLES = \ osguserstats.1 \ osgvertexattributes.1 \ osgviewerGTK.1 \ - osgviewerQtContext.1 \ osgviewerSDL.1 \ osgvirtualprogram.1 \ present3D.1 \ osguserdata.1 \ - osgviewerQt.1 \ osgviewerWX.1 \ osgatomiccounter.1 \ osgcomputeshaders.1 \ @@ -357,7 +332,7 @@ override_dh_auto_build-indep: mkdir -p html doxygen debian/Doxyfile-openscenegraph # Use Debian's jquery.js - rm html/openscenegraph/jquery.js + rm -f html/openscenegraph/jquery.js find html -name "*.html" -print0 | xargs -0 perl -i -pe 's|src="jquery.js"|src="/usr/share/javascript/jquery/jquery.js"|' @@ -370,5 +345,4 @@ override_dh_auto_configure: -DLIB_POSTFIX="/${DEB_HOST_MULTIARCH}" \ -DCMAKE_RELWITHDEBINFO_POSTFIX="" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DOSG_USE_LOCAL_LUA_SOURCE:BOOL=OFF \ - ${ARM_DEFINES} + -DOSG_USE_LOCAL_LUA_SOURCE:BOOL=OFF