Merge pull request #50 from weiwest/master

add astc support (Great Job)
This commit is contained in:
HALX99 2020-02-12 20:24:29 +08:00 committed by GitHub
commit f6853a5852
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 353 additions and 5 deletions

View File

@ -46,6 +46,7 @@ Configuration::Configuration()
, _supportsETC1(false)
, _supportsS3TC(false)
, _supportsATITC(false)
, _supportsASTC(false)
, _supportsNPOT(false)
, _supportsBGRA8888(false)
, _supportsDiscardFramebuffer(false)
@ -111,6 +112,8 @@ std::string Configuration::getInfo() const
void Configuration::gatherGPUInfo()
{
auto _deviceInfo = backend::Device::getInstance()->getDeviceInfo();
CCLOG("weichao %s",_deviceInfo->getExtension());
_valueDict["vendor"] = Value(_deviceInfo->getVendor());
_valueDict["renderer"] = Value(_deviceInfo->getRenderer());
_valueDict["version"] = Value(_deviceInfo->getVersion());
@ -131,6 +134,10 @@ void Configuration::gatherGPUInfo()
_supportsATITC = _deviceInfo->checkForFeatureSupported(backend::FeatureType::AMD_COMPRESSED_ATC);
_valueDict["supports_ATITC"] = Value(_supportsATITC);
//_supportsASTC = checkForGLExtension("GL_OES_texture_compression_astc");
_supportsASTC = _deviceInfo->checkForFeatureSupported(backend::FeatureType::ASTC);
_valueDict["gl.supports_ASTC"] = Value(_supportsASTC);
_supportsPVRTC = _deviceInfo->checkForFeatureSupported(backend::FeatureType::PVRTC);
_valueDict["supports_PVRTC"] = Value(_supportsPVRTC);
@ -224,6 +231,11 @@ bool Configuration::supportsATITC() const
return _supportsATITC;
}
bool Configuration::supportsASTC() const
{
return _supportsASTC;
}
bool Configuration::supportsBGRA8888() const
{
return _supportsBGRA8888;

View File

@ -119,7 +119,13 @@ public:
* @return Is true if supports ATITC Texture Compressed.
*/
bool supportsATITC() const;
/** Whether or not ASTC Texture Compressed is supported.
*
* @return Is true if supports ASTC Texture Compressed.
*/
bool supportsASTC() const;
/** Whether or not BGRA8888 textures are supported.
*
* @return Is true if supports BGRA8888 textures.
@ -248,6 +254,7 @@ protected:
bool _supportsETC1;
bool _supportsS3TC;
bool _supportsATITC;
bool _supportsASTC;
bool _supportsNPOT;
bool _supportsBGRA8888;
bool _supportsDiscardFramebuffer;

View File

@ -15,6 +15,7 @@ elseif(LINUX OR WINDOWS)
endif()
set(COCOS_BASE_HEADER
base/astc.h
base/pvr.h
base/CCValue.h
base/CCEventListenerMouse.h
@ -131,5 +132,6 @@ set(COCOS_BASE_SRC
base/etc1.cpp
base/pvr.cpp
base/s3tc.cpp
base/astc.cpp
${COCOS_BASE_SPECIFIC_SRC}
)

73
cocos/base/astc.cpp Normal file
View File

@ -0,0 +1,73 @@
/******************************************************************************
ASTC Texture Decompression.
******************************************************************************/
#include "base/astc.h"
#include "astc/astc_codec_internals.h"
// Functions that are used in compilation units we depend on, but don't actually
// use.
//int astc_codec_unlink(const char* filename) { return 0; }
//void astc_codec_internal_error(const char* filename, int linenum) {}
astc_codec_image* load_ktx_uncompressed_image(const char* filename, int padding, int* result) { return 0; }
astc_codec_image* load_dds_uncompressed_image(const char* filename, int padding, int* result) { return 0; }
astc_codec_image* load_tga_image(const char* tga_filename, int padding, int* result) { return 0; }
astc_codec_image* load_image_with_stb(const char* filename, int padding, int* result) { return 0; }
int store_ktx_uncompressed_image(const astc_codec_image* img, const char* filename, int bitness) { return 0; }
int store_dds_uncompressed_image(const astc_codec_image* img, const char* filename, int bitness) { return 0; }
int store_tga_image(const astc_codec_image* img, const char* tga_filename, int bitness) { return 0; }
extern int ASTC_INIT = 0;
uint8_t float2byte(float f) {
if (f > 1.0f) { return 255; }
if (f < 0.0f) { return 0; }
return (uint8_t)(f * 255.0f + 0.5f);
}
uint8_t decompress_astc(const uint8_t* in, uint8_t* out, uint32_t width, uint32_t height, uint32_t xdim, uint32_t ydim, uint32_t datalen)
{
//init astc mode table only once
if (ASTC_INIT <= 0)
{
ASTC_INIT = 1;
build_quantization_mode_table();
}
uint32_t xblocks = (width + xdim - 1) / xdim;
uint32_t yblocks = (height + ydim - 1) / ydim;
imageblock pb;
for (uint32_t by = 0; by < yblocks; by++) {
for (uint32_t bx = 0; bx < xblocks; bx++) {
physical_compressed_block pcb = *(physical_compressed_block*)in;
symbolic_compressed_block scb;
physical_to_symbolic(xdim, ydim, 1, pcb, &scb);
decompress_symbolic_block(DECODE_LDR_SRGB, xdim, ydim, 1, bx * xdim, by * ydim, 0, &scb, &pb);
in += 16;
const float* data = pb.orig_data;
for (uint32_t dy = 0; dy < ydim; dy++) {
uint32_t y = by * ydim + dy;
for (uint32_t dx = 0; dx < xdim; dx++) {
uint32_t x = bx * xdim + dx;
if (x < width && y < height) {
uint8_t* pxl = &out[(width * y + x) * 4];
pxl[0] = float2byte(data[0]);
pxl[1] = float2byte(data[1]);
pxl[2] = float2byte(data[2]);
pxl[3] = float2byte(data[3]);
}
data += 4;
}
}
}
}
return 0;
}

24
cocos/base/astc.h Normal file
View File

@ -0,0 +1,24 @@
/******************************************************************************
ASTC Texture Decompression.
******************************************************************************/
#ifndef __ASTC_H__
#define __ASTC_H__
#include <stdint.h>
// ASTC parameters
#define ASTC_HEAD_SIZE 16
#ifdef __cplusplus
extern "C" {
#endif
uint8_t decompress_astc(const uint8_t* in, uint8_t* out, uint32_t width, uint32_t height, uint32_t xdim, uint32_t ydim, uint32_t datalen);
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__ASTC_H__

View File

@ -93,6 +93,8 @@ extern "C"
#endif //CC_USE_PNG
#include "base/etc1.h"
#include "base/astc.h"
#if CC_USE_JPEG
#include "jpeglib.h"
@ -124,6 +126,8 @@ extern "C"
#define CC_GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
#define CC_GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
#define ASTC_MAGIC_FILE_CONSTANT 0x5CA1AB13
NS_CC_BEGIN
//////////////////////////////////////////////////////////////////////////
@ -435,6 +439,24 @@ namespace
//////////////////////////////////////////////////////////////////////////
//struct and data for ASTC struct
namespace
{
struct ASTCTexHeader
{
uint8_t magic[4];
uint8_t blockdim_x;
uint8_t blockdim_y;
uint8_t blockdim_z;
uint8_t xsize[3]; // x-size = xsize[0] + xsize[1] + xsize[2]
uint8_t ysize[3]; // x-size, y-size and z-size are given in texels;
uint8_t zsize[3]; // block count is inferred
};
}
//atitc struct end
//////////////////////////////////////////////////////////////////////////
namespace
{
typedef struct
@ -599,6 +621,9 @@ bool Image::initWithImageData(const unsigned char* data, ssize_t dataLen, bool o
case Format::ATITC:
ret = initWithATITCData(unpackedData, unpackedLen);
break;
case Format::ASTC:
ret = initWithASTCData(unpackedData, unpackedLen, ownData);
break;
case Format::BMP:
ret = initWithBmpData(unpackedData, unpackedLen);
break;
@ -676,6 +701,19 @@ bool Image::isATITC(const unsigned char *data, ssize_t /*dataLen*/)
return true;
}
bool Image::isASTC(const unsigned char* data, ssize_t /*dataLen*/)
{
ASTCTexHeader* hdr = (ASTCTexHeader*)data;
uint32_t magicval = hdr->magic[0] + 256 * (uint32_t)(hdr->magic[1]) + 65536 * (uint32_t)(hdr->magic[2]) + 16777216 * (uint32_t)(hdr->magic[3]);
if (magicval != ASTC_MAGIC_FILE_CONSTANT)
{
return false;
}
return true;
}
bool Image::isJpg(const unsigned char * data, ssize_t dataLen)
{
if (dataLen <= 4)
@ -749,6 +787,10 @@ Image::Format Image::detectFormat(const unsigned char * data, ssize_t dataLen)
{
return Format::ATITC;
}
else if (isASTC(data, dataLen))
{
return Format::ASTC;
}
else
{
return Format::UNKNOWN;
@ -1524,6 +1566,70 @@ bool Image::initWithETCData(const unsigned char* data, ssize_t dataLen, bool own
return false;
}
bool Image::initWithASTCData(const unsigned char* data, ssize_t dataLen, bool ownData)
{
ASTCTexHeader* header = (ASTCTexHeader*)data;
_width = header->xsize[0] + 256 * header->xsize[1] + 65536 * header->xsize[2];
_height = header->ysize[0] + 256 * header->ysize[1] + 65536 * header->ysize[2];
if (0 == _width || 0 == _height)
{
return false;
}
uint8_t xdim = header->blockdim_x;
uint8_t ydim = header->blockdim_y;
if ((xdim != 4 && xdim != 8) || (ydim != 4 && ydim != 8))
{
CCLOG("unly support 4x4|8x8£¬becouse cocos unly support int bpp");
return false;
}
if (Configuration::getInstance()->supportsASTC())
{
_pixelFormat = backend::PixelFormat::ASTC4;
if (xdim == 8 && ydim == 8)
{
_pixelFormat = backend::PixelFormat::ASTC8;
}
_dataLen = dataLen;
_data = (unsigned char*)data;
_offset = ASTC_HEAD_SIZE;
return true;
}
else
{
CCLOG("cocos2d: Hardware ASTC decoder not present. Using software decoder");
bool ret = true;
_pixelFormat = backend::PixelFormat::RGBA8888;
_dataLen = _width * _height * 32;
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
uint8_t result = decompress_astc(static_cast<const unsigned char*>(data) + ASTC_HEAD_SIZE, _data, _width, _height, xdim, ydim, _dataLen);
if (result != 0)
{
_dataLen = 0;
if (_data != nullptr)
{
free(_data);
_data = nullptr;
}
ret = false;
}
if (ownData) free((void*)data);
return ret;
}
return false;
}
bool Image::initWithTGAData(tImageTGA* tgaData)
{
bool ret = false;

View File

@ -92,6 +92,8 @@ public:
ATITC,
//! TGA
TGA,
//£¡ASTC
ASTC,
//! Raw Data
RAW_DATA,
//! Unknown format
@ -170,6 +172,7 @@ protected:
bool initWithETCData(const unsigned char* data, ssize_t dataLen, bool ownData);
bool initWithS3TCData(const unsigned char * data, ssize_t dataLen);
bool initWithATITCData(const unsigned char *data, ssize_t dataLen);
bool initWithASTCData(const unsigned char* data, ssize_t dataLen, bool ownData);
typedef struct sImageTGA tImageTGA;
bool initWithTGAData(tImageTGA* tgaData);
@ -226,6 +229,7 @@ protected:
bool isEtc(const unsigned char * data, ssize_t dataLen);
bool isS3TC(const unsigned char * data,ssize_t dataLen);
bool isATITC(const unsigned char *data, ssize_t dataLen);
bool isASTC(const unsigned char* data, ssize_t dataLen);
};
// end of platform group

View File

@ -71,7 +71,9 @@ namespace {
PixelFormatInfoMapValue(backend::PixelFormat::A8, Texture2D::PixelFormatInfo(8, false, false)),
PixelFormatInfoMapValue(backend::PixelFormat::I8, Texture2D::PixelFormatInfo(8, false, false)),
PixelFormatInfoMapValue(backend::PixelFormat::AI88, Texture2D::PixelFormatInfo(16, false, true)),
PixelFormatInfoMapValue(backend::PixelFormat::ASTC4, Texture2D::PixelFormatInfo(8, true, true)),
PixelFormatInfoMapValue(backend::PixelFormat::ASTC8, Texture2D::PixelFormatInfo(2, true, true)),
#if defined( GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2, Texture2D::PixelFormatInfo(2, true, false)),
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2A, Texture2D::PixelFormatInfo(2, true, true)),
@ -321,7 +323,7 @@ bool Texture2D::updateWithImage(Image* image, backend::PixelFormat format, int i
updateWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getPixelFormat(), renderFormat, imageWidth, imageHeight, image->hasPremultipliedAlpha(), index);
}
else if (image->isCompressed())
{
{
if (renderFormat != image->getPixelFormat())
{
CCLOG("cocos2d: WARNING: This image is compressed and we can't convert it for now");
@ -383,6 +385,7 @@ bool Texture2D::updateWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::
if (info.compressed && !Configuration::getInstance()->supportsPVRTC()
&& !Configuration::getInstance()->supportsETC()
&& !Configuration::getInstance()->supportsS3TC()
&& !Configuration::getInstance()->supportsASTC()
&& !Configuration::getInstance()->supportsATITC())
{
CCLOG("cocos2d: WARNING: PVRTC/ETC images are not supported");
@ -727,7 +730,12 @@ const char* Texture2D::getStringForFormat() const
case backend::PixelFormat::MTL_BGR5A1:
return "MTL_BGR5A1";
case backend::PixelFormat::ASTC4:
return "ASTC4";
case backend::PixelFormat::ASTC8:
return "ASTC8";
default:
CCASSERT(false , "unrecognized pixel format");
CCLOG("stringForFormat: %ld, cannot give useful result", (long)_pixelFormat);

View File

@ -79,6 +79,10 @@ namespace
return byte(2);
case PixelFormat::MTL_ABGR4:
return byte(2);
case PixelFormat::ASTC4:
return bit(8);
case PixelFormat::ASTC8:
return bit(2);
case PixelFormat::D24S8:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
//ios use MTLPixelFormatDepth32Float_Stencil8 as DepthStencil combined format, its 64 bits

View File

@ -119,6 +119,12 @@ enum class PixelFormat
MTL_BGR5A1,
MTL_ABGR4,
ASTC4,
//! ASTC compressed texture: ASTC 4x4 block
ASTC8,
//! ASTC compressed texture: ASTC 8x8 block
// A packed 32-bit combined depth and stencil pixel format with two nomorlized unsigned integer
// components: 24 bits, typically used for a depth render target, and 8 bits, typically used for
// a stencil render target.

View File

@ -98,6 +98,9 @@ bool DeviceInfoGL::checkForFeatureSupported(FeatureType feature)
case FeatureType::DEPTH24:
featureSupported = checkForGLExtension("GL_OES_depth24");
break;
case FeatureType::ASTC:
featureSupported = checkForGLExtension("GL_OES_texture_compression_astc");
break;
default:
break;
}

View File

@ -253,6 +253,21 @@ void UtilsGL::toGLTypes(PixelFormat textureFormat, GLint &internalFormat, GLuint
format = GL_RGBA;
type = GL_UNSIGNED_SHORT_5_5_5_1;
break;
#ifdef GL_COMPRESSED_RGBA_ASTC_4x4_KHR
case PixelFormat::ASTC4:
internalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
format = 0xFFFFFFFF;
type = 0xFFFFFFFF;
break;
#endif
#ifdef GL_COMPRESSED_RGBA_ASTC_8x8_KHR
case PixelFormat::ASTC8:
internalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
format = 0xFFFFFFFF;
type = 0xFFFFFFFF;
break;
#endif
#ifdef GL_ETC1_RGB8_OES
case PixelFormat::ETC:
internalFormat = GL_ETC1_RGB8_OES;

View File

@ -1,5 +1,5 @@
{
"version": "v26",
"version": "v28",
"zip_file_size": "107642814",
"repo_name": "engine-v5-3rd",
"repo_parent": "https://github.com/c4games/",

View File

@ -61,6 +61,7 @@ SpriteTests::SpriteTests()
ADD_TEST_CASE(Sprite1);
ADD_TEST_CASE(Sprite1BMP);
ADD_TEST_CASE(Sprite1ETC1Alpha);
ADD_TEST_CASE(SpriteASTC);
ADD_TEST_CASE(SpriteBatchNode1);
ADD_TEST_CASE(SpriteAnchorPoint);
ADD_TEST_CASE(SpriteBatchNodeAnchorPoint);
@ -355,6 +356,74 @@ std::string Sprite1ETC1Alpha::subtitle() const
return "Tap screen to add more sprites";
}
//------------------------------------------------------------------
//
// SpriteASTC
//
//------------------------------------------------------------------
SpriteASTC::SpriteASTC()
{
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesEnded = CC_CALLBACK_2(SpriteASTC::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
bool SpriteASTC::init()
{
if (!SpriteTestDemo::init())
return false;
auto& canvasSize = getContentSize();
_background = LayerColor::create(Color4B(15, 19, 42, 255), canvasSize.width, canvasSize.height);
_background->setIgnoreAnchorPointForPosition(false);
_background->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
auto s = Director::getInstance()->getWinSize();
_background->setPosition(Vec2(s.width / 2, s.height / 2));
this->addChild(_background);
addNewSpriteWithCoords();
return true;
}
void SpriteASTC::addNewSpriteWithCoords()
{
auto s = Director::getInstance()->getWinSize();
auto sprite4 = Sprite::create("Images/ASTC_RGBA.astc");
sprite4->setPosition(Vec2(s.width * 0.2, s.height * 0.5));
_background->addChild(sprite4);
auto spriteA4 = Sprite::create("Images/ASTC_RGB.astc");
spriteA4->setPosition(Vec2(s.width * 0.5, s.height * 0.5));
_background->addChild(spriteA4);
auto sprite8 = Sprite::create("Images/ASTC_RGBA_8x8.astc");
sprite8->setPosition(Vec2(s.width * 0.8, s.height * 0.5));
_background->addChild(sprite8);
}
void SpriteASTC::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
{
//for (auto touch : touches)
//{
// auto location = touch->getLocation();
// addNewSpriteWithCoords();
//}
}
std::string SpriteASTC::title() const
{
return "Testing Sprite ASTC support";
}
std::string SpriteASTC::subtitle() const
{
return "";
}
//------------------------------------------------------------------
//
// SpriteBatchNode1

View File

@ -79,6 +79,21 @@ public:
cocos2d::Node* _background;
};
class SpriteASTC : public SpriteTestDemo
{
public:
CREATE_FUNC(SpriteASTC);
SpriteASTC();
bool init() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
void addNewSpriteWithCoords();
void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
cocos2d::Node* _background;
};
class SpriteBatchNode1: public SpriteTestDemo
{
public:

Binary file not shown.

Binary file not shown.

Binary file not shown.