mirror of https://github.com/axmolengine/axmol.git
for MTL layer
This commit is contained in:
parent
c08e2cda4d
commit
c180c29d32
|
@ -1448,7 +1448,11 @@ bool Image::initWithETCData(const unsigned char* data, ssize_t dataLen, bool own
|
|||
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
|
||||
#if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL)
|
||||
_pixelFormat = backend::PixelFormat::ETC;
|
||||
_data = data;
|
||||
if(ownData) _data = (unsigned char*)data;
|
||||
else {
|
||||
_data = (unsigned char*)malloc(dataLen);
|
||||
if(_data) memcpy(_data, data, dataLen);
|
||||
}
|
||||
_dataLen = dataLen;
|
||||
_offset = ETC_PKM_HEADER_SIZE;
|
||||
return true;
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
*/
|
||||
inline bool hasMipmaps() const { return _hasMipmaps; }
|
||||
|
||||
virtual int getCount() const = 0;
|
||||
virtual int getCount() const { return 1; };
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "../Texture.h"
|
||||
#include "DeviceMTL.h"
|
||||
#import <Metal/Metal.h>
|
||||
#include <array>
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
/**
|
||||
|
@ -54,7 +55,7 @@ public:
|
|||
* @param height Specifies the height of the texture image.
|
||||
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
||||
*/
|
||||
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level) override;
|
||||
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Update a two-dimensional texture image in a compressed format
|
||||
|
@ -75,7 +76,7 @@ public:
|
|||
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
||||
* @param data Specifies a pointer to the image data in memory.
|
||||
*/
|
||||
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data) override;
|
||||
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Update a two-dimensional texture subimage in a compressed format
|
||||
|
@ -93,7 +94,7 @@ public:
|
|||
* Update sampler
|
||||
* @param sampler Specifies the sampler descriptor.
|
||||
*/
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) override;
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Read a block of pixels from the drawable texture
|
||||
|
@ -113,13 +114,17 @@ public:
|
|||
* Update texture description.
|
||||
* @param descriptor Specifies texture and sampler descriptor.
|
||||
*/
|
||||
virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor) override;
|
||||
virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index = 0) override;
|
||||
|
||||
int getCount() const override { return _mtlMaxTexIdx + 1; };
|
||||
|
||||
id<MTLTexture> ensure(int index);
|
||||
|
||||
/**
|
||||
* Get MTLTexture object.
|
||||
* @return A MTLTexture object.
|
||||
*/
|
||||
inline id<MTLTexture> getMTLTexture() const { return _mtlTexture; }
|
||||
inline id<MTLTexture> getMTLTexture() const { return _mtlTextures[0]; }
|
||||
|
||||
/**
|
||||
* Get MTLSamplerState object
|
||||
|
@ -128,7 +133,7 @@ public:
|
|||
inline id<MTLSamplerState> getMTLSamplerState() const { return _mtlSamplerState; }
|
||||
|
||||
private:
|
||||
void createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor);
|
||||
void createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor, int index);
|
||||
void createSampler(id<MTLDevice> mtlDevice, const SamplerDescriptor& descriptor);
|
||||
|
||||
MTLSamplerAddressMode _sAddressMode;
|
||||
|
@ -137,8 +142,11 @@ private:
|
|||
MTLSamplerMinMagFilter _magFilter;
|
||||
MTLSamplerMipFilter _mipFilter;
|
||||
|
||||
TextureDescriptor _textureDescriptor;
|
||||
|
||||
id<MTLDevice> _mtlDevice = nil;
|
||||
id<MTLTexture> _mtlTexture = nil;
|
||||
std::array<id<MTLTexture>, CC_META_TEXTURES + 1> _mtlTextures;
|
||||
int _mtlMaxTexIdx = 0;
|
||||
id<MTLSamplerState> _mtlSamplerState = nil;
|
||||
unsigned int _bytesPerRow = 0;
|
||||
};
|
||||
|
@ -160,7 +168,7 @@ public:
|
|||
* Update sampler
|
||||
* @param sampler Specifies the sampler descriptor.
|
||||
*/
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) override;
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Update texutre cube data in give slice side.
|
||||
|
@ -187,7 +195,7 @@ public:
|
|||
* Update texture description.
|
||||
* @param descriptor Specifies texture and sampler descriptor.
|
||||
*/
|
||||
virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor) override;
|
||||
virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Get MTLTexture object.
|
||||
|
|
|
@ -193,25 +193,31 @@ TextureMTL::TextureMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descrip
|
|||
: backend::Texture2DBackend(descriptor)
|
||||
{
|
||||
_mtlDevice = mtlDevice;
|
||||
_mtlTextures.fill(nil);
|
||||
updateTextureDescriptor(descriptor);
|
||||
}
|
||||
|
||||
TextureMTL::~TextureMTL()
|
||||
{
|
||||
[_mtlTexture release];
|
||||
id<MTLTexture> texture;
|
||||
int i = 0;
|
||||
while((texture = _mtlTextures[i++]))
|
||||
[texture release];
|
||||
|
||||
[_mtlSamplerState release];
|
||||
}
|
||||
|
||||
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
|
||||
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int index)
|
||||
{
|
||||
createSampler(_mtlDevice, sampler);
|
||||
}
|
||||
|
||||
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
|
||||
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
|
||||
{
|
||||
TextureBackend::updateTextureDescriptor(descriptor);
|
||||
createTexture(_mtlDevice, descriptor);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||
_textureDescriptor = descriptor;
|
||||
TextureBackend::updateTextureDescriptor(descriptor, index);
|
||||
createTexture(_mtlDevice, descriptor, index);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor, index);
|
||||
if (PixelFormat::RGB888 == _textureFormat)
|
||||
{
|
||||
_bitsPerElement = 4 * 8;
|
||||
|
@ -220,13 +226,16 @@ void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescript
|
|||
_bytesPerRow = descriptor.width * _bitsPerElement / 8 ;
|
||||
}
|
||||
|
||||
void TextureMTL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level)
|
||||
void TextureMTL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index)
|
||||
{
|
||||
updateSubData(0, 0, width, height, level, data);
|
||||
updateSubData(0, 0, width, height, level, data, index);
|
||||
}
|
||||
|
||||
void TextureMTL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data)
|
||||
void TextureMTL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index)
|
||||
{
|
||||
auto mtlTexture = ensure(index);
|
||||
if(!mtlTexture) return;
|
||||
|
||||
MTLRegion region =
|
||||
{
|
||||
{xoffset, yoffset, 0}, // MTLOrigin
|
||||
|
@ -240,7 +249,7 @@ void TextureMTL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::si
|
|||
|
||||
std::size_t bytesPerRow = getBytesPerRow(_textureFormat, width, _bitsPerElement);
|
||||
|
||||
[_mtlTexture replaceRegion:region
|
||||
[mtlTexture replaceRegion:region
|
||||
mipmapLevel:level
|
||||
withBytes:convertedData
|
||||
bytesPerRow:bytesPerRow];
|
||||
|
@ -262,7 +271,7 @@ void TextureMTL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffse
|
|||
updateSubData(xoffset, yoffset, width, height, level, data);
|
||||
}
|
||||
|
||||
void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor)
|
||||
void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor, int index)
|
||||
{
|
||||
MTLPixelFormat pixelFormat = Utils::toMTLPixelFormat(descriptor.textureFormat);
|
||||
if(pixelFormat == MTLPixelFormatInvalid)
|
||||
|
@ -282,9 +291,10 @@ void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor&
|
|||
textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
|
||||
}
|
||||
|
||||
if(_mtlTexture)
|
||||
[_mtlTexture release];
|
||||
_mtlTexture = [mtlDevice newTextureWithDescriptor:textureDescriptor];
|
||||
id<MTLTexture>& mtlTexture = _mtlTextures[index];
|
||||
if(mtlTexture)
|
||||
[mtlTexture release];
|
||||
mtlTexture = [mtlDevice newTextureWithDescriptor:textureDescriptor];
|
||||
}
|
||||
|
||||
void TextureMTL::createSampler(id<MTLDevice> mtlDevice, const SamplerDescriptor &descriptor)
|
||||
|
@ -339,7 +349,7 @@ void TextureMTL::getBytes(std::size_t x, std::size_t y, std::size_t width, std::
|
|||
}
|
||||
};
|
||||
auto flipImageCallback = std::bind(flipImageFunc, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
Utils::getTextureBytes(x, y, width, height, _mtlTexture, flipImageCallback);
|
||||
Utils::getTextureBytes(x, y, width, height, _mtlTextures[0], flipImageCallback);
|
||||
}
|
||||
|
||||
void TextureMTL::generateMipmaps()
|
||||
|
@ -350,11 +360,22 @@ void TextureMTL::generateMipmaps()
|
|||
if(!_hasMipmaps)
|
||||
{
|
||||
_hasMipmaps = true;
|
||||
Utils::generateMipmaps(_mtlTexture);
|
||||
|
||||
Utils::generateMipmaps(_mtlTextures[0]);
|
||||
}
|
||||
}
|
||||
|
||||
id<MTLTexture> TextureMTL::ensure(int index)
|
||||
{
|
||||
if(index < CC_META_TEXTURES) {
|
||||
id<MTLTexture>& mtlTexture = _mtlTextures[index];
|
||||
if(mtlTexture) return mtlTexture;
|
||||
createTexture(_mtlDevice, _textureDescriptor, index);
|
||||
if(_mtlMaxTexIdx < index) _mtlMaxTexIdx = index;
|
||||
return mtlTexture;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
TextureCubeMTL::TextureCubeMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor)
|
||||
: backend::TextureCubemapBackend(descriptor)
|
||||
{
|
||||
|
@ -368,7 +389,7 @@ TextureCubeMTL::~TextureCubeMTL()
|
|||
[_mtlSamplerState release];
|
||||
}
|
||||
|
||||
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
|
||||
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
|
||||
{
|
||||
TextureBackend::updateTextureDescriptor(descriptor);
|
||||
createTexture(_mtlDevice, descriptor);
|
||||
|
@ -431,7 +452,7 @@ void TextureCubeMTL::createSampler(id<MTLDevice> mtlDevice, const SamplerDescrip
|
|||
[mtlDescriptor release];
|
||||
}
|
||||
|
||||
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
|
||||
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int /*index*/)
|
||||
{
|
||||
createSampler(_mtlDevice, sampler);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue