mirror of https://github.com/axmolengine/axmol.git
Committing clang-format changes
This commit is contained in:
parent
05b21f335d
commit
9eeeb151a1
|
@ -60,7 +60,7 @@ bool ComponentContainer::add(Component* com)
|
|||
CCASSERT(false, "ComponentContainer already have this kind of component");
|
||||
break;
|
||||
}
|
||||
hlookup::set_item(_componentMap, componentName, com);//_componentMap[componentName] = com;
|
||||
hlookup::set_item(_componentMap, componentName, com); //_componentMap[componentName] = com;
|
||||
com->retain();
|
||||
com->setOwner(_owner);
|
||||
com->onAdd();
|
||||
|
|
|
@ -149,8 +149,7 @@ public:
|
|||
static FontFNT* create(std::string_view fntFilePath, std::string_view subTextureKey);
|
||||
static FontFNT* create(std::string_view fntFilePath);
|
||||
|
||||
CC_DEPRECATED_ATTRIBUTE static FontFNT* create(std::string_view fntFilePath,
|
||||
const Vec2& imageOffset = Vec2::ZERO);
|
||||
CC_DEPRECATED_ATTRIBUTE static FontFNT* create(std::string_view fntFilePath, const Vec2& imageOffset = Vec2::ZERO);
|
||||
|
||||
/** Purges the cached data.
|
||||
Removes from memory the cached configurations and the atlas name dictionary.
|
||||
|
|
|
@ -875,10 +875,7 @@ bool Label::setBMFontFilePath(std::string_view bmfontFilePath, float fontSize)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Label::setBMFontFilePath(std::string_view bmfontFilePath,
|
||||
const Rect& imageRect,
|
||||
bool imageRotated,
|
||||
float fontSize)
|
||||
bool Label::setBMFontFilePath(std::string_view bmfontFilePath, const Rect& imageRect, bool imageRotated, float fontSize)
|
||||
{
|
||||
FontAtlas* newAtlas = FontAtlasCache::getFontAtlasFNT(bmfontFilePath, imageRect, imageRotated);
|
||||
|
||||
|
|
|
@ -341,9 +341,7 @@ public:
|
|||
float fontSize = 0);
|
||||
|
||||
/** Sets a new bitmap font to Label */
|
||||
virtual bool setBMFontFilePath(std::string_view bmfontFilePath,
|
||||
std::string_view subTextureKey,
|
||||
float fontSize = 0);
|
||||
virtual bool setBMFontFilePath(std::string_view bmfontFilePath, std::string_view subTextureKey, float fontSize = 0);
|
||||
|
||||
/** Sets a new bitmap font to Label */
|
||||
CC_DEPRECATED_ATTRIBUTE virtual bool setBMFontFilePath(std::string_view bmfontFilePath,
|
||||
|
|
|
@ -139,9 +139,9 @@ void Label::updateBMFontScale()
|
|||
auto font = _fontAtlas->getFont();
|
||||
if (_currentLabelType == LabelType::BMFONT)
|
||||
{
|
||||
FontFNT* bmFont = (FontFNT*)font;
|
||||
FontFNT* bmFont = (FontFNT*)font;
|
||||
auto originalFontSize = bmFont->getOriginalFontSize();
|
||||
_bmfontScale = _bmFontSize * CC_CONTENT_SCALE_FACTOR() / originalFontSize;
|
||||
_bmfontScale = _bmFontSize * CC_CONTENT_SCALE_FACTOR() / originalFontSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -52,11 +52,7 @@ MotionStreak::~MotionStreak()
|
|||
CC_SAFE_FREE(_texCoords);
|
||||
}
|
||||
|
||||
MotionStreak* MotionStreak::create(float fade,
|
||||
float minSeg,
|
||||
float stroke,
|
||||
const Color3B& color,
|
||||
std::string_view path)
|
||||
MotionStreak* MotionStreak::create(float fade, float minSeg, float stroke, const Color3B& color, std::string_view path)
|
||||
{
|
||||
MotionStreak* ret = new MotionStreak();
|
||||
if (ret->initWithFade(fade, minSeg, stroke, color, path))
|
||||
|
|
|
@ -74,9 +74,7 @@ void PlistSpriteSheetLoader::load(std::string_view filePath, Texture2D* texture,
|
|||
addSpriteFramesWithDictionary(dict, texture, filePath, cache);
|
||||
}
|
||||
|
||||
void PlistSpriteSheetLoader::load(std::string_view filePath,
|
||||
std::string_view textureFileName,
|
||||
SpriteFrameCache& cache)
|
||||
void PlistSpriteSheetLoader::load(std::string_view filePath, std::string_view textureFileName, SpriteFrameCache& cache)
|
||||
{
|
||||
CCASSERT(!textureFileName.empty(), "texture name should not be null");
|
||||
const auto fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
|
@ -401,7 +399,7 @@ void PlistSpriteSheetLoader::reloadSpriteFramesWithDictionary(ValueMap& dict,
|
|||
|
||||
for (auto& iter : framesDict)
|
||||
{
|
||||
const ValueMap& frameDict = iter.second.asValueMap();
|
||||
const ValueMap& frameDict = iter.second.asValueMap();
|
||||
std::string_view spriteFrameName = iter.first;
|
||||
|
||||
cache.eraseFrame(spriteFrameName);
|
||||
|
|
|
@ -142,7 +142,7 @@ protected:
|
|||
std::vector<Camera*> _cameras; // weak ref to Camera
|
||||
Camera* _defaultCamera = nullptr; // weak ref, default camera created by scene, _cameras[0], Caution that the
|
||||
// default camera can not be added to _cameras before onEnter is called
|
||||
bool _cameraOrderDirty = true; // order is dirty, need sort
|
||||
bool _cameraOrderDirty = true; // order is dirty, need sort
|
||||
EventListenerCustom* _event;
|
||||
|
||||
std::vector<BaseLight*> _lights;
|
||||
|
|
|
@ -288,9 +288,10 @@ void SpriteFrameCache::insertFrame(const std::shared_ptr<SpriteSheet>& spriteShe
|
|||
{
|
||||
spriteSheet->frames.emplace(frameName);
|
||||
_spriteFrames.insert(frameName, spriteFrame); // add SpriteFrame
|
||||
_spriteSheets[spriteSheet->path] = spriteSheet;
|
||||
hlookup::set_item(_spriteFrameToSpriteSheetMap, frameName, spriteSheet); // _spriteFrameToSpriteSheetMap[frameName] = spriteSheet; // insert
|
||||
// index frameName->plist
|
||||
_spriteSheets[spriteSheet->path] = spriteSheet;
|
||||
hlookup::set_item(_spriteFrameToSpriteSheetMap, frameName,
|
||||
spriteSheet); // _spriteFrameToSpriteSheetMap[frameName] = spriteSheet; // insert
|
||||
// index frameName->plist
|
||||
}
|
||||
|
||||
bool SpriteFrameCache::eraseFrame(std::string_view frameName)
|
||||
|
|
|
@ -72,13 +72,13 @@ public:
|
|||
class ISpriteSheetLoader
|
||||
{
|
||||
public:
|
||||
virtual ~ISpriteSheetLoader() = default;
|
||||
virtual uint32_t getFormat() = 0;
|
||||
virtual void load(std::string_view filePath, SpriteFrameCache& cache) = 0;
|
||||
virtual void load(std::string_view filePath, Texture2D* texture, SpriteFrameCache& cache) = 0;
|
||||
virtual ~ISpriteSheetLoader() = default;
|
||||
virtual uint32_t getFormat() = 0;
|
||||
virtual void load(std::string_view filePath, SpriteFrameCache& cache) = 0;
|
||||
virtual void load(std::string_view filePath, Texture2D* texture, SpriteFrameCache& cache) = 0;
|
||||
virtual void load(std::string_view filePath, std::string_view textureFileName, SpriteFrameCache& cache) = 0;
|
||||
virtual void load(const Data& content, Texture2D* texture, SpriteFrameCache& cache) = 0;
|
||||
virtual void reload(std::string_view filePath, SpriteFrameCache& cache) = 0;
|
||||
virtual void load(const Data& content, Texture2D* texture, SpriteFrameCache& cache) = 0;
|
||||
virtual void reload(std::string_view filePath, SpriteFrameCache& cache) = 0;
|
||||
};
|
||||
|
||||
class SpriteSheetLoader : public ISpriteSheetLoader
|
||||
|
@ -92,12 +92,12 @@ public:
|
|||
const std::vector<int>& triangleIndices,
|
||||
PolygonInfo& polygonInfo);
|
||||
|
||||
uint32_t getFormat() override = 0;
|
||||
void load(std::string_view filePath, SpriteFrameCache& cache) override = 0;
|
||||
void load(std::string_view filePath, Texture2D* texture, SpriteFrameCache& cache) override = 0;
|
||||
uint32_t getFormat() override = 0;
|
||||
void load(std::string_view filePath, SpriteFrameCache& cache) override = 0;
|
||||
void load(std::string_view filePath, Texture2D* texture, SpriteFrameCache& cache) override = 0;
|
||||
void load(std::string_view filePath, std::string_view textureFileName, SpriteFrameCache& cache) override = 0;
|
||||
void load(const Data& content, Texture2D* texture, SpriteFrameCache& cache) override = 0;
|
||||
void reload(std::string_view filePath, SpriteFrameCache& cache) override = 0;
|
||||
void load(const Data& content, Texture2D* texture, SpriteFrameCache& cache) override = 0;
|
||||
void reload(std::string_view filePath, SpriteFrameCache& cache) override = 0;
|
||||
};
|
||||
|
||||
// end of _2d group
|
||||
|
|
|
@ -166,7 +166,7 @@ void Animate3D::startWithTarget(Node* target)
|
|||
for (const auto& iter : boneCurves)
|
||||
{
|
||||
std::string_view boneName = iter.first;
|
||||
auto skin = sprite->getSkeleton();
|
||||
auto skin = sprite->getSkeleton();
|
||||
if (skin)
|
||||
{
|
||||
auto bone = skin->getBoneByName(boneName);
|
||||
|
@ -204,7 +204,7 @@ void Animate3D::startWithTarget(Node* target)
|
|||
for (const auto& iter : boneCurves)
|
||||
{
|
||||
std::string_view boneName = iter.first;
|
||||
Node* node = nullptr;
|
||||
Node* node = nullptr;
|
||||
if (target->getName() == boneName)
|
||||
node = target;
|
||||
else
|
||||
|
|
|
@ -33,7 +33,7 @@ Animation3D* Animation3D::create(std::string_view fileName, std::string_view ani
|
|||
{
|
||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
|
||||
fullPath.append("#").append(animationName);
|
||||
auto animation = Animation3DCache::getInstance()->getAnimation(fullPath);
|
||||
auto animation = Animation3DCache::getInstance()->getAnimation(fullPath);
|
||||
if (animation != nullptr)
|
||||
return animation;
|
||||
|
||||
|
|
|
@ -57,11 +57,7 @@ public:
|
|||
* @param path The texture file name of stoke.
|
||||
* @return An autoreleased MotionStreak3D object.
|
||||
*/
|
||||
static MotionStreak3D* create(float fade,
|
||||
float minSeg,
|
||||
float stroke,
|
||||
const Color3B& color,
|
||||
std::string_view path);
|
||||
static MotionStreak3D* create(float fade, float minSeg, float stroke, const Color3B& color, std::string_view path);
|
||||
/** Creates and initializes a motion streak with fade in seconds, minimum segments, stroke's width, color, texture.
|
||||
*
|
||||
* @param fade The fade time, in seconds.
|
||||
|
|
|
@ -223,10 +223,7 @@ public:
|
|||
|
||||
/** load file and set it to meshedatas, nodedatas and materialdatas, obj file .mtl file should be at the same
|
||||
* directory if exist */
|
||||
bool loadFromFile(std::string_view path,
|
||||
NodeDatas* nodedatas,
|
||||
MeshDatas* meshdatas,
|
||||
MaterialDatas* materialdatas);
|
||||
bool loadFromFile(std::string_view path, NodeDatas* nodedatas, MeshDatas* meshdatas, MaterialDatas* materialdatas);
|
||||
|
||||
/**
|
||||
* Visits this Sprite3D's children and draw them recursively.
|
||||
|
|
|
@ -178,8 +178,8 @@ public:
|
|||
~Sprite3DMaterialCache();
|
||||
|
||||
protected:
|
||||
static Sprite3DMaterialCache* _cacheInstance; // instance
|
||||
hlookup::string_map<Texture2D*> _materials; // cached material
|
||||
static Sprite3DMaterialCache* _cacheInstance; // instance
|
||||
hlookup::string_map<Texture2D*> _materials; // cached material
|
||||
};
|
||||
|
||||
// end of 3d group
|
||||
|
|
|
@ -343,7 +343,7 @@ float Terrain::getHeight(float x, float z, Vec3* normal) const
|
|||
normal->z = d - a;
|
||||
normal->normalize();
|
||||
//(*normal) = (1-u)*(1-v)*getNormal(i,j)+ (1-u)*v*getNormal(i,j+1) + u*(1-v)*getNormal(i+1,j)+
|
||||
//u*v*getNormal(i+1,j+1);
|
||||
// u*v*getNormal(i+1,j+1);
|
||||
}
|
||||
float result = (1 - u) * (1 - v) * getImageHeight(i, j) * getScaleY() +
|
||||
(1 - u) * v * getImageHeight(i, j + 1) * getScaleY() +
|
||||
|
|
|
@ -122,8 +122,8 @@ void VertexAttribBinding::parseAttributes()
|
|||
_attributes.clear();
|
||||
_vertexAttribsFlags = 0;
|
||||
|
||||
auto program = _programState->getProgram();
|
||||
_attributes = program->getActiveAttributes();
|
||||
auto program = _programState->getProgram();
|
||||
_attributes = program->getActiveAttributes();
|
||||
}
|
||||
|
||||
bool VertexAttribBinding::hasAttribute(const shaderinfos::VertexKey& key) const
|
||||
|
|
|
@ -32,183 +32,194 @@
|
|||
|
||||
#define LOG_TAG "AudioDecoder"
|
||||
|
||||
namespace cocos2d {
|
||||
namespace cocos2d
|
||||
{
|
||||
|
||||
AudioDecoderEXT::AudioDecoderEXT()
|
||||
: _extRef(nullptr), _fileStream(nullptr), _streamSize(0), _audioFileId(nullptr)
|
||||
{
|
||||
memset(&_outputFormat, 0, sizeof(_outputFormat));
|
||||
}
|
||||
AudioDecoderEXT::AudioDecoderEXT() : _extRef(nullptr), _fileStream(nullptr), _streamSize(0), _audioFileId(nullptr)
|
||||
{
|
||||
memset(&_outputFormat, 0, sizeof(_outputFormat));
|
||||
}
|
||||
|
||||
AudioDecoderEXT::~AudioDecoderEXT()
|
||||
{
|
||||
closeInternal();
|
||||
}
|
||||
AudioDecoderEXT::~AudioDecoderEXT()
|
||||
{
|
||||
closeInternal();
|
||||
}
|
||||
|
||||
bool AudioDecoderEXT::open(std::string_view fullPath)
|
||||
bool AudioDecoderEXT::open(std::string_view fullPath)
|
||||
{
|
||||
bool ret = false;
|
||||
CFURLRef fileURL = nil;
|
||||
do
|
||||
{
|
||||
bool ret = false;
|
||||
CFURLRef fileURL = nil;
|
||||
do
|
||||
BREAK_IF_ERR_LOG(fullPath.empty(), "Invalid path!");
|
||||
|
||||
_fileStream = cocos2d::FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::READ);
|
||||
BREAK_IF_ERR_LOG(_fileStream == nullptr, "FileUtils::openFileStream FAILED for file: %s", fullPath.data());
|
||||
if (_fileStream)
|
||||
{
|
||||
BREAK_IF_ERR_LOG(fullPath.empty(), "Invalid path!");
|
||||
|
||||
_fileStream = cocos2d::FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::READ);
|
||||
BREAK_IF_ERR_LOG(_fileStream == nullptr, "FileUtils::openFileStream FAILED for file: %s", fullPath.data());
|
||||
if (_fileStream)
|
||||
{
|
||||
_streamSize = _fileStream->size(); // cache the stream size
|
||||
}
|
||||
|
||||
OSStatus status = AudioFileOpenWithCallbacks(this, &AudioDecoderEXT::readCallback, nullptr, &AudioDecoderEXT::getSizeCallback, nullptr, 0, &_audioFileId);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "AudioFileOpenWithCallbacks FAILED, Error = %d", (int)status);
|
||||
|
||||
status = ExtAudioFileWrapAudioFileID(_audioFileId, false, &_extRef);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileWrapAudioFileID FAILED, Error = %d", (int)status);
|
||||
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileOpenURL FAILED, Error = %d", (int)status);
|
||||
|
||||
AudioStreamBasicDescription fileFormat;
|
||||
UInt32 propertySize = sizeof(fileFormat);
|
||||
|
||||
// Get the audio data format
|
||||
status = ExtAudioFileGetProperty(_extRef, kExtAudioFileProperty_FileDataFormat, &propertySize, &fileFormat);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %d", (int)status);
|
||||
BREAK_IF_ERR_LOG(fileFormat.mChannelsPerFrame > 2, "Unsupported Format, channel count is greater than stereo!");
|
||||
|
||||
// Set the client format to 16 bit signed integer (native-endian) data
|
||||
// Maintain the channel count and sample rate of the original source format
|
||||
_outputFormat.mSampleRate = fileFormat.mSampleRate;
|
||||
_outputFormat.mChannelsPerFrame = fileFormat.mChannelsPerFrame;
|
||||
_outputFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
_outputFormat.mFramesPerPacket = 1;
|
||||
_outputFormat.mBitsPerChannel = 16;
|
||||
_outputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
|
||||
|
||||
_sampleRate = _outputFormat.mSampleRate;
|
||||
_channelCount = _outputFormat.mChannelsPerFrame;
|
||||
_bytesPerBlock = 2 * _outputFormat.mChannelsPerFrame;
|
||||
|
||||
_outputFormat.mBytesPerPacket = _bytesPerBlock;
|
||||
_outputFormat.mBytesPerFrame = _bytesPerBlock;
|
||||
|
||||
status = ExtAudioFileSetProperty(_extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(_outputFormat), &_outputFormat);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileSetProperty FAILED, Error = %d", (int)status);
|
||||
|
||||
// Get the total frame count
|
||||
SInt64 totalFrames = 0;
|
||||
propertySize = sizeof(totalFrames);
|
||||
status = ExtAudioFileGetProperty(_extRef, kExtAudioFileProperty_FileLengthFrames, &propertySize, &totalFrames);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d",(int)status);
|
||||
BREAK_IF_ERR_LOG(totalFrames <= 0, "Total frames is 0, it's an invalid audio file: %s", fullPath.data());
|
||||
_totalFrames = static_cast<uint32_t>(totalFrames);
|
||||
_isOpened = true;
|
||||
|
||||
ret = true;
|
||||
} while (false);
|
||||
|
||||
if (fileURL != nil)
|
||||
CFRelease(fileURL);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
close();
|
||||
_streamSize = _fileStream->size(); // cache the stream size
|
||||
}
|
||||
|
||||
return ret;
|
||||
OSStatus status = AudioFileOpenWithCallbacks(this, &AudioDecoderEXT::readCallback, nullptr,
|
||||
&AudioDecoderEXT::getSizeCallback, nullptr, 0, &_audioFileId);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "AudioFileOpenWithCallbacks FAILED, Error = %d", (int)status);
|
||||
|
||||
status = ExtAudioFileWrapAudioFileID(_audioFileId, false, &_extRef);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileWrapAudioFileID FAILED, Error = %d", (int)status);
|
||||
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileOpenURL FAILED, Error = %d", (int)status);
|
||||
|
||||
AudioStreamBasicDescription fileFormat;
|
||||
UInt32 propertySize = sizeof(fileFormat);
|
||||
|
||||
// Get the audio data format
|
||||
status = ExtAudioFileGetProperty(_extRef, kExtAudioFileProperty_FileDataFormat, &propertySize, &fileFormat);
|
||||
BREAK_IF_ERR_LOG(status != noErr,
|
||||
"ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %d",
|
||||
(int)status);
|
||||
BREAK_IF_ERR_LOG(fileFormat.mChannelsPerFrame > 2, "Unsupported Format, channel count is greater than stereo!");
|
||||
|
||||
// Set the client format to 16 bit signed integer (native-endian) data
|
||||
// Maintain the channel count and sample rate of the original source format
|
||||
_outputFormat.mSampleRate = fileFormat.mSampleRate;
|
||||
_outputFormat.mChannelsPerFrame = fileFormat.mChannelsPerFrame;
|
||||
_outputFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
_outputFormat.mFramesPerPacket = 1;
|
||||
_outputFormat.mBitsPerChannel = 16;
|
||||
_outputFormat.mFormatFlags =
|
||||
kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
|
||||
|
||||
_sampleRate = _outputFormat.mSampleRate;
|
||||
_channelCount = _outputFormat.mChannelsPerFrame;
|
||||
_bytesPerBlock = 2 * _outputFormat.mChannelsPerFrame;
|
||||
|
||||
_outputFormat.mBytesPerPacket = _bytesPerBlock;
|
||||
_outputFormat.mBytesPerFrame = _bytesPerBlock;
|
||||
|
||||
status = ExtAudioFileSetProperty(_extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(_outputFormat),
|
||||
&_outputFormat);
|
||||
BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileSetProperty FAILED, Error = %d", (int)status);
|
||||
|
||||
// Get the total frame count
|
||||
SInt64 totalFrames = 0;
|
||||
propertySize = sizeof(totalFrames);
|
||||
status = ExtAudioFileGetProperty(_extRef, kExtAudioFileProperty_FileLengthFrames, &propertySize, &totalFrames);
|
||||
BREAK_IF_ERR_LOG(status != noErr,
|
||||
"ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d",
|
||||
(int)status);
|
||||
BREAK_IF_ERR_LOG(totalFrames <= 0, "Total frames is 0, it's an invalid audio file: %s", fullPath.data());
|
||||
_totalFrames = static_cast<uint32_t>(totalFrames);
|
||||
_isOpened = true;
|
||||
|
||||
ret = true;
|
||||
} while (false);
|
||||
|
||||
if (fileURL != nil)
|
||||
CFRelease(fileURL);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void AudioDecoderEXT::close()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioDecoderEXT::close()
|
||||
{
|
||||
closeInternal();
|
||||
}
|
||||
|
||||
uint32_t AudioDecoderEXT::read(uint32_t framesToRead, char* pcmBuf)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
do
|
||||
{
|
||||
closeInternal();
|
||||
BREAK_IF_ERR_LOG(!isOpened(), "decoder isn't openned");
|
||||
BREAK_IF_ERR_LOG(framesToRead == INVALID_FRAME_INDEX, "frameToRead is INVALID_FRAME_INDEX");
|
||||
BREAK_IF_ERR_LOG(framesToRead == 0, "frameToRead is 0");
|
||||
BREAK_IF_ERR_LOG(pcmBuf == nullptr, "pcmBuf is nullptr");
|
||||
|
||||
AudioBufferList bufferList;
|
||||
bufferList.mNumberBuffers = 1;
|
||||
bufferList.mBuffers[0].mDataByteSize = framesToRead * _bytesPerBlock;
|
||||
bufferList.mBuffers[0].mNumberChannels = _outputFormat.mChannelsPerFrame;
|
||||
bufferList.mBuffers[0].mData = pcmBuf;
|
||||
|
||||
UInt32 frames = framesToRead;
|
||||
OSStatus status = ExtAudioFileRead(_extRef, &frames, &bufferList);
|
||||
BREAK_IF(status != noErr);
|
||||
ret = frames;
|
||||
} while (false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AudioDecoderEXT::seek(uint32_t frameOffset)
|
||||
{
|
||||
bool ret = false;
|
||||
do
|
||||
{
|
||||
BREAK_IF_ERR_LOG(!isOpened(), "decoder isn't openned");
|
||||
BREAK_IF_ERR_LOG(frameOffset == INVALID_FRAME_INDEX, "frameIndex is INVALID_FRAME_INDEX");
|
||||
|
||||
OSStatus status = ExtAudioFileSeek(_extRef, frameOffset);
|
||||
BREAK_IF(status != noErr);
|
||||
ret = true;
|
||||
} while (false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioDecoderEXT::closeInternal()
|
||||
{
|
||||
if (_extRef != nullptr)
|
||||
{
|
||||
ExtAudioFileDispose(_extRef);
|
||||
AudioFileClose(_audioFileId);
|
||||
_extRef = nullptr;
|
||||
_audioFileId = nullptr;
|
||||
_fileStream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus AudioDecoderEXT::readCallback(void* inClientData,
|
||||
SInt64 inPosition,
|
||||
UInt32 requestCount,
|
||||
void* buffer,
|
||||
UInt32* actualCount)
|
||||
{
|
||||
if (!inClientData)
|
||||
{
|
||||
return kAudioFileNotOpenError;
|
||||
}
|
||||
|
||||
uint32_t AudioDecoderEXT::read(uint32_t framesToRead, char* pcmBuf)
|
||||
auto* audioDecoder = (AudioDecoderEXT*)inClientData;
|
||||
auto* fileStream = audioDecoder->_fileStream.get();
|
||||
auto currPos = (SInt64)fileStream->tell();
|
||||
auto posDiff = inPosition - currPos;
|
||||
if (posDiff != 0)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
do
|
||||
if (fileStream->seek(posDiff, SEEK_CUR) < 0)
|
||||
{
|
||||
BREAK_IF_ERR_LOG(!isOpened(), "decoder isn't openned");
|
||||
BREAK_IF_ERR_LOG(framesToRead == INVALID_FRAME_INDEX, "frameToRead is INVALID_FRAME_INDEX");
|
||||
BREAK_IF_ERR_LOG(framesToRead == 0, "frameToRead is 0");
|
||||
BREAK_IF_ERR_LOG(pcmBuf == nullptr, "pcmBuf is nullptr");
|
||||
|
||||
AudioBufferList bufferList;
|
||||
bufferList.mNumberBuffers = 1;
|
||||
bufferList.mBuffers[0].mDataByteSize = framesToRead * _bytesPerBlock;
|
||||
bufferList.mBuffers[0].mNumberChannels = _outputFormat.mChannelsPerFrame;
|
||||
bufferList.mBuffers[0].mData = pcmBuf;
|
||||
|
||||
UInt32 frames = framesToRead;
|
||||
OSStatus status = ExtAudioFileRead(_extRef, &frames, &bufferList);
|
||||
BREAK_IF(status != noErr);
|
||||
ret = frames;
|
||||
} while (false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AudioDecoderEXT::seek(uint32_t frameOffset)
|
||||
{
|
||||
bool ret = false;
|
||||
do
|
||||
{
|
||||
BREAK_IF_ERR_LOG(!isOpened(), "decoder isn't openned");
|
||||
BREAK_IF_ERR_LOG(frameOffset == INVALID_FRAME_INDEX, "frameIndex is INVALID_FRAME_INDEX");
|
||||
|
||||
OSStatus status = ExtAudioFileSeek(_extRef, frameOffset);
|
||||
BREAK_IF(status != noErr);
|
||||
ret = true;
|
||||
} while(false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioDecoderEXT::closeInternal()
|
||||
{
|
||||
if (_extRef != nullptr)
|
||||
{
|
||||
ExtAudioFileDispose(_extRef);
|
||||
AudioFileClose(_audioFileId);
|
||||
_extRef = nullptr;
|
||||
_audioFileId = nullptr;
|
||||
_fileStream = nullptr;
|
||||
return kAudioFilePositionError;
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus AudioDecoderEXT::readCallback(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount)
|
||||
const auto count = fileStream->read(buffer, requestCount);
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
if (!inClientData)
|
||||
{
|
||||
return kAudioFileNotOpenError;
|
||||
}
|
||||
|
||||
auto* audioDecoder = (AudioDecoderEXT*)inClientData;
|
||||
auto* fileStream = audioDecoder->_fileStream.get();
|
||||
auto currPos = (SInt64)fileStream->tell();
|
||||
auto posDiff = inPosition - currPos;
|
||||
if (posDiff != 0)
|
||||
{
|
||||
if (fileStream->seek(posDiff, SEEK_CUR) < 0)
|
||||
{
|
||||
return kAudioFilePositionError;
|
||||
}
|
||||
}
|
||||
|
||||
const auto count = fileStream->read(buffer, requestCount);
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
return kAudioFileEndOfFileError;
|
||||
}
|
||||
|
||||
*actualCount = count;
|
||||
|
||||
return noErr;
|
||||
return kAudioFileEndOfFileError;
|
||||
}
|
||||
|
||||
SInt64 AudioDecoderEXT::getSizeCallback(void *inClientData)
|
||||
{
|
||||
auto* audioDecoder = (AudioDecoderEXT*)inClientData;
|
||||
return audioDecoder->_streamSize;
|
||||
}
|
||||
} // namespace cocos2d {
|
||||
*actualCount = count;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
SInt64 AudioDecoderEXT::getSizeCallback(void* inClientData)
|
||||
{
|
||||
auto* audioDecoder = (AudioDecoderEXT*)inClientData;
|
||||
return audioDecoder->_streamSize;
|
||||
}
|
||||
} // namespace cocos2d {
|
||||
|
|
|
@ -410,7 +410,7 @@ AudioCache* AudioEngineImpl::preload(std::string_view filePath, std::function<vo
|
|||
auto it = _audioCaches.find(filePath);
|
||||
if (it == _audioCaches.end())
|
||||
{
|
||||
audioCache = new AudioCache(); // hlookup_second(it);
|
||||
audioCache = new AudioCache(); // hlookup_second(it);
|
||||
_audioCaches.emplace(filePath, std::unique_ptr<AudioCache>(audioCache));
|
||||
audioCache->_fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
unsigned int cacheId = audioCache->_id;
|
||||
|
|
|
@ -293,8 +293,7 @@ std::string_view Console::Utility::getPrompt()
|
|||
|
||||
Console::Command::Command() : _callback(nullptr) {}
|
||||
|
||||
Console::Command::Command(std::string_view name, std::string_view help)
|
||||
: _name(name), _help(help), _callback(nullptr)
|
||||
Console::Command::Command(std::string_view name, std::string_view help) : _name(name), _help(help), _callback(nullptr)
|
||||
{}
|
||||
|
||||
Console::Command::Command(std::string_view name, std::string_view help, const Callback& callback)
|
||||
|
@ -1621,9 +1620,7 @@ void Console::printFileUtils(socket_native_type fd)
|
|||
Console::Utility::sendPrompt(fd);
|
||||
}
|
||||
|
||||
void Console::sendHelp(socket_native_type fd,
|
||||
const hlookup::string_map<Command*>& commands,
|
||||
const char* msg)
|
||||
void Console::sendHelp(socket_native_type fd, const hlookup::string_map<Command*>& commands, const char* msg)
|
||||
{
|
||||
Console::Utility::sendToConsole(fd, msg, strlen(msg));
|
||||
for (auto& it : commands)
|
||||
|
|
|
@ -299,9 +299,7 @@ private:
|
|||
void printFileUtils(socket_native_type fd);
|
||||
|
||||
/** send help message to console */
|
||||
static void sendHelp(socket_native_type fd,
|
||||
const hlookup::string_map<Command*>& commands,
|
||||
const char* msg);
|
||||
static void sendHelp(socket_native_type fd, const hlookup::string_map<Command*>& commands, const char* msg);
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
Copyright (c) 2014 cocos2d-x.org
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -28,36 +28,35 @@
|
|||
#include "platform/CCPlatformConfig.h"
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
|
||||
#include "base/ccMacros.h"
|
||||
#include "base/CCEventDispatcher.h"
|
||||
#include "base/CCEventController.h"
|
||||
#include "base/CCEventListenerController.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "2d/CCLabel.h"
|
||||
# include "base/ccMacros.h"
|
||||
# include "base/CCEventDispatcher.h"
|
||||
# include "base/CCEventController.h"
|
||||
# include "base/CCEventListenerController.h"
|
||||
# include "base/CCDirector.h"
|
||||
# include "2d/CCLabel.h"
|
||||
|
||||
#import <GameController/GameController.h>
|
||||
# import <GameController/GameController.h>
|
||||
|
||||
typedef void (^GCControllerConnectionBlock)(GCController* controller);
|
||||
typedef void (^GCControllerDisconnectionBlock)(GCController* controller);
|
||||
|
||||
@interface GCControllerConnectionEventHandler : NSObject
|
||||
{
|
||||
@interface GCControllerConnectionEventHandler : NSObject {
|
||||
}
|
||||
|
||||
@property (copy) GCControllerConnectionBlock _connectionBlock;
|
||||
@property (copy) GCControllerDisconnectionBlock _disconnectionBlock;
|
||||
@property(copy) GCControllerConnectionBlock _connectionBlock;
|
||||
@property(copy) GCControllerDisconnectionBlock _disconnectionBlock;
|
||||
|
||||
+(GCControllerConnectionEventHandler*) getInstance;
|
||||
+(void) destroyInstance;
|
||||
+ (GCControllerConnectionEventHandler*)getInstance;
|
||||
+ (void)destroyInstance;
|
||||
@end
|
||||
|
||||
@implementation GCControllerConnectionEventHandler
|
||||
|
||||
|
||||
static GCControllerConnectionEventHandler* __instance = nil;
|
||||
|
||||
+(GCControllerConnectionEventHandler*) getInstance {
|
||||
|
||||
+ (GCControllerConnectionEventHandler*)getInstance
|
||||
{
|
||||
|
||||
if (__instance == nil)
|
||||
{
|
||||
__instance = [[GCControllerConnectionEventHandler alloc] init];
|
||||
|
@ -65,7 +64,8 @@ static GCControllerConnectionEventHandler* __instance = nil;
|
|||
return __instance;
|
||||
}
|
||||
|
||||
+(void) destroyInstance {
|
||||
+ (void)destroyInstance
|
||||
{
|
||||
if (__instance)
|
||||
{
|
||||
[__instance release];
|
||||
|
@ -73,33 +73,44 @@ static GCControllerConnectionEventHandler* __instance = nil;
|
|||
}
|
||||
}
|
||||
|
||||
-(void) observerConnection: (GCControllerConnectionBlock) connectBlock disconnection: (GCControllerDisconnectionBlock) disconnectBlock {
|
||||
self._connectionBlock = connectBlock;
|
||||
- (void)observerConnection:(GCControllerConnectionBlock)connectBlock
|
||||
disconnection:(GCControllerDisconnectionBlock)disconnectBlock
|
||||
{
|
||||
self._connectionBlock = connectBlock;
|
||||
self._disconnectionBlock = disconnectBlock;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onControllerConnected:) name:GCControllerDidConnectNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onControllerDisconnected:) name:GCControllerDidDisconnectNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onControllerConnected:)
|
||||
name:GCControllerDidConnectNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onControllerDisconnected:)
|
||||
name:GCControllerDidDisconnectNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
// Have to reset 'copy' property to nil value to avoid memory leak.
|
||||
self._connectionBlock = nil;
|
||||
self._connectionBlock = nil;
|
||||
self._disconnectionBlock = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void) onControllerConnected :(NSNotification *)connectedNotification {
|
||||
GCController *controller =(GCController *)[connectedNotification object];
|
||||
|
||||
- (void)onControllerConnected:(NSNotification*)connectedNotification
|
||||
{
|
||||
GCController* controller = (GCController*)[connectedNotification object];
|
||||
|
||||
self._connectionBlock(controller);
|
||||
}
|
||||
|
||||
-(void) onControllerDisconnected :(NSNotification *)connectedNotification {
|
||||
|
||||
GCController *controller =(GCController *)[connectedNotification object];
|
||||
- (void)onControllerDisconnected:(NSNotification*)connectedNotification
|
||||
{
|
||||
|
||||
GCController* controller = (GCController*)[connectedNotification object];
|
||||
self._disconnectionBlock(controller);
|
||||
}
|
||||
|
||||
|
@ -110,67 +121,64 @@ NS_CC_BEGIN
|
|||
class ControllerImpl
|
||||
{
|
||||
public:
|
||||
ControllerImpl(Controller* controller)
|
||||
: _controller(controller)
|
||||
, _gcController(nil)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ControllerImpl(Controller* controller) : _controller(controller), _gcController(nil) {}
|
||||
|
||||
Controller* _controller;
|
||||
GCController* _gcController;
|
||||
};
|
||||
|
||||
void Controller::startDiscoveryController()
|
||||
{
|
||||
if (NSClassFromString(@"GCController") == nil) {
|
||||
if (NSClassFromString(@"GCController") == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
[GCController startWirelessControllerDiscoveryWithCompletionHandler: nil];
|
||||
|
||||
[[GCControllerConnectionEventHandler getInstance] observerConnection: ^(GCController* gcController) {
|
||||
|
||||
auto controller = new Controller();
|
||||
controller->_impl->_gcController = gcController;
|
||||
controller->_deviceName = [gcController.vendorName UTF8String];
|
||||
|
||||
s_allController.push_back(controller);
|
||||
|
||||
controller->registerListeners();
|
||||
controller->getDeviceName();
|
||||
|
||||
controller->onConnected();
|
||||
|
||||
} disconnection: ^(GCController* gcController) {
|
||||
auto iter = std::find_if(s_allController.begin(), s_allController.end(), [gcController](Controller* c){ return c->_impl->_gcController == gcController; });
|
||||
|
||||
if(iter == s_allController.end())
|
||||
{
|
||||
log("disconnect:Could not find the controller");
|
||||
return;
|
||||
[GCController startWirelessControllerDiscoveryWithCompletionHandler:nil];
|
||||
|
||||
[[GCControllerConnectionEventHandler getInstance]
|
||||
observerConnection:^(GCController* gcController) {
|
||||
auto controller = new Controller();
|
||||
controller->_impl->_gcController = gcController;
|
||||
controller->_deviceName = [gcController.vendorName UTF8String];
|
||||
|
||||
s_allController.push_back(controller);
|
||||
|
||||
controller->registerListeners();
|
||||
controller->getDeviceName();
|
||||
|
||||
controller->onConnected();
|
||||
}
|
||||
|
||||
(*iter)->onDisconnected();
|
||||
s_allController.erase(iter);
|
||||
|
||||
}];
|
||||
disconnection:^(GCController* gcController) {
|
||||
auto iter = std::find_if(s_allController.begin(), s_allController.end(),
|
||||
[gcController](Controller* c) { return c->_impl->_gcController == gcController; });
|
||||
|
||||
if (iter == s_allController.end())
|
||||
{
|
||||
log("disconnect:Could not find the controller");
|
||||
return;
|
||||
}
|
||||
|
||||
(*iter)->onDisconnected();
|
||||
s_allController.erase(iter);
|
||||
}];
|
||||
}
|
||||
|
||||
void Controller::stopDiscoveryController()
|
||||
{
|
||||
if (NSClassFromString(@"GCController") == nil) {
|
||||
if (NSClassFromString(@"GCController") == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
[GCController stopWirelessControllerDiscovery];
|
||||
}
|
||||
|
||||
Controller::Controller()
|
||||
: _deviceId(0)
|
||||
, _controllerTag(TAG_UNSET)
|
||||
, _impl(new ControllerImpl(this))
|
||||
, _connectEvent(nullptr)
|
||||
, _keyEvent(nullptr)
|
||||
, _axisEvent(nullptr)
|
||||
: _deviceId(0)
|
||||
, _controllerTag(TAG_UNSET)
|
||||
, _impl(new ControllerImpl(this))
|
||||
, _connectEvent(nullptr)
|
||||
, _keyEvent(nullptr)
|
||||
, _axisEvent(nullptr)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
@ -178,7 +186,7 @@ Controller::Controller()
|
|||
Controller::~Controller()
|
||||
{
|
||||
delete _impl;
|
||||
|
||||
|
||||
delete _connectEvent;
|
||||
delete _keyEvent;
|
||||
delete _axisEvent;
|
||||
|
@ -188,164 +196,184 @@ void Controller::registerListeners()
|
|||
{
|
||||
if (_impl->_gcController.extendedGamepad != nil)
|
||||
{
|
||||
_impl->_gcController.extendedGamepad.dpad.up.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_UP, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.dpad.down.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_DOWN, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.dpad.left.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_LEFT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.dpad.right.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_RIGHT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.leftThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value){
|
||||
onAxisEvent(Key::JOYSTICK_LEFT_X, value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.leftThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value){
|
||||
onAxisEvent(Key::JOYSTICK_LEFT_Y, -value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.rightThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value){
|
||||
onAxisEvent(Key::JOYSTICK_RIGHT_X, value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.rightThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *axis, float value){
|
||||
onAxisEvent(Key::JOYSTICK_RIGHT_Y, -value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.valueChangedHandler = ^(GCExtendedGamepad *gamepad, GCControllerElement *element){
|
||||
if (element == gamepad.buttonA)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_A, gamepad.buttonA.isPressed, gamepad.buttonA.value, gamepad.buttonA.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonB)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_B, gamepad.buttonB.isPressed, gamepad.buttonB.value, gamepad.buttonB.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonX)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_X, gamepad.buttonX.isPressed, gamepad.buttonX.value, gamepad.buttonX.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonY)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_Y, gamepad.buttonY.isPressed, gamepad.buttonY.value, gamepad.buttonY.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.leftShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_LEFT_SHOULDER, gamepad.leftShoulder.isPressed, gamepad.leftShoulder.value, gamepad.leftShoulder.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.rightShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_RIGHT_SHOULDER, gamepad.rightShoulder.isPressed, gamepad.rightShoulder.value, gamepad.rightShoulder.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.leftTrigger)
|
||||
{
|
||||
onAxisEvent(Key::AXIS_LEFT_TRIGGER, gamepad.leftTrigger.value, gamepad.leftTrigger.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.rightTrigger)
|
||||
{
|
||||
onAxisEvent(Key::AXIS_RIGHT_TRIGGER, gamepad.rightTrigger.value, gamepad.rightTrigger.isAnalog);
|
||||
}
|
||||
_impl->_gcController.extendedGamepad.dpad.up.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_UP, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.dpad.down.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_DOWN, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.dpad.left.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_LEFT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.dpad.right.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_RIGHT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.leftThumbstick.xAxis.valueChangedHandler =
|
||||
^(GCControllerAxisInput* axis, float value) {
|
||||
onAxisEvent(Key::JOYSTICK_LEFT_X, value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.leftThumbstick.yAxis.valueChangedHandler =
|
||||
^(GCControllerAxisInput* axis, float value) {
|
||||
onAxisEvent(Key::JOYSTICK_LEFT_Y, -value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.rightThumbstick.xAxis.valueChangedHandler =
|
||||
^(GCControllerAxisInput* axis, float value) {
|
||||
onAxisEvent(Key::JOYSTICK_RIGHT_X, value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.rightThumbstick.yAxis.valueChangedHandler =
|
||||
^(GCControllerAxisInput* axis, float value) {
|
||||
onAxisEvent(Key::JOYSTICK_RIGHT_Y, -value, axis.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.extendedGamepad.valueChangedHandler = ^(GCExtendedGamepad* gamepad,
|
||||
GCControllerElement* element) {
|
||||
if (element == gamepad.buttonA)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_A, gamepad.buttonA.isPressed, gamepad.buttonA.value, gamepad.buttonA.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonB)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_B, gamepad.buttonB.isPressed, gamepad.buttonB.value, gamepad.buttonB.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonX)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_X, gamepad.buttonX.isPressed, gamepad.buttonX.value, gamepad.buttonX.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonY)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_Y, gamepad.buttonY.isPressed, gamepad.buttonY.value, gamepad.buttonY.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.leftShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_LEFT_SHOULDER, gamepad.leftShoulder.isPressed, gamepad.leftShoulder.value,
|
||||
gamepad.leftShoulder.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.rightShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_RIGHT_SHOULDER, gamepad.rightShoulder.isPressed, gamepad.rightShoulder.value,
|
||||
gamepad.rightShoulder.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.leftTrigger)
|
||||
{
|
||||
onAxisEvent(Key::AXIS_LEFT_TRIGGER, gamepad.leftTrigger.value, gamepad.leftTrigger.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.rightTrigger)
|
||||
{
|
||||
onAxisEvent(Key::AXIS_RIGHT_TRIGGER, gamepad.rightTrigger.value, gamepad.rightTrigger.isAnalog);
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (_impl->_gcController.gamepad != nil)
|
||||
{
|
||||
_impl->_gcController.gamepad.dpad.up.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_UP, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.dpad.down.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_DOWN, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.dpad.left.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_LEFT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.dpad.right.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_RIGHT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.valueChangedHandler = ^(GCGamepad *gamepad, GCControllerElement *element){
|
||||
|
||||
if (element == gamepad.buttonA)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_A, gamepad.buttonA.isPressed, gamepad.buttonA.value, gamepad.buttonA.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonB)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_B, gamepad.buttonB.isPressed, gamepad.buttonB.value, gamepad.buttonB.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonX)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_X, gamepad.buttonX.isPressed, gamepad.buttonX.value, gamepad.buttonX.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonY)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_Y, gamepad.buttonY.isPressed, gamepad.buttonY.value, gamepad.buttonY.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.leftShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_LEFT_SHOULDER, gamepad.leftShoulder.isPressed, gamepad.leftShoulder.value, gamepad.leftShoulder.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.rightShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_RIGHT_SHOULDER, gamepad.rightShoulder.isPressed, gamepad.rightShoulder.value, gamepad.rightShoulder.isAnalog);
|
||||
}
|
||||
_impl->_gcController.gamepad.dpad.up.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_UP, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.dpad.down.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_DOWN, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.dpad.left.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_LEFT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.dpad.right.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_RIGHT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.gamepad.valueChangedHandler = ^(GCGamepad* gamepad, GCControllerElement* element) {
|
||||
if (element == gamepad.buttonA)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_A, gamepad.buttonA.isPressed, gamepad.buttonA.value, gamepad.buttonA.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonB)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_B, gamepad.buttonB.isPressed, gamepad.buttonB.value, gamepad.buttonB.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonX)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_X, gamepad.buttonX.isPressed, gamepad.buttonX.value, gamepad.buttonX.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonY)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_Y, gamepad.buttonY.isPressed, gamepad.buttonY.value, gamepad.buttonY.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.leftShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_LEFT_SHOULDER, gamepad.leftShoulder.isPressed, gamepad.leftShoulder.value,
|
||||
gamepad.leftShoulder.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.rightShoulder)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_RIGHT_SHOULDER, gamepad.rightShoulder.isPressed, gamepad.rightShoulder.value,
|
||||
gamepad.rightShoulder.isAnalog);
|
||||
}
|
||||
};
|
||||
}
|
||||
#if defined(CC_TARGET_OS_TVOS)
|
||||
# if defined(CC_TARGET_OS_TVOS)
|
||||
else if (_impl->_gcController.microGamepad != nil)
|
||||
{
|
||||
_impl->_gcController.microGamepad.dpad.up.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_UP, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.dpad.down.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_DOWN, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.dpad.left.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_LEFT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.dpad.right.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed){
|
||||
onButtonEvent(Key::BUTTON_DPAD_RIGHT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.valueChangedHandler = ^(GCMicroGamepad *gamepad, GCControllerElement *element){
|
||||
|
||||
if (element == gamepad.buttonA)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_A, gamepad.buttonA.isPressed, gamepad.buttonA.value, gamepad.buttonA.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonX)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_X, gamepad.buttonX.isPressed, gamepad.buttonX.value, gamepad.buttonX.isAnalog);
|
||||
}
|
||||
_impl->_gcController.microGamepad.dpad.up.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_UP, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.dpad.down.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_DOWN, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.dpad.left.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_LEFT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.dpad.right.valueChangedHandler =
|
||||
^(GCControllerButtonInput* button, float value, BOOL pressed) {
|
||||
onButtonEvent(Key::BUTTON_DPAD_RIGHT, pressed, value, button.isAnalog);
|
||||
};
|
||||
|
||||
_impl->_gcController.microGamepad.valueChangedHandler = ^(GCMicroGamepad* gamepad,
|
||||
GCControllerElement* element) {
|
||||
if (element == gamepad.buttonA)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_A, gamepad.buttonA.isPressed, gamepad.buttonA.value, gamepad.buttonA.isAnalog);
|
||||
}
|
||||
else if (element == gamepad.buttonX)
|
||||
{
|
||||
onButtonEvent(Key::BUTTON_X, gamepad.buttonX.isPressed, gamepad.buttonX.value, gamepad.buttonX.isAnalog);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
_impl->_gcController.controllerPausedHandler = ^(GCController* gcCon){
|
||||
|
||||
auto iter = std::find_if(s_allController.begin(), s_allController.end(), [gcCon](Controller* c){ return c->_impl->_gcController == gcCon; });
|
||||
|
||||
if(iter == s_allController.end())
|
||||
{
|
||||
log("Could not find the controller");
|
||||
return;
|
||||
}
|
||||
|
||||
onButtonEvent(Key::BUTTON_PAUSE, true, 1.0f, false);
|
||||
onButtonEvent(Key::BUTTON_PAUSE, false, 0.0f, false);
|
||||
# endif
|
||||
|
||||
_impl->_gcController.controllerPausedHandler = ^(GCController* gcCon) {
|
||||
auto iter = std::find_if(s_allController.begin(), s_allController.end(),
|
||||
[gcCon](Controller* c) { return c->_impl->_gcController == gcCon; });
|
||||
|
||||
if (iter == s_allController.end())
|
||||
{
|
||||
log("Could not find the controller");
|
||||
return;
|
||||
}
|
||||
|
||||
onButtonEvent(Key::BUTTON_PAUSE, true, 1.0f, false);
|
||||
onButtonEvent(Key::BUTTON_PAUSE, false, 0.0f, false);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -354,10 +382,8 @@ bool Controller::isConnected() const
|
|||
return _impl->_gcController.isAttachedToDevice == YES;
|
||||
}
|
||||
|
||||
void Controller::receiveExternalKeyEvent(int externalKeyCode,bool receive)
|
||||
{
|
||||
}
|
||||
void Controller::receiveExternalKeyEvent(int externalKeyCode, bool receive) {}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif // #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
#endif // #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
EventCustom::EventCustom(std::string_view eventName) : Event(Type::CUSTOM), _userData(nullptr), _eventName(eventName)
|
||||
{}
|
||||
EventCustom::EventCustom(std::string_view eventName) : Event(Type::CUSTOM), _userData(nullptr), _eventName(eventName) {}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -451,9 +451,9 @@ void EventDispatcher::addEventListener(EventListener* listener)
|
|||
|
||||
void EventDispatcher::forceAddEventListener(EventListener* listener)
|
||||
{
|
||||
EventListenerVector* listeners = nullptr;
|
||||
auto listenerID = listener->getListenerID();
|
||||
auto itr = _listenerMap.find(listenerID);
|
||||
EventListenerVector* listeners = nullptr;
|
||||
auto listenerID = listener->getListenerID();
|
||||
auto itr = _listenerMap.find(listenerID);
|
||||
if (itr == _listenerMap.end())
|
||||
{
|
||||
|
||||
|
@ -1303,8 +1303,7 @@ void EventDispatcher::sortEventListeners(std::string_view listenerID)
|
|||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::sortEventListenersOfSceneGraphPriority(std::string_view listenerID,
|
||||
Node* rootNode)
|
||||
void EventDispatcher::sortEventListenersOfSceneGraphPriority(std::string_view listenerID, Node* rootNode)
|
||||
{
|
||||
auto listeners = getListeners(listenerID);
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ public:
|
|||
* Member type K is the keys for the elements in the container. defined in Map<K, V> as an alias of its first
|
||||
* template parameter (Key).
|
||||
*/
|
||||
template<typename K2>
|
||||
template <typename K2>
|
||||
const V at(const K2& key) const
|
||||
{
|
||||
auto iter = _data.find(key);
|
||||
|
@ -305,19 +305,19 @@ public:
|
|||
* Member type 'K' is the type of the keys for the elements in the container,
|
||||
* defined in Map<K, V> as an alias of its first template parameter (Key).
|
||||
*/
|
||||
//size_t erase(const K& k)
|
||||
// size_t erase(const K& k)
|
||||
//{
|
||||
// auto iter = _data.find(k);
|
||||
// if (iter != _data.end())
|
||||
// {
|
||||
// iter->second->release();
|
||||
// _data.erase(iter);
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
// auto iter = _data.find(k);
|
||||
// if (iter != _data.end())
|
||||
// {
|
||||
// iter->second->release();
|
||||
// _data.erase(iter);
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
template<typename _K2>
|
||||
template <typename _K2>
|
||||
size_t erase(const _K2& k)
|
||||
{
|
||||
auto iter = _data.find(k);
|
||||
|
@ -335,7 +335,7 @@ public:
|
|||
*
|
||||
* @param keys Keys of elements to be erased.
|
||||
*/
|
||||
template<typename _K2>
|
||||
template <typename _K2>
|
||||
void erase(const std::vector<_K2>& keys)
|
||||
{
|
||||
for (const auto& key : keys)
|
||||
|
@ -438,7 +438,7 @@ protected:
|
|||
RefMap _data;
|
||||
};
|
||||
|
||||
template<typename _Valty>
|
||||
template <typename _Valty>
|
||||
using StringMap = Map<std::string, _Valty, hlookup::string_hash, hlookup::equal_to>;
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -1114,7 +1114,7 @@ void calculateNamespacePath(std::string_view urlString,
|
|||
size_t loc = urlString.rfind('#');
|
||||
if (loc != std::string::npos)
|
||||
{
|
||||
fileString = urlString.substr(0, loc);
|
||||
fileString = urlString.substr(0, loc);
|
||||
auto namespacePathString = urlString.substr(loc + 1);
|
||||
while ((loc = namespacePathString.find('/')) != std::string::npos)
|
||||
{
|
||||
|
|
|
@ -774,7 +774,7 @@ std::vector<std::string> ZipFile::listFiles(std::string_view pathname) const
|
|||
if (cxx20::starts_with(filename, cxx17::string_view{dirname}))
|
||||
{
|
||||
std::string_view suffix{filename.substr(dirname.length())};
|
||||
auto pos = suffix.find('/');
|
||||
auto pos = suffix.find('/');
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
fileSet.insert(std::string{suffix});
|
||||
|
@ -923,7 +923,7 @@ bool ZipFile::zfopen(std::string_view fileName, ZipFileStream* zfs)
|
|||
auto it = _data->fileList.find(fileName);
|
||||
if (it != _data->fileList.end())
|
||||
{
|
||||
zfs->entry = &it->second;
|
||||
zfs->entry = &it->second;
|
||||
zfs->offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -325,9 +325,7 @@ public:
|
|||
* @warning Recall: you are responsible for calling free() on any Non-nullptr pointer returned.
|
||||
*/
|
||||
CC_DEPRECATED()
|
||||
static unsigned char* getFileDataFromZip(std::string_view zipFilePath,
|
||||
std::string_view filename,
|
||||
ssize_t* size);
|
||||
static unsigned char* getFileDataFromZip(std::string_view zipFilePath, std::string_view filename, ssize_t* size);
|
||||
|
||||
private:
|
||||
/* Only used internal for createWithBuffer() */
|
||||
|
|
|
@ -53,9 +53,9 @@
|
|||
//#define MATH_LOG2E 1.442695040888963387f
|
||||
//#define MATH_PI 3.14159265358979323846f
|
||||
//#define MATH_RANDOM_MINUS1_1() ((2.0f*((float)rand()/RAND_MAX))-1.0f) // Returns a random float between -1
|
||||
//and 1. #define MATH_RANDOM_0_1() ((float)rand()/RAND_MAX) // Returns a random float
|
||||
//between 0 and 1. #define MATH_CLAMP(x, lo, hi) ((x < lo) ? lo : ((x > hi) ? hi : x)) #ifndef M_1_PI #define
|
||||
//M_1_PI 0.31830988618379067154
|
||||
// and 1. #define MATH_RANDOM_0_1() ((float)rand()/RAND_MAX) // Returns a random float
|
||||
// between 0 and 1. #define MATH_CLAMP(x, lo, hi) ((x < lo) ? lo : ((x > hi) ? hi : x)) #ifndef M_1_PI #define
|
||||
// M_1_PI 0.31830988618379067154
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define NS_CC_MATH_BEGIN \
|
||||
|
|
|
@ -129,8 +129,7 @@ public:
|
|||
|
||||
void setOnTaskError(
|
||||
const std::function<
|
||||
void(const DownloadTask& task, int errorCode, int errorCodeInternal, std::string_view errorStr)>&
|
||||
callback)
|
||||
void(const DownloadTask& task, int errorCode, int errorCodeInternal, std::string_view errorStr)>& callback)
|
||||
{
|
||||
onTaskError = callback;
|
||||
};
|
||||
|
@ -141,7 +140,7 @@ public:
|
|||
std::string_view storagePath,
|
||||
std::string_view identifier = "",
|
||||
std::string_view checksum = "",
|
||||
bool background = false);
|
||||
bool background = false);
|
||||
|
||||
private:
|
||||
std::unique_ptr<IDownloaderImpl> _impl;
|
||||
|
|
|
@ -590,9 +590,7 @@ FileUtils::Status FileUtils::getContents(std::string_view filename, ResizableBuf
|
|||
return Status::OK;
|
||||
}
|
||||
|
||||
void FileUtils::writeValueMapToFile(ValueMap dict,
|
||||
std::string_view fullPath,
|
||||
std::function<void(bool)> callback) const
|
||||
void FileUtils::writeValueMapToFile(ValueMap dict, std::string_view fullPath, std::function<void(bool)> callback) const
|
||||
{
|
||||
|
||||
performOperationOffthread(
|
||||
|
@ -637,9 +635,9 @@ std::string FileUtils::getPathForFilename(std::string_view filename,
|
|||
std::string_view resolutionDirectory,
|
||||
std::string_view searchPath) const
|
||||
{
|
||||
auto file = filename;
|
||||
auto file = filename;
|
||||
std::string_view file_path = hlookup::empty_sv;
|
||||
size_t pos = filename.find_last_of('/');
|
||||
size_t pos = filename.find_last_of('/');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
file_path = filename.substr(0, pos + 1);
|
||||
|
@ -1336,8 +1334,7 @@ bool FileUtils::renameFile(std::string_view oldfullpath, std::string_view newful
|
|||
|
||||
if (0 != errorCode)
|
||||
{
|
||||
CCLOGERROR("Fail to rename file %s to %s !Error code is %d", oldfullpath.data(), newfullpath.data(),
|
||||
errorCode);
|
||||
CCLOGERROR("Fail to rename file %s to %s !Error code is %d", oldfullpath.data(), newfullpath.data(), errorCode);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -814,8 +814,7 @@ public:
|
|||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
virtual void listFilesAsync(std::string_view dirPath,
|
||||
std::function<void(std::vector<std::string>)> callback) const;
|
||||
virtual void listFilesAsync(std::string_view dirPath, std::function<void(std::vector<std::string>)> callback) const;
|
||||
|
||||
/**
|
||||
* List all files recursively in a directory.
|
||||
|
|
|
@ -423,7 +423,8 @@ std::string FileUtilsAndroid::getNativeWritableAbsolutePath() const
|
|||
{
|
||||
// Fix for Nexus 10 (Android 4.2 multi-user environment)
|
||||
// the path is retrieved through Java Context.getCacheDir() method
|
||||
std::string path = JniHelper::callStaticStringMethod("org.cocos2dx.lib.Cocos2dxHelper"sv, "getCocos2dxWritablePath"sv);
|
||||
std::string path =
|
||||
JniHelper::callStaticStringMethod("org.cocos2dx.lib.Cocos2dxHelper"sv, "getCocos2dxWritablePath"sv);
|
||||
if (!path.empty())
|
||||
path.append("/");
|
||||
|
||||
|
|
|
@ -398,7 +398,7 @@ private:
|
|||
static std::string getJNISignature(const char*) { return "Ljava/lang/String;"; }
|
||||
|
||||
static std::string getJNISignature(std::string_view) { return "Ljava/lang/String;"; }
|
||||
|
||||
|
||||
static std::string getJNISignature(const std::string&) { return "Ljava/lang/String;"; }
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -29,51 +29,56 @@
|
|||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <string>
|
||||
# include <Foundation/Foundation.h>
|
||||
# include <Cocoa/Cocoa.h>
|
||||
# include <string>
|
||||
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
# import <UIKit/UIKit.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "base/ccTypes.h"
|
||||
#include "platform/apple/CCDevice-apple.h"
|
||||
|
||||
namespace FontUtils {
|
||||
NSMutableParagraphStyle* _calculateParagraphStyle(bool enableWrap, int overflow)
|
||||
{
|
||||
NSMutableParagraphStyle* paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
|
||||
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
return paragraphStyle;
|
||||
}
|
||||
|
||||
NSTextAlignment _calculateTextAlignment(cocos2d::Device::TextAlign align)
|
||||
{
|
||||
unsigned uHoriFlag = (int)align & 0x0f;
|
||||
NSTextAlignment nsAlign = (2 == uHoriFlag) ? NSTextAlignmentRight
|
||||
: (3 == uHoriFlag) ? NSTextAlignmentCenter
|
||||
: NSTextAlignmentLeft;
|
||||
|
||||
return nsAlign;
|
||||
}
|
||||
|
||||
namespace FontUtils
|
||||
{
|
||||
NSMutableParagraphStyle* _calculateParagraphStyle(bool enableWrap, int overflow)
|
||||
{
|
||||
NSMutableParagraphStyle* paragraphStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
|
||||
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
return paragraphStyle;
|
||||
}
|
||||
|
||||
|
||||
CGFloat _calculateTextDrawStartWidth(cocos2d::Device::TextAlign align, CGSize realDimensions, CGSize dimensions)
|
||||
NSTextAlignment _calculateTextAlignment(cocos2d::Device::TextAlign align)
|
||||
{
|
||||
unsigned uHoriFlag = (int)align & 0x0f;
|
||||
NSTextAlignment nsAlign = (2 == uHoriFlag) ? NSTextAlignmentRight
|
||||
: (3 == uHoriFlag) ? NSTextAlignmentCenter
|
||||
: NSTextAlignmentLeft;
|
||||
|
||||
return nsAlign;
|
||||
}
|
||||
|
||||
CGFloat _calculateTextDrawStartWidth(cocos2d::Device::TextAlign align, CGSize realDimensions, CGSize dimensions)
|
||||
{
|
||||
CGFloat xPadding = 0;
|
||||
unsigned uHoriFlag = (int)align & 0x0f;
|
||||
switch (uHoriFlag)
|
||||
{
|
||||
CGFloat xPadding = 0;
|
||||
unsigned uHoriFlag = (int)align & 0x0f;
|
||||
switch (uHoriFlag) {
|
||||
//center
|
||||
case 3: xPadding = (dimensions.width - realDimensions.width) / 2.0f; break;
|
||||
//right
|
||||
case 2: xPadding = dimensions.width - realDimensions.width; break;
|
||||
default: break;
|
||||
}
|
||||
return xPadding;
|
||||
// center
|
||||
case 3:
|
||||
xPadding = (dimensions.width - realDimensions.width) / 2.0f;
|
||||
break;
|
||||
// right
|
||||
case 2:
|
||||
xPadding = dimensions.width - realDimensions.width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return xPadding;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,29 +36,27 @@ THE SOFTWARE.
|
|||
#include "base/CCDirector.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
||||
#define DECLARE_GUARD (void)0 // std::lock_guard<std::recursive_mutex> mutexGuard(_mutex)
|
||||
#define DECLARE_GUARD (void)0 // std::lock_guard<std::recursive_mutex> mutexGuard(_mutex)
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
struct FileUtilsApple::IMPL {
|
||||
IMPL(NSBundle* bundle):bundle_([NSBundle mainBundle]) {}
|
||||
void setBundle(NSBundle* bundle) {
|
||||
bundle_ = bundle;
|
||||
}
|
||||
NSBundle* getBundle() const {
|
||||
return bundle_;
|
||||
}
|
||||
struct FileUtilsApple::IMPL
|
||||
{
|
||||
IMPL(NSBundle* bundle) : bundle_([NSBundle mainBundle]) {}
|
||||
void setBundle(NSBundle* bundle) { bundle_ = bundle; }
|
||||
NSBundle* getBundle() const { return bundle_; }
|
||||
|
||||
private:
|
||||
NSBundle* bundle_;
|
||||
};
|
||||
|
||||
FileUtilsApple::FileUtilsApple() : pimpl_(new IMPL([NSBundle mainBundle])) {
|
||||
}
|
||||
FileUtilsApple::FileUtilsApple() : pimpl_(new IMPL([NSBundle mainBundle])) {}
|
||||
|
||||
FileUtilsApple::~FileUtilsApple() = default;
|
||||
|
||||
#if CC_FILEUTILS_APPLE_ENABLE_OBJC
|
||||
void FileUtilsApple::setBundle(NSBundle* bundle) {
|
||||
void FileUtilsApple::setBundle(NSBundle* bundle)
|
||||
{
|
||||
pimpl_->setBundle(bundle);
|
||||
}
|
||||
#endif
|
||||
|
@ -72,17 +70,16 @@ FileUtils* FileUtils::getInstance()
|
|||
if (s_sharedFileUtils == nullptr)
|
||||
{
|
||||
s_sharedFileUtils = new FileUtilsApple();
|
||||
if(!s_sharedFileUtils->init())
|
||||
if (!s_sharedFileUtils->init())
|
||||
{
|
||||
delete s_sharedFileUtils;
|
||||
s_sharedFileUtils = nullptr;
|
||||
CCLOG("ERROR: Could not init CCFileUtilsApple");
|
||||
delete s_sharedFileUtils;
|
||||
s_sharedFileUtils = nullptr;
|
||||
CCLOG("ERROR: Could not init CCFileUtilsApple");
|
||||
}
|
||||
}
|
||||
return s_sharedFileUtils;
|
||||
}
|
||||
|
||||
|
||||
std::string FileUtilsApple::getWritablePath() const
|
||||
{
|
||||
DECLARE_GUARD;
|
||||
|
@ -98,9 +95,9 @@ std::string FileUtilsApple::getNativeWritableAbsolutePath() const
|
|||
}
|
||||
|
||||
// save to document folder
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
std::string strRet = [documentsDirectory UTF8String];
|
||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString* documentsDirectory = [paths objectAtIndex:0];
|
||||
std::string strRet = [documentsDirectory UTF8String];
|
||||
strRet.append("/");
|
||||
return strRet;
|
||||
}
|
||||
|
@ -121,8 +118,8 @@ bool FileUtilsApple::isFileExistInternal(std::string_view filePath) const
|
|||
size_t pos = filePath.find_last_of("/");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
file = filePath.substr(pos+1);
|
||||
path = filePath.substr(0, pos+1);
|
||||
file = filePath.substr(pos + 1);
|
||||
path = filePath.substr(0, pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -130,16 +127,18 @@ bool FileUtilsApple::isFileExistInternal(std::string_view filePath) const
|
|||
}
|
||||
|
||||
NSString* fullpath = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:file.c_str()]
|
||||
ofType:nil
|
||||
inDirectory:[NSString stringWithUTF8String:path.c_str()]];
|
||||
if (fullpath != nil) {
|
||||
ofType:nil
|
||||
inDirectory:[NSString stringWithUTF8String:path.c_str()]];
|
||||
if (fullpath != nil)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search path is an absolute path.
|
||||
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:filePath.c_str()]]) {
|
||||
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:filePath.c_str()]])
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
@ -147,12 +146,12 @@ bool FileUtilsApple::isFileExistInternal(std::string_view filePath) const
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
|
||||
static int unlink_cb(const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf)
|
||||
{
|
||||
auto ret = remove(fpath);
|
||||
if (ret)
|
||||
{
|
||||
log("Fail to remove: %s ",fpath);
|
||||
log("Fail to remove: %s ", fpath);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -166,56 +165,62 @@ bool FileUtilsApple::removeDirectory(std::string_view path) const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (nftw(path.c_str(),unlink_cb, 64, FTW_DEPTH | FTW_PHYS))
|
||||
if (nftw(path.c_str(), unlink_cb, 64, FTW_DEPTH | FTW_PHYS))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string FileUtilsApple::getPathForDirectory(const std::string &dir, const std::string &resolutionDiretory, const std::string &searchPath) const
|
||||
std::string FileUtilsApple::getPathForDirectory(const std::string& dir,
|
||||
const std::string& resolutionDiretory,
|
||||
const std::string& searchPath) const
|
||||
{
|
||||
auto path = searchPath + resolutionDiretory + dir;
|
||||
|
||||
if(!path.empty() && path[path.length() -1] == '/') {
|
||||
|
||||
if (!path.empty() && path[path.length() - 1] == '/')
|
||||
{
|
||||
path.erase(path.end() - 1);
|
||||
}
|
||||
|
||||
if(path[0] == '/')
|
||||
|
||||
if (path[0] == '/')
|
||||
{
|
||||
BOOL isDir = false;
|
||||
if([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:dir.c_str()]
|
||||
isDirectory:&isDir]) {
|
||||
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:dir.c_str()] isDirectory:&isDir])
|
||||
{
|
||||
return isDir ? path : "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *fullpath = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:path.c_str()]
|
||||
NSString* fullpath = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:path.c_str()]
|
||||
ofType:nil];
|
||||
if(fullpath != nil) {
|
||||
if (fullpath != nil)
|
||||
{
|
||||
return [fullpath UTF8String];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(std::string_view directory, std::string_view filename) const
|
||||
std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(std::string_view directory,
|
||||
std::string_view filename) const
|
||||
{
|
||||
if (directory[0] != '/')
|
||||
{
|
||||
NSString* fullpath = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:filename.c_str()]
|
||||
ofType:nil
|
||||
inDirectory:[NSString stringWithUTF8String:directory.c_str()]];
|
||||
if (fullpath != nil) {
|
||||
ofType:nil
|
||||
inDirectory:[NSString stringWithUTF8String:directory.c_str()]];
|
||||
if (fullpath != nil)
|
||||
{
|
||||
return [fullpath UTF8String];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fullPath = directory+filename;
|
||||
std::string fullPath = directory + filename;
|
||||
// Search path is an absolute path.
|
||||
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:fullPath.c_str()]]) {
|
||||
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:fullPath.c_str()]])
|
||||
{
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
|
@ -225,19 +230,22 @@ std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(std::string_vi
|
|||
bool FileUtilsApple::createDirectory(std::string_view path) const
|
||||
{
|
||||
CCASSERT(!path.empty(), "Invalid path");
|
||||
|
||||
|
||||
if (isDirectoryExist(path))
|
||||
return true;
|
||||
|
||||
|
||||
NSError* error;
|
||||
|
||||
bool result = [s_fileManager createDirectoryAtPath:[NSString stringWithUTF8String:path.c_str()] withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
|
||||
if(!result && error != nil)
|
||||
|
||||
bool result = [s_fileManager createDirectoryAtPath:[NSString stringWithUTF8String:path.c_str()]
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:&error];
|
||||
|
||||
if (!result && error != nil)
|
||||
{
|
||||
CCLOGERROR("Fail to create directory \"%s\": %s", path.c_str(), [error.localizedDescription UTF8String]);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -575,18 +575,18 @@ void GLViewImpl::pollEvents()
|
|||
|
||||
void GLViewImpl::enableRetina(bool enabled)
|
||||
{ // official v4 comment follow sources
|
||||
// #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
// _isRetinaEnabled = enabled;
|
||||
// if (_isRetinaEnabled)
|
||||
// {
|
||||
// _retinaFactor = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _retinaFactor = 2;
|
||||
// }
|
||||
// updateFrameSize();
|
||||
// #endif
|
||||
// #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
// _isRetinaEnabled = enabled;
|
||||
// if (_isRetinaEnabled)
|
||||
// {
|
||||
// _retinaFactor = 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _retinaFactor = 2;
|
||||
// }
|
||||
// updateFrameSize();
|
||||
// #endif
|
||||
}
|
||||
|
||||
void GLViewImpl::setIMEKeyboardState(bool /*bOpen*/) {}
|
||||
|
|
|
@ -37,7 +37,7 @@ Application* Application::sm_pSharedApplication = nullptr;
|
|||
|
||||
Application::Application()
|
||||
{
|
||||
CC_ASSERT(! sm_pSharedApplication);
|
||||
CC_ASSERT(!sm_pSharedApplication);
|
||||
sm_pSharedApplication = this;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ int Application::run()
|
|||
|
||||
void Application::setAnimationInterval(float interval)
|
||||
{
|
||||
[[CCDirectorCaller sharedDirectorCaller] setAnimationInterval: interval ];
|
||||
[[CCDirectorCaller sharedDirectorCaller] setAnimationInterval:interval];
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -71,39 +71,39 @@ Application* Application::getInstance()
|
|||
return sm_pSharedApplication;
|
||||
}
|
||||
|
||||
const char * Application::getCurrentLanguageCode()
|
||||
const char* Application::getCurrentLanguageCode()
|
||||
{
|
||||
static char code[3]={0};
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString *currentLanguage = [languages objectAtIndex:0];
|
||||
static char code[3] = {0};
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray* languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString* currentLanguage = [languages objectAtIndex:0];
|
||||
|
||||
// get the current language code.(such as English is "en", Chinese is "zh" and so on)
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString * languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString* languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
[languageCode getCString:code maxLength:3 encoding:NSASCIIStringEncoding];
|
||||
code[2]='\0';
|
||||
code[2] = '\0';
|
||||
return code;
|
||||
}
|
||||
|
||||
LanguageType Application::getCurrentLanguage()
|
||||
{
|
||||
// get the current language and country config
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString *currentLanguage = [languages objectAtIndex:0];
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray* languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString* currentLanguage = [languages objectAtIndex:0];
|
||||
|
||||
// get the current language code.(such as English is "en", Chinese is "zh" and so on)
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString * languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString* languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
|
||||
return utils::getLanguageTypeByISO2([languageCode UTF8String]);
|
||||
|
||||
}
|
||||
|
||||
Application::Platform Application::getTargetPlatform()
|
||||
{
|
||||
if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad) // idiom for iOS <= 3.2, otherwise: [UIDevice userInterfaceIdiom] is faster.
|
||||
if ([UIDevice.currentDevice userInterfaceIdiom] ==
|
||||
UIUserInterfaceIdiomPad) // idiom for iOS <= 3.2, otherwise: [UIDevice userInterfaceIdiom] is faster.
|
||||
{
|
||||
return Platform::OS_IPAD;
|
||||
}
|
||||
|
@ -113,21 +113,23 @@ Application::Platform Application::getTargetPlatform()
|
|||
}
|
||||
}
|
||||
|
||||
std::string Application::getVersion() {
|
||||
std::string Application::getVersion()
|
||||
{
|
||||
NSString* version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
|
||||
if (version) {
|
||||
if (version)
|
||||
{
|
||||
return [version UTF8String];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Application::openURL(const std::string &url)
|
||||
bool Application::openURL(const std::string& url)
|
||||
{
|
||||
NSString* msg = [NSString stringWithCString:url.c_str() encoding:NSUTF8StringEncoding];
|
||||
NSURL* nsUrl = [NSURL URLWithString:msg];
|
||||
|
||||
NSURL* nsUrl = [NSURL URLWithString:msg];
|
||||
|
||||
id application = [UIApplication sharedApplication];
|
||||
if ([application respondsToSelector:@selector(openURL:options:completionHandler:)] )
|
||||
if ([application respondsToSelector:@selector(openURL:options:completionHandler:)])
|
||||
{
|
||||
[application openURL:nsUrl options:@{} completionHandler:nil];
|
||||
}
|
||||
|
@ -137,8 +139,6 @@ bool Application::openURL(const std::string &url)
|
|||
}
|
||||
}
|
||||
|
||||
void Application::applicationScreenSizeChanged(int newWidth, int newHeight) {
|
||||
|
||||
}
|
||||
void Application::applicationScreenSizeChanged(int newWidth, int newHeight) {}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -36,29 +36,30 @@
|
|||
NS_CC_BEGIN
|
||||
|
||||
// ios no MessageBox, use log instead
|
||||
void ccMessageBox(const char * msg, const char * title)
|
||||
void ccMessageBox(const char* msg, const char* title)
|
||||
{
|
||||
// only enable it on iOS.
|
||||
// FIXME: Implement it for tvOS
|
||||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
NSString * tmpTitle = (title) ? [NSString stringWithUTF8String : title] : nil;
|
||||
NSString * tmpMsg = (msg) ? [NSString stringWithUTF8String : msg] : nil;
|
||||
NSString* tmpTitle = (title) ? [NSString stringWithUTF8String:title] : nil;
|
||||
NSString* tmpMsg = (msg) ? [NSString stringWithUTF8String:msg] : nil;
|
||||
|
||||
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:tmpTitle
|
||||
message:tmpMsg
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
message:tmpMsg
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {}];
|
||||
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction* action){
|
||||
}];
|
||||
|
||||
[alertController addAction:defaultAction];
|
||||
auto rootViewController = [UIApplication sharedApplication].windows[0].rootViewController;
|
||||
[rootViewController presentViewController:alertController animated:YES completion:nil];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void LuaLog(const char * format)
|
||||
void LuaLog(const char* format)
|
||||
{
|
||||
puts(format);
|
||||
}
|
||||
|
|
|
@ -34,29 +34,30 @@
|
|||
|
||||
// Accelerometer
|
||||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
#import<CoreMotion/CoreMotion.h>
|
||||
# import <CoreMotion/CoreMotion.h>
|
||||
#endif
|
||||
#import<CoreFoundation/CoreFoundation.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
// Vibrate
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
const float MAX_MEASURE_HEIGHT = 10000;
|
||||
|
||||
|
||||
static NSAttributedString* __attributedStringWithFontSize(NSMutableAttributedString* attributedString, CGFloat fontSize)
|
||||
{
|
||||
{
|
||||
[attributedString beginEditing];
|
||||
|
||||
[attributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
|
||||
[attributedString enumerateAttribute:NSFontAttributeName
|
||||
inRange:NSMakeRange(0, attributedString.length)
|
||||
options:0
|
||||
usingBlock:^(id value, NSRange range, BOOL* stop) {
|
||||
UIFont* font = value;
|
||||
font = [font fontWithSize:fontSize];
|
||||
|
||||
UIFont* font = value;
|
||||
font = [font fontWithSize:fontSize];
|
||||
|
||||
[attributedString removeAttribute:NSFontAttributeName range:range];
|
||||
[attributedString addAttribute:NSFontAttributeName value:font range:range];
|
||||
}];
|
||||
[attributedString removeAttribute:NSFontAttributeName range:range];
|
||||
[attributedString addAttribute:NSFontAttributeName value:font range:range];
|
||||
}];
|
||||
|
||||
[attributedString endEditing];
|
||||
}
|
||||
|
@ -69,97 +70,116 @@ static CGFloat _calculateTextDrawStartHeight(cocos2d::Device::TextAlign align, C
|
|||
float startH = 0;
|
||||
// vertical alignment
|
||||
unsigned int vAlignment = ((int)align >> 4) & 0x0F;
|
||||
switch (vAlignment) {
|
||||
//bottom
|
||||
case 2:startH = dimensions.height - realDimensions.height;break;
|
||||
//top
|
||||
case 1:startH = 0;break;
|
||||
//center
|
||||
case 3: startH = (dimensions.height - realDimensions.height) / 2;break;
|
||||
default:
|
||||
break;
|
||||
switch (vAlignment)
|
||||
{
|
||||
// bottom
|
||||
case 2:
|
||||
startH = dimensions.height - realDimensions.height;
|
||||
break;
|
||||
// top
|
||||
case 1:
|
||||
startH = 0;
|
||||
break;
|
||||
// center
|
||||
case 3:
|
||||
startH = (dimensions.height - realDimensions.height) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return startH;
|
||||
}
|
||||
|
||||
static CGSize _calculateShrinkedSizeForString(NSAttributedString **str,
|
||||
static CGSize _calculateShrinkedSizeForString(NSAttributedString** str,
|
||||
id font,
|
||||
CGSize constrainSize,
|
||||
bool enableWrap,
|
||||
int& newFontSize)
|
||||
{
|
||||
CGRect actualSize = CGRectMake(0, 0, constrainSize.width + 1, constrainSize.height + 1);
|
||||
int fontSize = [font pointSize];
|
||||
fontSize = fontSize + 1;
|
||||
int fontSize = [font pointSize];
|
||||
fontSize = fontSize + 1;
|
||||
|
||||
if (!enableWrap) {
|
||||
while (actualSize.size.width > constrainSize.width ||
|
||||
actualSize.size.height > constrainSize.height) {
|
||||
if (!enableWrap)
|
||||
{
|
||||
while (actualSize.size.width > constrainSize.width || actualSize.size.height > constrainSize.height)
|
||||
{
|
||||
fontSize = fontSize - 1;
|
||||
|
||||
if(fontSize < 0) {
|
||||
if (fontSize < 0)
|
||||
{
|
||||
actualSize = CGRectMake(0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
NSMutableAttributedString *mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
NSMutableAttributedString* mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)*str);
|
||||
CTFramesetterRef framesetter =
|
||||
CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) * str);
|
||||
CGSize targetSize = CGSizeMake(MAX_MEASURE_HEIGHT, MAX_MEASURE_HEIGHT);
|
||||
CGSize fitSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, [(*str) length]), NULL, targetSize, NULL);
|
||||
CGSize fitSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, [(*str) length]),
|
||||
NULL, targetSize, NULL);
|
||||
CFRelease(framesetter);
|
||||
if (fitSize.width == 0 || fitSize.height == 0) {
|
||||
if (fitSize.width == 0 || fitSize.height == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
actualSize.size = fitSize;
|
||||
|
||||
if (constrainSize.width <= 0) {
|
||||
|
||||
if (constrainSize.width <= 0)
|
||||
{
|
||||
constrainSize.width = fitSize.width;
|
||||
}
|
||||
if (constrainSize.height <= 0) {
|
||||
if (constrainSize.height <= 0)
|
||||
{
|
||||
constrainSize.height = fitSize.height;
|
||||
}
|
||||
if (fontSize <= 0) {
|
||||
if (fontSize <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
while (actualSize.size.height > constrainSize.height ||
|
||||
actualSize.size.width > constrainSize.width) {
|
||||
else
|
||||
{
|
||||
while (actualSize.size.height > constrainSize.height || actualSize.size.width > constrainSize.width)
|
||||
{
|
||||
fontSize = fontSize - 1;
|
||||
if(fontSize < 0) {
|
||||
if (fontSize < 0)
|
||||
{
|
||||
actualSize = CGRectMake(0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
NSMutableAttributedString *mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(constrainSize.width, MAX_MEASURE_HEIGHT)
|
||||
options:(NSStringDrawingUsesLineFragmentOrigin)
|
||||
context:nil].size;
|
||||
|
||||
if (fitSize.width == 0 || fitSize.height == 0) {
|
||||
NSMutableAttributedString* mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(constrainSize.width, MAX_MEASURE_HEIGHT)
|
||||
options:(NSStringDrawingUsesLineFragmentOrigin)context:nil]
|
||||
.size;
|
||||
|
||||
if (fitSize.width == 0 || fitSize.height == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
actualSize.size = fitSize;
|
||||
|
||||
if (constrainSize.height <= 0) {
|
||||
|
||||
if (constrainSize.height <= 0)
|
||||
{
|
||||
constrainSize.height = fitSize.height;
|
||||
}
|
||||
if (constrainSize.width <= 0) {
|
||||
if (constrainSize.width <= 0)
|
||||
{
|
||||
constrainSize.width = fitSize.width;
|
||||
}
|
||||
if (fontSize <= 0) {
|
||||
if (fontSize <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newFontSize = fontSize;
|
||||
|
@ -170,16 +190,15 @@ static CGSize _calculateShrinkedSizeForString(NSAttributedString **str,
|
|||
#define SENSOR_DELAY_GAME 0.02
|
||||
|
||||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
@interface CCAccelerometerDispatcher : NSObject
|
||||
{
|
||||
cocos2d::Acceleration *_acceleration;
|
||||
CMMotionManager *_motionManager;
|
||||
@interface CCAccelerometerDispatcher : NSObject {
|
||||
cocos2d::Acceleration* _acceleration;
|
||||
CMMotionManager* _motionManager;
|
||||
}
|
||||
|
||||
+ (id) sharedAccelerometerDispatcher;
|
||||
- (id) init;
|
||||
- (void) setAccelerometerEnabled: (bool) isEnabled;
|
||||
- (void) setAccelerometerInterval:(float) interval;
|
||||
+ (id)sharedAccelerometerDispatcher;
|
||||
- (id)init;
|
||||
- (void)setAccelerometerEnabled:(bool)isEnabled;
|
||||
- (void)setAccelerometerInterval:(float)interval;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -187,26 +206,28 @@ static CGSize _calculateShrinkedSizeForString(NSAttributedString **str,
|
|||
|
||||
static CCAccelerometerDispatcher* s_pAccelerometerDispatcher;
|
||||
|
||||
+ (id) sharedAccelerometerDispatcher
|
||||
+ (id)sharedAccelerometerDispatcher
|
||||
{
|
||||
if (s_pAccelerometerDispatcher == nil) {
|
||||
if (s_pAccelerometerDispatcher == nil)
|
||||
{
|
||||
s_pAccelerometerDispatcher = [[self alloc] init];
|
||||
}
|
||||
|
||||
return s_pAccelerometerDispatcher;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
- (id)init
|
||||
{
|
||||
if( (self = [super init]) ) {
|
||||
_acceleration = new cocos2d::Acceleration();
|
||||
_motionManager = [[CMMotionManager alloc] init];
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_acceleration = new cocos2d::Acceleration();
|
||||
_motionManager = [[CMMotionManager alloc] init];
|
||||
_motionManager.accelerometerUpdateInterval = SENSOR_DELAY_GAME;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
- (void)dealloc
|
||||
{
|
||||
s_pAccelerometerDispatcher = nullptr;
|
||||
delete _acceleration;
|
||||
|
@ -214,13 +235,14 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setAccelerometerEnabled: (bool) isEnabled
|
||||
- (void)setAccelerometerEnabled:(bool)isEnabled
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
[_motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
|
||||
[self accelerometer:accelerometerData];
|
||||
}];
|
||||
[_motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
|
||||
withHandler:^(CMAccelerometerData* accelerometerData, NSError* error) {
|
||||
[self accelerometer:accelerometerData];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,16 +250,16 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher;
|
|||
}
|
||||
}
|
||||
|
||||
-(void) setAccelerometerInterval:(float)interval
|
||||
- (void)setAccelerometerInterval:(float)interval
|
||||
{
|
||||
_motionManager.accelerometerUpdateInterval = interval;
|
||||
}
|
||||
|
||||
- (void)accelerometer:(CMAccelerometerData *)accelerometerData
|
||||
- (void)accelerometer:(CMAccelerometerData*)accelerometerData
|
||||
{
|
||||
_acceleration->x = accelerometerData.acceleration.x;
|
||||
_acceleration->y = accelerometerData.acceleration.y;
|
||||
_acceleration->z = accelerometerData.acceleration.z;
|
||||
_acceleration->x = accelerometerData.acceleration.x;
|
||||
_acceleration->y = accelerometerData.acceleration.y;
|
||||
_acceleration->z = accelerometerData.acceleration.z;
|
||||
_acceleration->timestamp = accelerometerData.timestamp;
|
||||
|
||||
double tmp = _acceleration->x;
|
||||
|
@ -251,28 +273,28 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher;
|
|||
// Fallback on earlier versions
|
||||
orientation = [[UIApplication sharedApplication] statusBarOrientation];
|
||||
}
|
||||
|
||||
|
||||
switch (orientation)
|
||||
{
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
_acceleration->x = -_acceleration->y;
|
||||
_acceleration->y = tmp;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
_acceleration->x = _acceleration->y;
|
||||
_acceleration->y = -tmp;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
_acceleration->x = -_acceleration->y;
|
||||
_acceleration->y = -tmp;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortrait:
|
||||
break;
|
||||
default:
|
||||
NSAssert(false, @"unknown orientation");
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
_acceleration->x = -_acceleration->y;
|
||||
_acceleration->y = tmp;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
_acceleration->x = _acceleration->y;
|
||||
_acceleration->y = -tmp;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
_acceleration->x = -_acceleration->y;
|
||||
_acceleration->y = -tmp;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortrait:
|
||||
break;
|
||||
default:
|
||||
NSAssert(false, @"unknown orientation");
|
||||
}
|
||||
|
||||
cocos2d::EventAcceleration event(*_acceleration);
|
||||
|
@ -280,8 +302,7 @@ static CCAccelerometerDispatcher* s_pAccelerometerDispatcher;
|
|||
dispatcher->dispatchEvent(&event);
|
||||
}
|
||||
@end
|
||||
#endif // !defined(CC_TARGET_OS_TVOS)
|
||||
|
||||
#endif // !defined(CC_TARGET_OS_TVOS)
|
||||
|
||||
//
|
||||
|
||||
|
@ -295,23 +316,28 @@ int Device::getDPI()
|
|||
{
|
||||
float scale = 1.0f;
|
||||
|
||||
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
|
||||
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
|
||||
{
|
||||
scale = [[UIScreen mainScreen] scale];
|
||||
}
|
||||
|
||||
UIUserInterfaceIdiom userInterfaceIdiom = [UIDevice.currentDevice userInterfaceIdiom];
|
||||
if (userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
if (userInterfaceIdiom == UIUserInterfaceIdiomPad)
|
||||
{
|
||||
dpi = 132 * scale;
|
||||
} else if (userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
|
||||
}
|
||||
else if (userInterfaceIdiom == UIUserInterfaceIdiomPhone)
|
||||
{
|
||||
dpi = 163 * scale;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dpi = 160 * scale;
|
||||
}
|
||||
}
|
||||
return dpi;
|
||||
}
|
||||
|
||||
|
||||
void Device::setAccelerometerEnabled(bool isEnabled)
|
||||
{
|
||||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
|
@ -330,67 +356,74 @@ typedef struct
|
|||
{
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
bool isPremultipliedAlpha;
|
||||
bool hasShadow;
|
||||
CGSize shadowOffset;
|
||||
float shadowBlur;
|
||||
float shadowOpacity;
|
||||
bool hasStroke;
|
||||
float strokeColorR;
|
||||
float strokeColorG;
|
||||
float strokeColorB;
|
||||
float strokeColorA;
|
||||
float strokeSize;
|
||||
float tintColorR;
|
||||
float tintColorG;
|
||||
float tintColorB;
|
||||
float tintColorA;
|
||||
bool isPremultipliedAlpha;
|
||||
bool hasShadow;
|
||||
CGSize shadowOffset;
|
||||
float shadowBlur;
|
||||
float shadowOpacity;
|
||||
bool hasStroke;
|
||||
float strokeColorR;
|
||||
float strokeColorG;
|
||||
float strokeColorB;
|
||||
float strokeColorA;
|
||||
float strokeSize;
|
||||
float tintColorR;
|
||||
float tintColorG;
|
||||
float tintColorB;
|
||||
float tintColorA;
|
||||
|
||||
unsigned char* data;
|
||||
unsigned char* data;
|
||||
|
||||
} tImageInfo;
|
||||
|
||||
static CGSize _calculateStringSize(NSAttributedString *str, id font, CGSize *constrainSize, bool enableWrap, int overflow)
|
||||
static CGSize _calculateStringSize(NSAttributedString* str,
|
||||
id font,
|
||||
CGSize* constrainSize,
|
||||
bool enableWrap,
|
||||
int overflow)
|
||||
{
|
||||
CGSize textRect = CGSizeZero;
|
||||
textRect.width = constrainSize->width > 0 ? constrainSize->width
|
||||
: MAX_MEASURE_HEIGHT;
|
||||
textRect.height = constrainSize->height > 0 ? constrainSize->height
|
||||
: MAX_MEASURE_HEIGHT;
|
||||
|
||||
if (overflow == 1) {
|
||||
if(!enableWrap) {
|
||||
textRect.width = MAX_MEASURE_HEIGHT;
|
||||
textRect.width = constrainSize->width > 0 ? constrainSize->width : MAX_MEASURE_HEIGHT;
|
||||
textRect.height = constrainSize->height > 0 ? constrainSize->height : MAX_MEASURE_HEIGHT;
|
||||
|
||||
if (overflow == 1)
|
||||
{
|
||||
if (!enableWrap)
|
||||
{
|
||||
textRect.width = MAX_MEASURE_HEIGHT;
|
||||
textRect.height = MAX_MEASURE_HEIGHT;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
textRect.height = MAX_MEASURE_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
CGSize dim;
|
||||
dim = [str boundingRectWithSize:CGSizeMake(textRect.width, textRect.height)
|
||||
options:(NSStringDrawingUsesLineFragmentOrigin)
|
||||
context:nil].size;
|
||||
options:(NSStringDrawingUsesLineFragmentOrigin)context:nil]
|
||||
.size;
|
||||
|
||||
dim.width = ceilf(dim.width);
|
||||
dim.width = ceilf(dim.width);
|
||||
dim.height = ceilf(dim.height);
|
||||
|
||||
return dim;
|
||||
}
|
||||
|
||||
static id _createSystemFont( const char * fontName, int size)
|
||||
static id _createSystemFont(const char* fontName, int size)
|
||||
{
|
||||
NSString * fntName = [NSString stringWithUTF8String:fontName];
|
||||
// On iOS custom fonts must be listed beforehand in the App info.plist (in order to be usable) and referenced only the by the font family name itself when
|
||||
// calling [UIFont fontWithName]. Therefore even if the developer adds 'SomeFont.ttf' or 'fonts/SomeFont.ttf' to the App .plist, the font must
|
||||
// be referenced as 'SomeFont' when calling [UIFont fontWithName]. Hence we strip out the folder path components and the extension here in order to get just
|
||||
// the font family name itself. This stripping step is required especially for references to user fonts stored in CCB files; CCB files appear to store
|
||||
// the '.ttf' extensions when referring to custom fonts.
|
||||
NSString* fntName = [NSString stringWithUTF8String:fontName];
|
||||
// On iOS custom fonts must be listed beforehand in the App info.plist (in order to be usable) and referenced only
|
||||
// the by the font family name itself when calling [UIFont fontWithName]. Therefore even if the developer adds
|
||||
// 'SomeFont.ttf' or 'fonts/SomeFont.ttf' to the App .plist, the font must be referenced as 'SomeFont' when calling
|
||||
// [UIFont fontWithName]. Hence we strip out the folder path components and the extension here in order to get just
|
||||
// the font family name itself. This stripping step is required especially for references to user fonts stored in
|
||||
// CCB files; CCB files appear to store the '.ttf' extensions when referring to custom fonts.
|
||||
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
|
||||
|
||||
|
||||
// create the font
|
||||
id font = [UIFont fontWithName:fntName size:size];
|
||||
|
||||
|
||||
if (!font)
|
||||
{
|
||||
font = [UIFont systemFontOfSize:size];
|
||||
|
@ -398,86 +431,89 @@ static id _createSystemFont( const char * fontName, int size)
|
|||
return font;
|
||||
}
|
||||
|
||||
static bool _initWithString(const char * text, cocos2d::Device::TextAlign align, const char * fontName, int size, tImageInfo* info, bool enableWrap, int overflow)
|
||||
static bool _initWithString(const char* text,
|
||||
cocos2d::Device::TextAlign align,
|
||||
const char* fontName,
|
||||
int size,
|
||||
tImageInfo* info,
|
||||
bool enableWrap,
|
||||
int overflow)
|
||||
{
|
||||
|
||||
bool bRet = false;
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(! text || ! info);
|
||||
CC_BREAK_IF(!text || !info);
|
||||
|
||||
id font = _createSystemFont(fontName, size);
|
||||
|
||||
CC_BREAK_IF(! font);
|
||||
|
||||
NSString * str = [NSString stringWithUTF8String:text];
|
||||
|
||||
CC_BREAK_IF(!font);
|
||||
|
||||
NSString* str = [NSString stringWithUTF8String:text];
|
||||
CC_BREAK_IF(!str);
|
||||
|
||||
CGSize dimensions;
|
||||
dimensions.width = info->width;
|
||||
dimensions.height = info->height;
|
||||
dimensions.width = info->width;
|
||||
dimensions.height = info->height;
|
||||
|
||||
NSTextAlignment nsAlign = FontUtils::_calculateTextAlignment(align);
|
||||
NSTextAlignment nsAlign = FontUtils::_calculateTextAlignment(align);
|
||||
NSMutableParagraphStyle* paragraphStyle = FontUtils::_calculateParagraphStyle(enableWrap, overflow);
|
||||
paragraphStyle.alignment = nsAlign;
|
||||
paragraphStyle.alignment = nsAlign;
|
||||
|
||||
// measure text size with specified font and determine the rectangle to draw text in
|
||||
|
||||
UIColor *foregroundColor = [UIColor colorWithRed:info->tintColorR
|
||||
green:info->tintColorG
|
||||
blue:info->tintColorB
|
||||
alpha:info->tintColorA];
|
||||
UIColor* foregroundColor = [UIColor colorWithRed:info->tintColorR
|
||||
green:info->tintColorG
|
||||
blue:info->tintColorB
|
||||
alpha:info->tintColorA];
|
||||
|
||||
// adjust text rect according to overflow
|
||||
NSMutableDictionary* tokenAttributesDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
foregroundColor,NSForegroundColorAttributeName,
|
||||
font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
||||
NSMutableDictionary* tokenAttributesDict = [NSMutableDictionary
|
||||
dictionaryWithObjectsAndKeys:foregroundColor, NSForegroundColorAttributeName, font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
||||
|
||||
NSAttributedString *stringWithAttributes =[[[NSAttributedString alloc] initWithString:str
|
||||
attributes:tokenAttributesDict] autorelease];
|
||||
NSAttributedString* stringWithAttributes =
|
||||
[[[NSAttributedString alloc] initWithString:str attributes:tokenAttributesDict] autorelease];
|
||||
|
||||
int shrinkFontSize = size;
|
||||
CGSize realDimensions;
|
||||
if (overflow == 2) {
|
||||
realDimensions = _calculateShrinkedSizeForString(&stringWithAttributes, font, dimensions, enableWrap, shrinkFontSize);
|
||||
} else {
|
||||
if (overflow == 2)
|
||||
{
|
||||
realDimensions =
|
||||
_calculateShrinkedSizeForString(&stringWithAttributes, font, dimensions, enableWrap, shrinkFontSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
realDimensions = _calculateStringSize(stringWithAttributes, font, &dimensions, enableWrap, overflow);
|
||||
}
|
||||
|
||||
|
||||
CC_BREAK_IF(realDimensions.width <= 0 || realDimensions.height <= 0);
|
||||
if (dimensions.width <= 0) {
|
||||
if (dimensions.width <= 0)
|
||||
{
|
||||
dimensions.width = realDimensions.width;
|
||||
}
|
||||
if (dimensions.height <= 0) {
|
||||
if (dimensions.height <= 0)
|
||||
{
|
||||
dimensions.height = realDimensions.height;
|
||||
}
|
||||
|
||||
// compute start point
|
||||
CGFloat yPadding = _calculateTextDrawStartHeight(align, realDimensions, dimensions);
|
||||
CGFloat xPadding = FontUtils::_calculateTextDrawStartWidth(align, realDimensions, dimensions);
|
||||
|
||||
|
||||
NSInteger POTWide = dimensions.width;
|
||||
NSInteger POTHigh = dimensions.height;
|
||||
|
||||
CGRect textRect = CGRectMake(xPadding, yPadding,
|
||||
realDimensions.width, realDimensions.height);
|
||||
|
||||
CGRect textRect = CGRectMake(xPadding, yPadding, realDimensions.width, realDimensions.height);
|
||||
|
||||
NSUInteger textureSize = POTWide * POTHigh * 4;
|
||||
unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * textureSize);
|
||||
unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * textureSize);
|
||||
memset(data, 0, textureSize);
|
||||
|
||||
// draw text
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGContextRef context = CGBitmapContextCreate(data,
|
||||
POTWide,
|
||||
POTHigh,
|
||||
8,
|
||||
POTWide * 4,
|
||||
colorSpace,
|
||||
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGContextRef context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide * 4, colorSpace,
|
||||
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
|
||||
if (!context)
|
||||
{
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
@ -486,16 +522,12 @@ static bool _initWithString(const char * text, cocos2d::Device::TextAlign align,
|
|||
}
|
||||
|
||||
// text color
|
||||
CGContextSetRGBFillColor(context,
|
||||
info->tintColorR,
|
||||
info->tintColorG,
|
||||
info->tintColorB,
|
||||
info->tintColorA);
|
||||
CGContextSetRGBFillColor(context, info->tintColorR, info->tintColorG, info->tintColorB, info->tintColorA);
|
||||
|
||||
// move Y rendering to the top of the image
|
||||
CGContextTranslateCTM(context, 0.0f, POTHigh);
|
||||
|
||||
//NOTE: NSString draws in UIKit referential i.e. renders upside-down compared to CGBitmapContext referential
|
||||
|
||||
// NOTE: NSString draws in UIKit referential i.e. renders upside-down compared to CGBitmapContext referential
|
||||
CGContextScaleCTM(context, 1.0f, -1.0f);
|
||||
// store the current context
|
||||
UIGraphicsPushContext(context);
|
||||
|
@ -506,34 +538,30 @@ static bool _initWithString(const char * text, cocos2d::Device::TextAlign align,
|
|||
|
||||
CGContextBeginTransparencyLayerWithRect(context, textRect, NULL);
|
||||
|
||||
|
||||
if ( info->hasStroke )
|
||||
if (info->hasStroke)
|
||||
{
|
||||
CGContextSetTextDrawingMode(context, kCGTextStroke);
|
||||
UIColor *strokeColor = [UIColor colorWithRed:info->strokeColorR
|
||||
green:info->strokeColorG
|
||||
blue:info->strokeColorB
|
||||
alpha:info->strokeColorA];
|
||||
UIColor* strokeColor = [UIColor colorWithRed:info->strokeColorR
|
||||
green:info->strokeColorG
|
||||
blue:info->strokeColorB
|
||||
alpha:info->strokeColorA];
|
||||
|
||||
|
||||
NSMutableDictionary* tokenAttributesDict2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
foregroundColor,NSForegroundColorAttributeName,
|
||||
font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
||||
[tokenAttributesDict2 setObject:[NSNumber numberWithFloat: info->strokeSize / shrinkFontSize * 100]
|
||||
NSMutableDictionary* tokenAttributesDict2 = [NSMutableDictionary
|
||||
dictionaryWithObjectsAndKeys:foregroundColor, NSForegroundColorAttributeName, font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
||||
[tokenAttributesDict2 setObject:[NSNumber numberWithFloat:info->strokeSize / shrinkFontSize * 100]
|
||||
forKey:NSStrokeWidthAttributeName];
|
||||
[tokenAttributesDict2 setObject:strokeColor forKey:NSStrokeColorAttributeName];
|
||||
|
||||
NSAttributedString *strokeString =[[[NSAttributedString alloc] initWithString:str
|
||||
attributes:tokenAttributesDict2] autorelease];
|
||||
|
||||
if(overflow == 2){
|
||||
[tokenAttributesDict2 setObject:strokeColor forKey:NSStrokeColorAttributeName];
|
||||
|
||||
NSAttributedString* strokeString =
|
||||
[[[NSAttributedString alloc] initWithString:str attributes:tokenAttributesDict2] autorelease];
|
||||
|
||||
if (overflow == 2)
|
||||
{
|
||||
_calculateShrinkedSizeForString(&strokeString, font, dimensions, enableWrap, shrinkFontSize);
|
||||
}
|
||||
|
||||
|
||||
[strokeString drawInRect:textRect];
|
||||
|
||||
}
|
||||
|
||||
CGContextSetTextDrawingMode(context, kCGTextFill);
|
||||
|
@ -548,51 +576,57 @@ static bool _initWithString(const char * text, cocos2d::Device::TextAlign align,
|
|||
|
||||
// release the context
|
||||
CGContextRelease(context);
|
||||
|
||||
|
||||
// output params
|
||||
info->data = data;
|
||||
info->isPremultipliedAlpha = true;
|
||||
info->width = static_cast<int>(POTWide);
|
||||
info->height = static_cast<int>(POTHigh);
|
||||
bRet = true;
|
||||
bRet = true;
|
||||
|
||||
} while (0);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
Data Device::getTextureDataForText(const char * text, const FontDefinition& textDefinition, TextAlign align, int &width, int &height, bool& hasPremultipliedAlpha)
|
||||
Data Device::getTextureDataForText(const char* text,
|
||||
const FontDefinition& textDefinition,
|
||||
TextAlign align,
|
||||
int& width,
|
||||
int& height,
|
||||
bool& hasPremultipliedAlpha)
|
||||
{
|
||||
Data ret;
|
||||
|
||||
do {
|
||||
tImageInfo info = {0};
|
||||
info.width = textDefinition._dimensions.width;
|
||||
info.height = textDefinition._dimensions.height;
|
||||
info.hasShadow = textDefinition._shadow._shadowEnabled;
|
||||
info.shadowOffset.width = textDefinition._shadow._shadowOffset.width;
|
||||
info.shadowOffset.height = textDefinition._shadow._shadowOffset.height;
|
||||
info.shadowBlur = textDefinition._shadow._shadowBlur;
|
||||
info.shadowOpacity = textDefinition._shadow._shadowOpacity;
|
||||
info.hasStroke = textDefinition._stroke._strokeEnabled;
|
||||
info.strokeColorR = textDefinition._stroke._strokeColor.r / 255.0f;
|
||||
info.strokeColorG = textDefinition._stroke._strokeColor.g / 255.0f;
|
||||
info.strokeColorB = textDefinition._stroke._strokeColor.b / 255.0f;
|
||||
info.strokeColorA = textDefinition._stroke._strokeAlpha / 255.0f;
|
||||
info.strokeSize = textDefinition._stroke._strokeSize;
|
||||
info.tintColorR = textDefinition._fontFillColor.r / 255.0f;
|
||||
info.tintColorG = textDefinition._fontFillColor.g / 255.0f;
|
||||
info.tintColorB = textDefinition._fontFillColor.b / 255.0f;
|
||||
info.tintColorA = textDefinition._fontAlpha / 255.0f;
|
||||
do
|
||||
{
|
||||
tImageInfo info = {0};
|
||||
info.width = textDefinition._dimensions.width;
|
||||
info.height = textDefinition._dimensions.height;
|
||||
info.hasShadow = textDefinition._shadow._shadowEnabled;
|
||||
info.shadowOffset.width = textDefinition._shadow._shadowOffset.width;
|
||||
info.shadowOffset.height = textDefinition._shadow._shadowOffset.height;
|
||||
info.shadowBlur = textDefinition._shadow._shadowBlur;
|
||||
info.shadowOpacity = textDefinition._shadow._shadowOpacity;
|
||||
info.hasStroke = textDefinition._stroke._strokeEnabled;
|
||||
info.strokeColorR = textDefinition._stroke._strokeColor.r / 255.0f;
|
||||
info.strokeColorG = textDefinition._stroke._strokeColor.g / 255.0f;
|
||||
info.strokeColorB = textDefinition._stroke._strokeColor.b / 255.0f;
|
||||
info.strokeColorA = textDefinition._stroke._strokeAlpha / 255.0f;
|
||||
info.strokeSize = textDefinition._stroke._strokeSize;
|
||||
info.tintColorR = textDefinition._fontFillColor.r / 255.0f;
|
||||
info.tintColorG = textDefinition._fontFillColor.g / 255.0f;
|
||||
info.tintColorB = textDefinition._fontFillColor.b / 255.0f;
|
||||
info.tintColorA = textDefinition._fontAlpha / 255.0f;
|
||||
|
||||
if (! _initWithString(text, align, textDefinition._fontName.c_str(), textDefinition._fontSize, &info, textDefinition._enableWrap, textDefinition._overflow))
|
||||
if (!_initWithString(text, align, textDefinition._fontName.c_str(), textDefinition._fontSize, &info,
|
||||
textDefinition._enableWrap, textDefinition._overflow))
|
||||
{
|
||||
break;
|
||||
}
|
||||
height = info.height;
|
||||
width = info.width;
|
||||
ret.fastSet(info.data,width * height * 4);
|
||||
width = info.width;
|
||||
ret.fastSet(info.data, width * height * 4);
|
||||
hasPremultipliedAlpha = true;
|
||||
} while (0);
|
||||
|
||||
|
@ -605,22 +639,23 @@ void Device::setKeepScreenOn(bool value)
|
|||
}
|
||||
|
||||
/*!
|
||||
@brief Only works on iOS devices that support vibration (such as iPhone). Should only be used for important alerts. Use risks rejection in iTunes Store.
|
||||
@brief Only works on iOS devices that support vibration (such as iPhone). Should only be used for important alerts. Use
|
||||
risks rejection in iTunes Store.
|
||||
@param duration ignored for iOS
|
||||
*/
|
||||
void Device::vibrate(float duration)
|
||||
{
|
||||
// See http://stackoverflow.com/questions/4724980/making-the-iphone-vibrate
|
||||
// should vibrate no matter it is silient or not
|
||||
if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
|
||||
if ([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
|
||||
{
|
||||
AudioServicesPlaySystemSound (1352); //works ALWAYS as of this post
|
||||
AudioServicesPlaySystemSound(1352); // works ALWAYS as of this post
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not an iPhone, so doesn't have vibrate
|
||||
// play the less annoying tick noise or one of your own
|
||||
AudioServicesPlayAlertSound (kSystemSoundID_Vibrate);
|
||||
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,50 +35,55 @@
|
|||
|
||||
static id s_sharedDirectorCaller;
|
||||
|
||||
@interface NSObject(CADisplayLink)
|
||||
+(id) displayLinkWithTarget: (id)arg1 selector:(SEL)arg2;
|
||||
-(void) addToRunLoop: (id)arg1 forMode: (id)arg2;
|
||||
-(void) setFrameInterval: (NSInteger)interval;
|
||||
-(void) invalidate;
|
||||
@interface NSObject (CADisplayLink)
|
||||
+ (id)displayLinkWithTarget:(id)arg1 selector:(SEL)arg2;
|
||||
- (void)addToRunLoop:(id)arg1 forMode:(id)arg2;
|
||||
- (void)setFrameInterval:(NSInteger)interval;
|
||||
- (void)invalidate;
|
||||
@end
|
||||
|
||||
@implementation CCDirectorCaller
|
||||
|
||||
@synthesize interval;
|
||||
|
||||
+(id) sharedDirectorCaller
|
||||
+ (id)sharedDirectorCaller
|
||||
{
|
||||
if (s_sharedDirectorCaller == nil)
|
||||
{
|
||||
s_sharedDirectorCaller = [[CCDirectorCaller alloc] init];
|
||||
}
|
||||
|
||||
|
||||
return s_sharedDirectorCaller;
|
||||
}
|
||||
|
||||
+(void) destroy
|
||||
+ (void)destroy
|
||||
{
|
||||
[s_sharedDirectorCaller stopMainLoop];
|
||||
[s_sharedDirectorCaller release];
|
||||
s_sharedDirectorCaller = nil;
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
isAppActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive;
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserver:self selector:@selector(appDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
[nc addObserver:self selector:@selector(appDidBecomeInactive) name:UIApplicationWillResignActiveNotification object:nil];
|
||||
|
||||
isAppActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive;
|
||||
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserver:self
|
||||
selector:@selector(appDidBecomeActive)
|
||||
name:UIApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
[nc addObserver:self
|
||||
selector:@selector(appDidBecomeInactive)
|
||||
name:UIApplicationWillResignActiveNotification
|
||||
object:nil];
|
||||
|
||||
self.interval = 1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[displayLink release];
|
||||
|
@ -100,52 +105,53 @@ static id s_sharedDirectorCaller;
|
|||
isAppActive = NO;
|
||||
}
|
||||
|
||||
-(void) startMainLoop
|
||||
- (void)startMainLoop
|
||||
{
|
||||
// Director::setAnimationInterval() is called, we should invalidate it first
|
||||
[self stopMainLoop];
|
||||
|
||||
|
||||
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];
|
||||
[displayLink setFrameInterval: self.interval];
|
||||
[displayLink setFrameInterval:self.interval];
|
||||
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
-(void) stopMainLoop
|
||||
- (void)stopMainLoop
|
||||
{
|
||||
[displayLink invalidate];
|
||||
displayLink = nil;
|
||||
}
|
||||
|
||||
-(void) setAnimationInterval:(double)intervalNew
|
||||
- (void)setAnimationInterval:(double)intervalNew
|
||||
{
|
||||
// Director::setAnimationInterval() is called, we should invalidate it first
|
||||
[self stopMainLoop];
|
||||
|
||||
|
||||
self.interval = 60.0 * intervalNew;
|
||||
|
||||
|
||||
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];
|
||||
[displayLink setFrameInterval: self.interval];
|
||||
[displayLink setFrameInterval:self.interval];
|
||||
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
-(void) doCaller: (id) sender
|
||||
|
||||
- (void)doCaller:(id)sender
|
||||
{
|
||||
if (isAppActive) {
|
||||
if (isAppActive)
|
||||
{
|
||||
cocos2d::Director* director = cocos2d::Director::getInstance();
|
||||
#if defined(CC_USE_GLES)
|
||||
EAGLContext* cocos2dxContext = [(CCEAGLView*)director->getOpenGLView()->getEAGLView() context];
|
||||
if (cocos2dxContext != [EAGLContext currentContext])
|
||||
glFlush();
|
||||
|
||||
[EAGLContext setCurrentContext: cocos2dxContext];
|
||||
|
||||
[EAGLContext setCurrentContext:cocos2dxContext];
|
||||
#endif
|
||||
CFTimeInterval dt = ((CADisplayLink*)displayLink).timestamp - lastDisplayTime;
|
||||
lastDisplayTime = ((CADisplayLink*)displayLink).timestamp;
|
||||
lastDisplayTime = ((CADisplayLink*)displayLink).timestamp;
|
||||
director->mainLoop(dt);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)initLastDisplayTime
|
||||
- (void)initLastDisplayTime
|
||||
{
|
||||
struct mach_timebase_info timeBaseInfo;
|
||||
mach_timebase_info(&timeBaseInfo);
|
||||
|
|
|
@ -70,21 +70,21 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
#import "platform/ios/CCInputView-ios.h"
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
#import <Metal/Metal.h>
|
||||
#import "renderer/backend/metal/DeviceMTL.h"
|
||||
#import "renderer/backend/metal/UtilsMTL.h"
|
||||
# import <Metal/Metal.h>
|
||||
# import "renderer/backend/metal/DeviceMTL.h"
|
||||
# import "renderer/backend/metal/UtilsMTL.h"
|
||||
#else
|
||||
#import "platform/ios/CCGLViewImpl-ios.h"
|
||||
#import "platform/ios/CCES2Renderer-ios.h"
|
||||
#import "platform/ios/OpenGL_Internal-ios.h"
|
||||
# import "platform/ios/CCGLViewImpl-ios.h"
|
||||
# import "platform/ios/CCES2Renderer-ios.h"
|
||||
# import "platform/ios/OpenGL_Internal-ios.h"
|
||||
#endif
|
||||
|
||||
//CLASS IMPLEMENTATIONS:
|
||||
// CLASS IMPLEMENTATIONS:
|
||||
|
||||
#define IOS_MAX_TOUCHES_COUNT 10
|
||||
#define IOS_MAX_TOUCHES_COUNT 10
|
||||
|
||||
@interface CCEAGLView ()
|
||||
@property (nonatomic) CCInputView* textInputView;
|
||||
@property(nonatomic) CCInputView* textInputView;
|
||||
@property(nonatomic, readwrite, assign) BOOL isKeyboardShown;
|
||||
@property(nonatomic, copy) NSNotification* keyboardShowNotification;
|
||||
@property(nonatomic, assign) CGRect originalRect;
|
||||
|
@ -92,17 +92,17 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
|
||||
@implementation CCEAGLView
|
||||
|
||||
@synthesize surfaceSize=size_;
|
||||
@synthesize pixelFormat=pixelformat_, depthFormat=depthFormat_;
|
||||
@synthesize surfaceSize = size_;
|
||||
@synthesize pixelFormat = pixelformat_, depthFormat = depthFormat_;
|
||||
#if !defined(CC_USE_METAL)
|
||||
@synthesize context=context_;
|
||||
@synthesize context = context_;
|
||||
#endif
|
||||
@synthesize multiSampling=multiSampling_;
|
||||
@synthesize multiSampling = multiSampling_;
|
||||
@synthesize keyboardShowNotification = keyboardShowNotification_;
|
||||
@synthesize isKeyboardShown;
|
||||
@synthesize originalRect = originalRect_;
|
||||
|
||||
+ (Class) layerClass
|
||||
+ (Class)layerClass
|
||||
{
|
||||
#if defined(CC_USE_METAL)
|
||||
return [CAMetalLayer class];
|
||||
|
@ -111,153 +111,191 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
#endif
|
||||
}
|
||||
|
||||
+ (id) viewWithFrame:(CGRect)frame
|
||||
+ (id)viewWithFrame:(CGRect)frame
|
||||
{
|
||||
return [[[self alloc] initWithFrame:frame] autorelease];
|
||||
}
|
||||
|
||||
+ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format
|
||||
+ (id)viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format
|
||||
{
|
||||
return [[[self alloc]initWithFrame:frame pixelFormat:format] autorelease];
|
||||
return [[[self alloc] initWithFrame:frame pixelFormat:format] autorelease];
|
||||
}
|
||||
|
||||
+ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth
|
||||
+ (id)viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth
|
||||
{
|
||||
return [[[self alloc] initWithFrame:frame pixelFormat:format depthFormat:depth preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0] autorelease];
|
||||
return [[[self alloc] initWithFrame:frame
|
||||
pixelFormat:format
|
||||
depthFormat:depth
|
||||
preserveBackbuffer:NO
|
||||
sharegroup:nil
|
||||
multiSampling:NO
|
||||
numberOfSamples:0] autorelease];
|
||||
}
|
||||
|
||||
+ (id) viewWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth preserveBackbuffer:(BOOL)retained sharegroup:(EAGLSharegroup*)sharegroup multiSampling:(BOOL)multisampling numberOfSamples:(unsigned int)samples
|
||||
+ (id)viewWithFrame:(CGRect)frame
|
||||
pixelFormat:(NSString*)format
|
||||
depthFormat:(GLuint)depth
|
||||
preserveBackbuffer:(BOOL)retained
|
||||
sharegroup:(EAGLSharegroup*)sharegroup
|
||||
multiSampling:(BOOL)multisampling
|
||||
numberOfSamples:(unsigned int)samples
|
||||
{
|
||||
return [[[self alloc]initWithFrame:frame pixelFormat:format depthFormat:depth preserveBackbuffer:retained sharegroup:sharegroup multiSampling:multisampling numberOfSamples:samples] autorelease];
|
||||
return [[[self alloc] initWithFrame:frame
|
||||
pixelFormat:format
|
||||
depthFormat:depth
|
||||
preserveBackbuffer:retained
|
||||
sharegroup:sharegroup
|
||||
multiSampling:multisampling
|
||||
numberOfSamples:samples] autorelease];
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(CGRect)frame
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
return [self initWithFrame:frame pixelFormat:kEAGLColorFormatRGB565 depthFormat:0 preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0];
|
||||
return [self initWithFrame:frame
|
||||
pixelFormat:kEAGLColorFormatRGB565
|
||||
depthFormat:0
|
||||
preserveBackbuffer:NO
|
||||
sharegroup:nil
|
||||
multiSampling:NO
|
||||
numberOfSamples:0];
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(CGRect)frame pixelFormat:(NSString*)format
|
||||
- (id)initWithFrame:(CGRect)frame pixelFormat:(NSString*)format
|
||||
{
|
||||
return [self initWithFrame:frame pixelFormat:format depthFormat:0 preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0];
|
||||
return [self initWithFrame:frame
|
||||
pixelFormat:format
|
||||
depthFormat:0
|
||||
preserveBackbuffer:NO
|
||||
sharegroup:nil
|
||||
multiSampling:NO
|
||||
numberOfSamples:0];
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(CGRect)frame pixelFormat:(NSString*)format depthFormat:(GLuint)depth preserveBackbuffer:(BOOL)retained sharegroup:(EAGLSharegroup*)sharegroup multiSampling:(BOOL)sampling numberOfSamples:(unsigned int)nSamples
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
pixelFormat:(NSString*)format
|
||||
depthFormat:(GLuint)depth
|
||||
preserveBackbuffer:(BOOL)retained
|
||||
sharegroup:(EAGLSharegroup*)sharegroup
|
||||
multiSampling:(BOOL)sampling
|
||||
numberOfSamples:(unsigned int)nSamples
|
||||
{
|
||||
if((self = [super initWithFrame:frame]))
|
||||
if ((self = [super initWithFrame:frame]))
|
||||
{
|
||||
self.textInputView = [[CCInputView alloc] initWithFrame:frame];
|
||||
|
||||
originalRect_ = self.frame;
|
||||
originalRect_ = self.frame;
|
||||
self.keyboardShowNotification = nil;
|
||||
if ([self respondsToSelector:@selector(setContentScaleFactor:)])
|
||||
{
|
||||
self.contentScaleFactor = [[UIScreen mainScreen] scale];
|
||||
}
|
||||
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
if (!device)
|
||||
{
|
||||
CCLOG("Doesn't support metal.");
|
||||
return nil;
|
||||
CCLOG("Doesn't support metal.");
|
||||
return nil;
|
||||
}
|
||||
CAMetalLayer* metalLayer = (CAMetalLayer*)[self layer];
|
||||
metalLayer.device = device;
|
||||
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
CAMetalLayer* metalLayer = (CAMetalLayer*)[self layer];
|
||||
metalLayer.device = device;
|
||||
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
metalLayer.framebufferOnly = YES;
|
||||
cocos2d::backend::DeviceMTL::setCAMetalLayer(metalLayer);
|
||||
#else
|
||||
pixelformat_ = format;
|
||||
depthFormat_ = depth;
|
||||
multiSampling_ = sampling;
|
||||
requestedSamples_ = nSamples;
|
||||
pixelformat_ = format;
|
||||
depthFormat_ = depth;
|
||||
multiSampling_ = sampling;
|
||||
requestedSamples_ = nSamples;
|
||||
preserveBackbuffer_ = retained;
|
||||
if( ! [self setupSurfaceWithSharegroup:sharegroup] ) {
|
||||
if (![self setupSurfaceWithSharegroup:sharegroup])
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id) initWithCoder:(NSCoder *)aDecoder
|
||||
- (id)initWithCoder:(NSCoder*)aDecoder
|
||||
{
|
||||
if ( (self = [super initWithCoder:aDecoder]) )
|
||||
if ((self = [super initWithCoder:aDecoder]))
|
||||
{
|
||||
self.textInputView = [[CCInputView alloc] initWithCoder:aDecoder];
|
||||
#if defined(CC_USE_METAL)
|
||||
size_ = [self bounds].size;
|
||||
#else
|
||||
CAEAGLLayer* eaglLayer = (CAEAGLLayer*)[self layer];
|
||||
|
||||
pixelformat_ = kEAGLColorFormatRGB565;
|
||||
depthFormat_ = 0; // GL_DEPTH_COMPONENT24_OES;
|
||||
multiSampling_= NO;
|
||||
|
||||
pixelformat_ = kEAGLColorFormatRGB565;
|
||||
depthFormat_ = 0; // GL_DEPTH_COMPONENT24_OES;
|
||||
multiSampling_ = NO;
|
||||
requestedSamples_ = 0;
|
||||
size_ = [eaglLayer bounds].size;
|
||||
|
||||
if( ! [self setupSurfaceWithSharegroup:nil] ) {
|
||||
size_ = [eaglLayer bounds].size;
|
||||
|
||||
if (![self setupSurfaceWithSharegroup:nil])
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(int) getWidth
|
||||
- (int)getWidth
|
||||
{
|
||||
CGSize bound = [self bounds].size;
|
||||
return (int)bound.width * self.contentScaleFactor;
|
||||
}
|
||||
|
||||
-(int) getHeight
|
||||
- (int)getHeight
|
||||
{
|
||||
CGSize bound = [self bounds].size;
|
||||
return (int)bound.height * self.contentScaleFactor;
|
||||
}
|
||||
|
||||
#if !defined(CC_USE_METAL)
|
||||
-(BOOL) setupSurfaceWithSharegroup:(EAGLSharegroup*)sharegroup
|
||||
- (BOOL)setupSurfaceWithSharegroup:(EAGLSharegroup*)sharegroup
|
||||
{
|
||||
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
|
||||
|
||||
CAEAGLLayer* eaglLayer = (CAEAGLLayer*)self.layer;
|
||||
|
||||
eaglLayer.opaque = YES;
|
||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:preserveBackbuffer_], kEAGLDrawablePropertyRetainedBacking,
|
||||
pixelformat_, kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
|
||||
eaglLayer.drawableProperties =
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:preserveBackbuffer_],
|
||||
kEAGLDrawablePropertyRetainedBacking, pixelformat_,
|
||||
kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
renderer_ = [[CCES2Renderer alloc] initWithDepthFormat:depthFormat_
|
||||
withPixelFormat:[self convertPixelFormat:pixelformat_]
|
||||
withSharegroup:sharegroup
|
||||
withMultiSampling:multiSampling_
|
||||
withNumberOfSamples:requestedSamples_];
|
||||
|
||||
withPixelFormat:[self convertPixelFormat:pixelformat_]
|
||||
withSharegroup:sharegroup
|
||||
withMultiSampling:multiSampling_
|
||||
withNumberOfSamples:requestedSamples_];
|
||||
|
||||
NSAssert(renderer_, @"OpenGL ES 2.O is required.");
|
||||
if (!renderer_)
|
||||
return NO;
|
||||
|
||||
|
||||
context_ = [renderer_ context];
|
||||
|
||||
#if GL_EXT_discard_framebuffer == 1
|
||||
discardFramebufferSupported_ = YES;
|
||||
#else
|
||||
discardFramebufferSupported_ = NO;
|
||||
#endif
|
||||
|
||||
|
||||
# if GL_EXT_discard_framebuffer == 1
|
||||
discardFramebufferSupported_ = YES;
|
||||
# else
|
||||
discardFramebufferSupported_ = NO;
|
||||
# endif
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void) dealloc
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self]; // remove keyboard notification
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self]; // remove keyboard notification
|
||||
#if !defined(CC_USE_METAL)
|
||||
[renderer_ release];
|
||||
#endif
|
||||
|
@ -265,29 +303,29 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) layoutSubviews
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
if (!cocos2d::Director::getInstance()->isValid())
|
||||
return;
|
||||
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
size_ = [self bounds].size;
|
||||
size_.width *= self.contentScaleFactor;
|
||||
size_.height *= self.contentScaleFactor;
|
||||
cocos2d::backend::UtilsMTL::resizeDefaultAttachmentTexture(size_.width, size_.height);
|
||||
cocos2d::backend::UtilsMTL::resizeDefaultAttachmentTexture(size_.width, size_.height);
|
||||
#else
|
||||
[renderer_ resizeFromLayer:(CAEAGLLayer*)self.layer];
|
||||
size_ = [renderer_ backingSize];
|
||||
|
||||
// Issue #914 #924
|
||||
// Director *director = [Director sharedDirector];
|
||||
// [director reshapeProjection:size_];
|
||||
// Director *director = [Director sharedDirector];
|
||||
// [director reshapeProjection:size_];
|
||||
cocos2d::Size size;
|
||||
size.width = size_.width;
|
||||
size.width = size_.width;
|
||||
size.height = size_.height;
|
||||
//cocos2d::Director::getInstance()->reshapeProjection(size);
|
||||
// cocos2d::Director::getInstance()->reshapeProjection(size);
|
||||
#endif
|
||||
|
||||
|
||||
// Avoid flicker. Issue #350
|
||||
if ([NSThread isMainThread])
|
||||
{
|
||||
|
@ -296,29 +334,28 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
}
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
- (void) swapBuffers
|
||||
{
|
||||
}
|
||||
- (void)swapBuffers
|
||||
{}
|
||||
#else
|
||||
- (void) swapBuffers
|
||||
- (void)swapBuffers
|
||||
{
|
||||
// IMPORTANT:
|
||||
// - preconditions
|
||||
// -> context_ MUST be the OpenGL context
|
||||
// -> renderbuffer_ must be the RENDER BUFFER
|
||||
// - preconditions
|
||||
// -> context_ MUST be the OpenGL context
|
||||
// -> renderbuffer_ must be the RENDER BUFFER
|
||||
|
||||
# ifdef __IPHONE_4_0
|
||||
|
||||
#ifdef __IPHONE_4_0
|
||||
|
||||
if (multiSampling_)
|
||||
{
|
||||
/* Resolve from msaaFramebuffer to resolveFramebuffer */
|
||||
//glDisable(GL_SCISSOR_TEST);
|
||||
// glDisable(GL_SCISSOR_TEST);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, [renderer_ msaaFrameBuffer]);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, [renderer_ defaultFrameBuffer]);
|
||||
glResolveMultisampleFramebufferAPPLE();
|
||||
}
|
||||
|
||||
if(discardFramebufferSupported_)
|
||||
|
||||
if (discardFramebufferSupported_)
|
||||
{
|
||||
if (multiSampling_)
|
||||
{
|
||||
|
@ -332,97 +369,98 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
|
||||
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 1, attachments);
|
||||
}
|
||||
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, [renderer_ colorRenderBuffer]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// not MSAA
|
||||
else if (depthFormat_ ) {
|
||||
GLenum attachments[] = { GL_DEPTH_ATTACHMENT};
|
||||
else if (depthFormat_)
|
||||
{
|
||||
GLenum attachments[] = {GL_DEPTH_ATTACHMENT};
|
||||
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __IPHONE_4_0
|
||||
|
||||
if(![context_ presentRenderbuffer:GL_RENDERBUFFER])
|
||||
{
|
||||
// CCLOG(@"cocos2d: Failed to swap renderbuffer in %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
#if COCOS2D_DEBUG
|
||||
# endif // __IPHONE_4_0
|
||||
|
||||
if (![context_ presentRenderbuffer:GL_RENDERBUFFER])
|
||||
{
|
||||
// CCLOG(@"cocos2d: Failed to swap renderbuffer in %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
# if COCOS2D_DEBUG
|
||||
CHECK_GL_ERROR();
|
||||
#endif
|
||||
|
||||
# endif
|
||||
|
||||
// We can safely re-bind the framebuffer here, since this will be the
|
||||
// 1st instruction of the new main loop
|
||||
if( multiSampling_ )
|
||||
if (multiSampling_)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, [renderer_ msaaFrameBuffer]);
|
||||
}
|
||||
|
||||
- (unsigned int) convertPixelFormat:(NSString*) pixelFormat
|
||||
- (unsigned int)convertPixelFormat:(NSString*)pixelFormat
|
||||
{
|
||||
// define the pixel format
|
||||
GLenum pFormat;
|
||||
|
||||
|
||||
if([pixelFormat isEqualToString:@"EAGLColorFormat565"])
|
||||
|
||||
if ([pixelFormat isEqualToString:@"EAGLColorFormat565"])
|
||||
pFormat = GL_RGB565;
|
||||
else
|
||||
pFormat = GL_RGBA8_OES;
|
||||
|
||||
|
||||
return pFormat;
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark CCEAGLView - Point conversion
|
||||
|
||||
- (CGPoint) convertPointFromViewToSurface:(CGPoint)point
|
||||
- (CGPoint)convertPointFromViewToSurface:(CGPoint)point
|
||||
{
|
||||
CGRect bounds = [self bounds];
|
||||
|
||||
|
||||
CGPoint ret;
|
||||
ret.x = (point.x - bounds.origin.x) / bounds.size.width * size_.width;
|
||||
ret.y = (point.y - bounds.origin.y) / bounds.size.height * size_.height;
|
||||
|
||||
ret.y = (point.y - bounds.origin.y) / bounds.size.height * size_.height;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (CGRect) convertRectFromViewToSurface:(CGRect)rect
|
||||
- (CGRect)convertRectFromViewToSurface:(CGRect)rect
|
||||
{
|
||||
CGRect bounds = [self bounds];
|
||||
|
||||
|
||||
CGRect ret;
|
||||
ret.origin.x = (rect.origin.x - bounds.origin.x) / bounds.size.width * size_.width;
|
||||
ret.origin.y = (rect.origin.y - bounds.origin.y) / bounds.size.height * size_.height;
|
||||
ret.size.width = rect.size.width / bounds.size.width * size_.width;
|
||||
ret.origin.x = (rect.origin.x - bounds.origin.x) / bounds.size.width * size_.width;
|
||||
ret.origin.y = (rect.origin.y - bounds.origin.y) / bounds.size.height * size_.height;
|
||||
ret.size.width = rect.size.width / bounds.size.width * size_.width;
|
||||
ret.size.height = rect.size.height / bounds.size.height * size_.height;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Pass the touches to the superview
|
||||
#pragma mark CCEAGLView - Touch Delegate
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
if (self.isKeyboardShown)
|
||||
[self closeKeyboardOpenedByEditBox];
|
||||
|
||||
|
||||
UITouch* ids[IOS_MAX_TOUCHES_COUNT] = {0};
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
int i = 0;
|
||||
for (UITouch *touch in touches) {
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT) {
|
||||
for (UITouch* touch in touches)
|
||||
{
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT)
|
||||
{
|
||||
CCLOG("warning: touches more than 10, should adjust IOS_MAX_TOUCHES_COUNT");
|
||||
break;
|
||||
}
|
||||
|
||||
ids[i] = touch;
|
||||
xs[i] = [touch locationInView: [touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView: [touch view]].y * self.contentScaleFactor;
|
||||
xs[i] = [touch locationInView:[touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView:[touch view]].y * self.contentScaleFactor;
|
||||
++i;
|
||||
}
|
||||
|
||||
|
@ -430,27 +468,30 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
glview->handleTouchesBegin(i, (intptr_t*)ids, xs, ys);
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
UITouch* ids[IOS_MAX_TOUCHES_COUNT] = {0};
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float fs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ms[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float fs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ms[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
int i = 0;
|
||||
for (UITouch *touch in touches) {
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT) {
|
||||
for (UITouch* touch in touches)
|
||||
{
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT)
|
||||
{
|
||||
CCLOG("warning: touches more than 10, should adjust IOS_MAX_TOUCHES_COUNT");
|
||||
break;
|
||||
}
|
||||
|
||||
ids[i] = touch;
|
||||
xs[i] = [touch locationInView: [touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView: [touch view]].y * self.contentScaleFactor;
|
||||
xs[i] = [touch locationInView:[touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView:[touch view]].y * self.contentScaleFactor;
|
||||
#if defined(__IPHONE_9_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0)
|
||||
// running on iOS 9.0 or higher version
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0f) {
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0f)
|
||||
{
|
||||
fs[i] = touch.force;
|
||||
ms[i] = touch.maximumPossibleForce;
|
||||
}
|
||||
|
@ -462,45 +503,49 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
glview->handleTouchesMove(i, (intptr_t*)ids, xs, ys, fs, ms);
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
UITouch* ids[IOS_MAX_TOUCHES_COUNT] = {0};
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
int i = 0;
|
||||
for (UITouch *touch in touches) {
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT) {
|
||||
for (UITouch* touch in touches)
|
||||
{
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT)
|
||||
{
|
||||
CCLOG("warning: touches more than 10, should adjust IOS_MAX_TOUCHES_COUNT");
|
||||
break;
|
||||
}
|
||||
|
||||
ids[i] = touch;
|
||||
xs[i] = [touch locationInView: [touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView: [touch view]].y * self.contentScaleFactor;
|
||||
xs[i] = [touch locationInView:[touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView:[touch view]].y * self.contentScaleFactor;
|
||||
++i;
|
||||
}
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
glview->handleTouchesEnd(i, (intptr_t*)ids, xs, ys);
|
||||
}
|
||||
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
|
||||
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
UITouch* ids[IOS_MAX_TOUCHES_COUNT] = {0};
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
float xs[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
float ys[IOS_MAX_TOUCHES_COUNT] = {0.0f};
|
||||
|
||||
int i = 0;
|
||||
for (UITouch *touch in touches) {
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT) {
|
||||
for (UITouch* touch in touches)
|
||||
{
|
||||
if (i >= IOS_MAX_TOUCHES_COUNT)
|
||||
{
|
||||
CCLOG("warning: touches more than 10, should adjust IOS_MAX_TOUCHES_COUNT");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ids[i] = touch;
|
||||
xs[i] = [touch locationInView: [touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView: [touch view]].y * self.contentScaleFactor;
|
||||
xs[i] = [touch locationInView:[touch view]].x * self.contentScaleFactor;
|
||||
ys[i] = [touch locationInView:[touch view]].y * self.contentScaleFactor;
|
||||
++i;
|
||||
}
|
||||
|
||||
|
@ -508,83 +553,90 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|||
glview->handleTouchesCancel(i, (intptr_t*)ids, xs, ys);
|
||||
}
|
||||
|
||||
- (void) showKeyboard
|
||||
- (void)showKeyboard
|
||||
{
|
||||
[self addSubview:self.textInputView];
|
||||
[self.textInputView becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (void) hideKeyboard
|
||||
- (void)hideKeyboard
|
||||
{
|
||||
[self.textInputView resignFirstResponder];
|
||||
[self.textInputView removeFromSuperview];
|
||||
}
|
||||
|
||||
-(void) doAnimationWhenKeyboardMoveWithDuration:(float) duration distance:(float) dis
|
||||
- (void)doAnimationWhenKeyboardMoveWithDuration:(float)duration distance:(float)dis
|
||||
{
|
||||
[UIView beginAnimations:nil context:nullptr];
|
||||
[UIView setAnimationDelegate:self];
|
||||
[UIView setAnimationDuration:duration];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
|
||||
//NSLog(@"[animation] dis = %f, scale = %f \n", dis, cocos2d::GLView::getInstance()->getScaleY());
|
||||
|
||||
if (dis < 0.0f) dis = 0.0f;
|
||||
[UIView setAnimationDelegate:self];
|
||||
[UIView setAnimationDuration:duration];
|
||||
[UIView setAnimationBeginsFromCurrentState:YES];
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
dis *= glview->getScaleY();
|
||||
|
||||
dis /= self.contentScaleFactor;
|
||||
// NSLog(@"[animation] dis = %f, scale = %f \n", dis, cocos2d::GLView::getInstance()->getScaleY());
|
||||
|
||||
#if defined(CC_TARGET_OS_TVOS)
|
||||
self.frame = CGRectMake(originalRect_.origin.x, originalRect_.origin.y - dis, originalRect_.size.width, originalRect_.size.height);
|
||||
#else
|
||||
switch (getFixedOrientation([[UIApplication sharedApplication] statusBarOrientation]))
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
self.frame = CGRectMake(originalRect_.origin.x, originalRect_.origin.y - dis, originalRect_.size.width, originalRect_.size.height);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
self.frame = CGRectMake(originalRect_.origin.x, originalRect_.origin.y + dis, originalRect_.size.width, originalRect_.size.height);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
self.frame = CGRectMake(originalRect_.origin.x - dis, originalRect_.origin.y , originalRect_.size.width, originalRect_.size.height);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
self.frame = CGRectMake(originalRect_.origin.x + dis, originalRect_.origin.y , originalRect_.size.width, originalRect_.size.height);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
[UIView commitAnimations];
|
||||
if (dis < 0.0f)
|
||||
dis = 0.0f;
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
dis *= glview->getScaleY();
|
||||
|
||||
dis /= self.contentScaleFactor;
|
||||
|
||||
#if defined(CC_TARGET_OS_TVOS)
|
||||
self.frame = CGRectMake(originalRect_.origin.x, originalRect_.origin.y - dis, originalRect_.size.width,
|
||||
originalRect_.size.height);
|
||||
#else
|
||||
switch (getFixedOrientation([[UIApplication sharedApplication] statusBarOrientation]))
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
self.frame = CGRectMake(originalRect_.origin.x, originalRect_.origin.y - dis, originalRect_.size.width,
|
||||
originalRect_.size.height);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
self.frame = CGRectMake(originalRect_.origin.x, originalRect_.origin.y + dis, originalRect_.size.width,
|
||||
originalRect_.size.height);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
self.frame = CGRectMake(originalRect_.origin.x - dis, originalRect_.origin.y, originalRect_.size.width,
|
||||
originalRect_.size.height);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
self.frame = CGRectMake(originalRect_.origin.x + dis, originalRect_.origin.y, originalRect_.size.width,
|
||||
originalRect_.size.height);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
|
||||
-(void) doAnimationWhenAnotherEditBeClicked
|
||||
- (void)doAnimationWhenAnotherEditBeClicked
|
||||
{
|
||||
if (self.keyboardShowNotification != nil)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]postNotification:self.keyboardShowNotification];
|
||||
[[NSNotificationCenter defaultCenter] postNotification:self.keyboardShowNotification];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma UIKeyboard notification
|
||||
|
||||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
namespace {
|
||||
UIInterfaceOrientation getFixedOrientation(UIInterfaceOrientation statusBarOrientation)
|
||||
namespace
|
||||
{
|
||||
UIInterfaceOrientation getFixedOrientation(UIInterfaceOrientation statusBarOrientation)
|
||||
{
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
|
||||
{
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
|
||||
{
|
||||
statusBarOrientation = UIInterfaceOrientationPortrait;
|
||||
}
|
||||
return statusBarOrientation;
|
||||
statusBarOrientation = UIInterfaceOrientationPortrait;
|
||||
}
|
||||
return statusBarOrientation;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -593,87 +645,89 @@ namespace {
|
|||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onUIKeyboardNotification:)
|
||||
name:UIKeyboardWillShowNotification object:nil];
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onUIKeyboardNotification:)
|
||||
name:UIKeyboardDidShowNotification object:nil];
|
||||
name:UIKeyboardDidShowNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onUIKeyboardNotification:)
|
||||
name:UIKeyboardWillHideNotification object:nil];
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onUIKeyboardNotification:)
|
||||
name:UIKeyboardDidHideNotification object:nil];
|
||||
name:UIKeyboardDidHideNotification
|
||||
object:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)onUIKeyboardNotification:(NSNotification *)notif
|
||||
- (void)onUIKeyboardNotification:(NSNotification*)notif
|
||||
{
|
||||
NSString * type = notif.name;
|
||||
|
||||
NSString* type = notif.name;
|
||||
|
||||
NSDictionary* info = [notif userInfo];
|
||||
CGRect begin = [self convertRect:
|
||||
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]
|
||||
fromView:self];
|
||||
CGRect end = [self convertRect:
|
||||
[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]
|
||||
fromView:self];
|
||||
CGRect begin = [self convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self];
|
||||
CGRect end = [self convertRect:[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:self];
|
||||
double aniDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
||||
|
||||
|
||||
CGSize viewSize = self.frame.size;
|
||||
|
||||
CGFloat tmp;
|
||||
switch (getFixedOrientation([[UIApplication sharedApplication] statusBarOrientation]))
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
begin.origin.y = viewSize.height - begin.origin.y - begin.size.height;
|
||||
end.origin.y = viewSize.height - end.origin.y - end.size.height;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
begin.origin.x = viewSize.width - (begin.origin.x + begin.size.width);
|
||||
end.origin.x = viewSize.width - (end.origin.x + end.size.width);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
std::swap(begin.size.width, begin.size.height);
|
||||
std::swap(end.size.width, end.size.height);
|
||||
std::swap(viewSize.width, viewSize.height);
|
||||
|
||||
tmp = begin.origin.x;
|
||||
begin.origin.x = begin.origin.y;
|
||||
begin.origin.y = viewSize.height - tmp - begin.size.height;
|
||||
tmp = end.origin.x;
|
||||
end.origin.x = end.origin.y;
|
||||
end.origin.y = viewSize.height - tmp - end.size.height;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
std::swap(begin.size.width, begin.size.height);
|
||||
std::swap(end.size.width, end.size.height);
|
||||
std::swap(viewSize.width, viewSize.height);
|
||||
|
||||
tmp = begin.origin.x;
|
||||
begin.origin.x = begin.origin.y;
|
||||
begin.origin.y = tmp;
|
||||
tmp = end.origin.x;
|
||||
end.origin.x = end.origin.y;
|
||||
end.origin.y = tmp;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case UIInterfaceOrientationPortrait:
|
||||
begin.origin.y = viewSize.height - begin.origin.y - begin.size.height;
|
||||
end.origin.y = viewSize.height - end.origin.y - end.size.height;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
begin.origin.x = viewSize.width - (begin.origin.x + begin.size.width);
|
||||
end.origin.x = viewSize.width - (end.origin.x + end.size.width);
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
std::swap(begin.size.width, begin.size.height);
|
||||
std::swap(end.size.width, end.size.height);
|
||||
std::swap(viewSize.width, viewSize.height);
|
||||
|
||||
tmp = begin.origin.x;
|
||||
begin.origin.x = begin.origin.y;
|
||||
begin.origin.y = viewSize.height - tmp - begin.size.height;
|
||||
tmp = end.origin.x;
|
||||
end.origin.x = end.origin.y;
|
||||
end.origin.y = viewSize.height - tmp - end.size.height;
|
||||
break;
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
std::swap(begin.size.width, begin.size.height);
|
||||
std::swap(end.size.width, end.size.height);
|
||||
std::swap(viewSize.width, viewSize.height);
|
||||
|
||||
tmp = begin.origin.x;
|
||||
begin.origin.x = begin.origin.y;
|
||||
begin.origin.y = tmp;
|
||||
tmp = end.origin.x;
|
||||
end.origin.x = end.origin.y;
|
||||
end.origin.y = tmp;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
float scaleX = glview->getScaleX();
|
||||
float scaleY = glview->getScaleY();
|
||||
|
||||
|
||||
// Convert to pixel coordinate
|
||||
begin = CGRectApplyAffineTransform(begin, CGAffineTransformScale(CGAffineTransformIdentity, self.contentScaleFactor, self.contentScaleFactor));
|
||||
end = CGRectApplyAffineTransform(end, CGAffineTransformScale(CGAffineTransformIdentity, self.contentScaleFactor, self.contentScaleFactor));
|
||||
|
||||
begin = CGRectApplyAffineTransform(
|
||||
begin, CGAffineTransformScale(CGAffineTransformIdentity, self.contentScaleFactor, self.contentScaleFactor));
|
||||
end = CGRectApplyAffineTransform(
|
||||
end, CGAffineTransformScale(CGAffineTransformIdentity, self.contentScaleFactor, self.contentScaleFactor));
|
||||
|
||||
float offestY = glview->getViewPortRect().origin.y;
|
||||
if (offestY < 0.0f)
|
||||
{
|
||||
|
@ -681,23 +735,18 @@ namespace {
|
|||
begin.size.height -= offestY;
|
||||
end.size.height -= offestY;
|
||||
}
|
||||
|
||||
// Convert to design coordinate
|
||||
begin = CGRectApplyAffineTransform(begin, CGAffineTransformScale(CGAffineTransformIdentity, 1.0f/scaleX, 1.0f/scaleY));
|
||||
end = CGRectApplyAffineTransform(end, CGAffineTransformScale(CGAffineTransformIdentity, 1.0f/scaleX, 1.0f/scaleY));
|
||||
|
||||
|
||||
// Convert to design coordinate
|
||||
begin = CGRectApplyAffineTransform(begin,
|
||||
CGAffineTransformScale(CGAffineTransformIdentity, 1.0f / scaleX, 1.0f / scaleY));
|
||||
end = CGRectApplyAffineTransform(end,
|
||||
CGAffineTransformScale(CGAffineTransformIdentity, 1.0f / scaleX, 1.0f / scaleY));
|
||||
|
||||
cocos2d::IMEKeyboardNotificationInfo notiInfo;
|
||||
notiInfo.begin = cocos2d::Rect(begin.origin.x,
|
||||
begin.origin.y,
|
||||
begin.size.width,
|
||||
begin.size.height);
|
||||
notiInfo.end = cocos2d::Rect(end.origin.x,
|
||||
end.origin.y,
|
||||
end.size.width,
|
||||
end.size.height);
|
||||
notiInfo.begin = cocos2d::Rect(begin.origin.x, begin.origin.y, begin.size.width, begin.size.height);
|
||||
notiInfo.end = cocos2d::Rect(end.origin.x, end.origin.y, end.size.width, end.size.height);
|
||||
notiInfo.duration = (float)aniDuration;
|
||||
|
||||
|
||||
cocos2d::IMEDispatcher* dispatcher = cocos2d::IMEDispatcher::sharedDispatcher();
|
||||
if (UIKeyboardWillShowNotification == type)
|
||||
{
|
||||
|
@ -720,14 +769,14 @@ namespace {
|
|||
}
|
||||
|
||||
// Close the keyboard opened by EditBox
|
||||
-(void) closeKeyboardOpenedByEditBox
|
||||
- (void)closeKeyboardOpenedByEditBox
|
||||
{
|
||||
NSArray *subviews = self.subviews;
|
||||
|
||||
for(UIView* view in subviews)
|
||||
NSArray* subviews = self.subviews;
|
||||
|
||||
for (UIView* view in subviews)
|
||||
{
|
||||
if([view isKindOfClass:NSClassFromString(@"UITextView")] ||
|
||||
[view isKindOfClass:NSClassFromString(@"UITextField")])
|
||||
if ([view isKindOfClass:NSClassFromString(@"UITextView")] ||
|
||||
[view isKindOfClass:NSClassFromString(@"UITextField")])
|
||||
{
|
||||
if ([view isFirstResponder])
|
||||
{
|
||||
|
|
|
@ -33,14 +33,15 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
void* GLViewImpl::_pixelFormat = kEAGLColorFormatRGB565;
|
||||
int GLViewImpl::_depthFormat = GL_DEPTH_COMPONENT16;
|
||||
void* GLViewImpl::_pixelFormat = kEAGLColorFormatRGB565;
|
||||
int GLViewImpl::_depthFormat = GL_DEPTH_COMPONENT16;
|
||||
int GLViewImpl::_multisamplingCount = 0;
|
||||
|
||||
GLViewImpl* GLViewImpl::createWithEAGLView(void *eaglview)
|
||||
GLViewImpl* GLViewImpl::createWithEAGLView(void* eaglview)
|
||||
{
|
||||
auto ret = new GLViewImpl;
|
||||
if(ret->initWithEAGLView(eaglview)) {
|
||||
if (ret->initWithEAGLView(eaglview))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -51,7 +52,8 @@ GLViewImpl* GLViewImpl::createWithEAGLView(void *eaglview)
|
|||
GLViewImpl* GLViewImpl::create(std::string_view viewName)
|
||||
{
|
||||
auto ret = new GLViewImpl;
|
||||
if(ret->initWithFullScreen(viewName)) {
|
||||
if (ret->initWithFullScreen(viewName))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -62,7 +64,8 @@ GLViewImpl* GLViewImpl::create(std::string_view viewName)
|
|||
GLViewImpl* GLViewImpl::createWithRect(std::string_view viewName, const Rect& rect, float frameZoomFactor)
|
||||
{
|
||||
auto ret = new GLViewImpl;
|
||||
if(ret->initWithRect(viewName, rect, frameZoomFactor)) {
|
||||
if (ret->initWithRect(viewName, rect, frameZoomFactor))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -73,7 +76,8 @@ GLViewImpl* GLViewImpl::createWithRect(std::string_view viewName, const Rect& re
|
|||
GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName)
|
||||
{
|
||||
auto ret = new GLViewImpl();
|
||||
if(ret->initWithFullScreen(viewName)) {
|
||||
if (ret->initWithFullScreen(viewName))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -83,49 +87,53 @@ GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName)
|
|||
|
||||
void GLViewImpl::convertAttrs()
|
||||
{
|
||||
if(_glContextAttrs.redBits==8 && _glContextAttrs.greenBits==8 && _glContextAttrs.blueBits==8 && _glContextAttrs.alphaBits==8)
|
||||
if (_glContextAttrs.redBits == 8 && _glContextAttrs.greenBits == 8 && _glContextAttrs.blueBits == 8 &&
|
||||
_glContextAttrs.alphaBits == 8)
|
||||
{
|
||||
_pixelFormat = kEAGLColorFormatRGBA8;
|
||||
} else if (_glContextAttrs.redBits==5 && _glContextAttrs.greenBits==6 && _glContextAttrs.blueBits==5 && _glContextAttrs.alphaBits==0)
|
||||
}
|
||||
else if (_glContextAttrs.redBits == 5 && _glContextAttrs.greenBits == 6 && _glContextAttrs.blueBits == 5 &&
|
||||
_glContextAttrs.alphaBits == 0)
|
||||
{
|
||||
_pixelFormat = kEAGLColorFormatRGB565;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
CCASSERT(0, "Unsupported render buffer pixel format. Using default");
|
||||
}
|
||||
|
||||
if(_glContextAttrs.depthBits==24 && _glContextAttrs.stencilBits==8)
|
||||
if (_glContextAttrs.depthBits == 24 && _glContextAttrs.stencilBits == 8)
|
||||
{
|
||||
_depthFormat = GL_DEPTH24_STENCIL8_OES;
|
||||
} else if (_glContextAttrs.depthBits==0 && _glContextAttrs.stencilBits==0)
|
||||
}
|
||||
else if (_glContextAttrs.depthBits == 0 && _glContextAttrs.stencilBits == 0)
|
||||
{
|
||||
_depthFormat = 0;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
CCASSERT(0, "Unsupported format for depth and stencil buffers. Using default");
|
||||
}
|
||||
|
||||
|
||||
_multisamplingCount = _glContextAttrs.multisamplingCount;
|
||||
}
|
||||
|
||||
GLViewImpl::GLViewImpl()
|
||||
{
|
||||
}
|
||||
GLViewImpl::GLViewImpl() {}
|
||||
|
||||
GLViewImpl::~GLViewImpl()
|
||||
{
|
||||
//CCEAGLView *glview = (CCEAGLView*) _eaglview;
|
||||
// CCEAGLView *glview = (CCEAGLView*) _eaglview;
|
||||
//[glview release];
|
||||
}
|
||||
|
||||
bool GLViewImpl::initWithEAGLView(void *eaglview)
|
||||
bool GLViewImpl::initWithEAGLView(void* eaglview)
|
||||
{
|
||||
_eaglview = eaglview;
|
||||
CCEAGLView *glview = (CCEAGLView*) _eaglview;
|
||||
_eaglview = eaglview;
|
||||
CCEAGLView* glview = (CCEAGLView*)_eaglview;
|
||||
|
||||
_screenSize.width = _designResolutionSize.width = [glview getWidth];
|
||||
_screenSize.height = _designResolutionSize.height = [glview getHeight];
|
||||
// _scaleX = _scaleY = [glview contentScaleFactor];
|
||||
// _scaleX = _scaleY = [glview contentScaleFactor];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -134,13 +142,13 @@ bool GLViewImpl::initWithRect(std::string_view viewName, const Rect& rect, float
|
|||
{
|
||||
CGRect r = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
|
||||
convertAttrs();
|
||||
CCEAGLView *eaglview = [CCEAGLView viewWithFrame: r
|
||||
pixelFormat: (NSString*)_pixelFormat
|
||||
depthFormat: _depthFormat
|
||||
preserveBackbuffer: NO
|
||||
sharegroup: nil
|
||||
multiSampling: NO
|
||||
numberOfSamples: 0];
|
||||
CCEAGLView* eaglview = [CCEAGLView viewWithFrame:r
|
||||
pixelFormat:(NSString*)_pixelFormat
|
||||
depthFormat:_depthFormat
|
||||
preserveBackbuffer:NO
|
||||
sharegroup:nil
|
||||
multiSampling:NO
|
||||
numberOfSamples:0];
|
||||
|
||||
// Not available on tvOS
|
||||
#if !defined(CC_TARGET_OS_TVOS)
|
||||
|
@ -149,7 +157,7 @@ bool GLViewImpl::initWithRect(std::string_view viewName, const Rect& rect, float
|
|||
|
||||
_screenSize.width = _designResolutionSize.width = [eaglview getWidth];
|
||||
_screenSize.height = _designResolutionSize.height = [eaglview getHeight];
|
||||
// _scaleX = _scaleY = [eaglview contentScaleFactor];
|
||||
// _scaleX = _scaleY = [eaglview contentScaleFactor];
|
||||
|
||||
_eaglview = eaglview;
|
||||
|
||||
|
@ -160,9 +168,9 @@ bool GLViewImpl::initWithFullScreen(std::string_view viewName)
|
|||
{
|
||||
CGRect rect = [[UIScreen mainScreen] bounds];
|
||||
Rect r;
|
||||
r.origin.x = rect.origin.x;
|
||||
r.origin.y = rect.origin.y;
|
||||
r.size.width = rect.size.width;
|
||||
r.origin.x = rect.origin.x;
|
||||
r.origin.y = rect.origin.y;
|
||||
r.size.width = rect.size.width;
|
||||
r.size.height = rect.size.height;
|
||||
|
||||
return initWithRect(viewName, r, 1);
|
||||
|
@ -175,10 +183,10 @@ bool GLViewImpl::isOpenGLReady()
|
|||
|
||||
bool GLViewImpl::setContentScaleFactor(float contentScaleFactor)
|
||||
{
|
||||
CC_ASSERT(_resolutionPolicy == ResolutionPolicy::UNKNOWN); // cannot enable retina mode
|
||||
CC_ASSERT(_resolutionPolicy == ResolutionPolicy::UNKNOWN); // cannot enable retina mode
|
||||
_scaleX = _scaleY = contentScaleFactor;
|
||||
|
||||
CCEAGLView *eaglview = (CCEAGLView*) _eaglview;
|
||||
CCEAGLView* eaglview = (CCEAGLView*)_eaglview;
|
||||
[eaglview setNeedsLayout];
|
||||
|
||||
return true;
|
||||
|
@ -186,11 +194,11 @@ bool GLViewImpl::setContentScaleFactor(float contentScaleFactor)
|
|||
|
||||
float GLViewImpl::getContentScaleFactor() const
|
||||
{
|
||||
CCEAGLView *eaglview = (CCEAGLView*) _eaglview;
|
||||
CCEAGLView* eaglview = (CCEAGLView*)_eaglview;
|
||||
|
||||
float scaleFactor = [eaglview contentScaleFactor];
|
||||
|
||||
// CCASSERT(scaleFactor == _scaleX == _scaleY, "Logic error in GLView::getContentScaleFactor");
|
||||
// CCASSERT(scaleFactor == _scaleX == _scaleY, "Logic error in GLView::getContentScaleFactor");
|
||||
|
||||
return scaleFactor;
|
||||
}
|
||||
|
@ -200,23 +208,22 @@ void GLViewImpl::end()
|
|||
[CCDirectorCaller destroy];
|
||||
|
||||
// destroy EAGLView
|
||||
CCEAGLView *eaglview = (CCEAGLView*) _eaglview;
|
||||
CCEAGLView* eaglview = (CCEAGLView*)_eaglview;
|
||||
|
||||
[eaglview removeFromSuperview];
|
||||
//[eaglview release];
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
void GLViewImpl::swapBuffers()
|
||||
{
|
||||
CCEAGLView *eaglview = (CCEAGLView*) _eaglview;
|
||||
CCEAGLView* eaglview = (CCEAGLView*)_eaglview;
|
||||
[eaglview swapBuffers];
|
||||
}
|
||||
|
||||
void GLViewImpl::setIMEKeyboardState(bool open)
|
||||
{
|
||||
CCEAGLView *eaglview = (CCEAGLView*) _eaglview;
|
||||
CCEAGLView* eaglview = (CCEAGLView*)_eaglview;
|
||||
|
||||
if (open)
|
||||
{
|
||||
|
@ -230,16 +237,16 @@ void GLViewImpl::setIMEKeyboardState(bool open)
|
|||
|
||||
Rect GLViewImpl::getSafeAreaRect() const
|
||||
{
|
||||
CCEAGLView *eaglview = (CCEAGLView*) _eaglview;
|
||||
CCEAGLView* eaglview = (CCEAGLView*)_eaglview;
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
|
||||
float version = [[UIDevice currentDevice].systemVersion floatValue];
|
||||
if (version >= 11.0f)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
UIEdgeInsets safeAreaInsets = eaglview.safeAreaInsets;
|
||||
#pragma clang diagnostic pop
|
||||
# pragma clang diagnostic pop
|
||||
|
||||
// Multiply contentScaleFactor since safeAreaInsets return points.
|
||||
safeAreaInsets.left *= eaglview.contentScaleFactor;
|
||||
|
@ -249,23 +256,23 @@ Rect GLViewImpl::getSafeAreaRect() const
|
|||
|
||||
// Get leftBottom and rightTop point in UI coordinates
|
||||
Vec2 leftBottom = Vec2(safeAreaInsets.left, _screenSize.height - safeAreaInsets.bottom);
|
||||
Vec2 rightTop = Vec2(_screenSize.width - safeAreaInsets.right, safeAreaInsets.top);
|
||||
Vec2 rightTop = Vec2(_screenSize.width - safeAreaInsets.right, safeAreaInsets.top);
|
||||
|
||||
// Convert a point from UI coordinates to which in design resolution coordinate.
|
||||
leftBottom.x = (leftBottom.x - _viewPortRect.origin.x) / _scaleX,
|
||||
leftBottom.y = (leftBottom.y - _viewPortRect.origin.y) / _scaleY;
|
||||
rightTop.x = (rightTop.x - _viewPortRect.origin.x) / _scaleX,
|
||||
rightTop.y = (rightTop.y - _viewPortRect.origin.y) / _scaleY;
|
||||
rightTop.x = (rightTop.x - _viewPortRect.origin.x) / _scaleX,
|
||||
rightTop.y = (rightTop.y - _viewPortRect.origin.y) / _scaleY;
|
||||
|
||||
// Adjust points to make them inside design resolution
|
||||
leftBottom.x = MAX(leftBottom.x, 0);
|
||||
leftBottom.y = MIN(leftBottom.y, _designResolutionSize.height);
|
||||
rightTop.x = MIN(rightTop.x, _designResolutionSize.width);
|
||||
rightTop.y = MAX(rightTop.y, 0);
|
||||
rightTop.x = MIN(rightTop.x, _designResolutionSize.width);
|
||||
rightTop.y = MAX(rightTop.y, 0);
|
||||
|
||||
// Convert to GL coordinates
|
||||
leftBottom = Director::getInstance()->convertToGL(leftBottom);
|
||||
rightTop = Director::getInstance()->convertToGL(rightTop);
|
||||
rightTop = Director::getInstance()->convertToGL(rightTop);
|
||||
|
||||
return Rect(leftBottom.x, leftBottom.y, rightTop.x - leftBottom.x, rightTop.y - leftBottom.y);
|
||||
}
|
||||
|
|
|
@ -37,13 +37,14 @@ NS_CC_BEGIN
|
|||
|
||||
bool cocos2d::Image::saveToFile(std::string_view filename, bool isToRGB)
|
||||
{
|
||||
//only support for backend::PixelFormat::RGB8 or backend::PixelFormat::RGBA8 uncompressed data
|
||||
// only support for backend::PixelFormat::RGB8 or backend::PixelFormat::RGBA8 uncompressed data
|
||||
if (isCompressed() || (_pixelFormat != backend::PixelFormat::RGB8 && _pixelFormat != backend::PixelFormat::RGBA8))
|
||||
{
|
||||
CCLOG("cocos2d: Image: saveToFile is only support for backend::PixelFormat::RGB8 or backend::PixelFormat::RGBA8 uncompressed data for now");
|
||||
CCLOG("cocos2d: Image: saveToFile is only support for backend::PixelFormat::RGB8 or "
|
||||
"backend::PixelFormat::RGBA8 uncompressed data for now");
|
||||
return false;
|
||||
}
|
||||
bool saveToPNG = false;
|
||||
bool saveToPNG = false;
|
||||
bool needToCopyPixels = false;
|
||||
|
||||
std::string basename(filename);
|
||||
|
@ -52,64 +53,65 @@ bool cocos2d::Image::saveToFile(std::string_view filename, bool isToRGB)
|
|||
{
|
||||
saveToPNG = true;
|
||||
}
|
||||
|
||||
int bitsPerComponent = 8;
|
||||
int bitsPerPixel = hasAlpha() ? 32 : 24;
|
||||
if ((! saveToPNG) || isToRGB)
|
||||
|
||||
int bitsPerComponent = 8;
|
||||
int bitsPerPixel = hasAlpha() ? 32 : 24;
|
||||
if ((!saveToPNG) || isToRGB)
|
||||
{
|
||||
bitsPerPixel = 24;
|
||||
}
|
||||
|
||||
int bytesPerRow = (bitsPerPixel/8) * _width;
|
||||
}
|
||||
|
||||
int bytesPerRow = (bitsPerPixel / 8) * _width;
|
||||
int myDataLength = bytesPerRow * _height;
|
||||
|
||||
unsigned char *pixels = _data;
|
||||
|
||||
|
||||
unsigned char* pixels = _data;
|
||||
|
||||
// The data has alpha channel, and want to save it with an RGB png file,
|
||||
// or want to save as jpg, remove the alpha channel.
|
||||
if (hasAlpha() && bitsPerPixel == 24)
|
||||
{
|
||||
pixels = new unsigned char[myDataLength];
|
||||
|
||||
|
||||
for (int i = 0; i < _height; ++i)
|
||||
{
|
||||
for (int j = 0; j < _width; ++j)
|
||||
{
|
||||
pixels[(i * _width + j) * 3] = _data[(i * _width + j) * 4];
|
||||
pixels[(i * _width + j) * 3] = _data[(i * _width + j) * 4];
|
||||
pixels[(i * _width + j) * 3 + 1] = _data[(i * _width + j) * 4 + 1];
|
||||
pixels[(i * _width + j) * 3 + 2] = _data[(i * _width + j) * 4 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
needToCopyPixels = true;
|
||||
}
|
||||
|
||||
|
||||
// make data provider with data.
|
||||
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
|
||||
if (saveToPNG && hasAlpha() && (! isToRGB))
|
||||
if (saveToPNG && hasAlpha() && (!isToRGB))
|
||||
{
|
||||
bitmapInfo |= kCGImageAlphaLast;
|
||||
}
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, pixels, myDataLength, nullptr);
|
||||
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef iref = CGImageCreate(_width, _height,
|
||||
bitsPerComponent, bitsPerPixel, bytesPerRow,
|
||||
colorSpaceRef, bitmapInfo, provider,
|
||||
nullptr, false,
|
||||
kCGRenderingIntentDefault);
|
||||
|
||||
UIImage* image = [[UIImage alloc] initWithCGImage:iref];
|
||||
|
||||
CGImageRelease(iref);
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, pixels, myDataLength, nullptr);
|
||||
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef iref = CGImageCreate(_width, _height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef,
|
||||
bitmapInfo, provider, nullptr, false, kCGRenderingIntentDefault);
|
||||
|
||||
UIImage* image = [[UIImage alloc] initWithCGImage:iref];
|
||||
|
||||
CGImageRelease(iref);
|
||||
CGColorSpaceRelease(colorSpaceRef);
|
||||
CGDataProviderRelease(provider);
|
||||
|
||||
// NOTE: Prevent memory leak. Requires ARC enabled.
|
||||
@autoreleasepool {
|
||||
NSData *data;
|
||||
if (saveToPNG) {
|
||||
@autoreleasepool
|
||||
{
|
||||
NSData* data;
|
||||
if (saveToPNG)
|
||||
{
|
||||
data = UIImagePNGRepresentation(image);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
data = UIImageJPEGRepresentation(image, 1.0f);
|
||||
}
|
||||
|
||||
|
@ -121,9 +123,9 @@ bool cocos2d::Image::saveToFile(std::string_view filename, bool isToRGB)
|
|||
|
||||
if (needToCopyPixels)
|
||||
{
|
||||
delete [] pixels;
|
||||
delete[] pixels;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,27 +41,31 @@ THE SOFTWARE.
|
|||
@synthesize tokenizer;
|
||||
@synthesize autocorrectionType;
|
||||
|
||||
- (instancetype) initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame] ) {
|
||||
self.myMarkedText = nil;
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame])
|
||||
{
|
||||
self.myMarkedText = nil;
|
||||
self.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self]; // remove keyboard notification
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self]; // remove keyboard notification
|
||||
[self.myMarkedText release];
|
||||
[self removeFromSuperview];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL) canBecomeFirstResponder {
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
|
||||
{
|
||||
[self resignFirstResponder];
|
||||
[self removeFromSuperview];
|
||||
|
@ -69,159 +73,190 @@ THE SOFTWARE.
|
|||
|
||||
#pragma TextInput protocol
|
||||
|
||||
- (id<UITextInputDelegate>)inputDelegate {
|
||||
- (id<UITextInputDelegate>)inputDelegate
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setInputDelegate:(id<UITextInputDelegate>)inputDelegate {
|
||||
|
||||
}
|
||||
- (void)setInputDelegate:(id<UITextInputDelegate>)inputDelegate
|
||||
{}
|
||||
|
||||
- (void)setSelectedTextRange:(UITextRange *)aSelectedTextRange {
|
||||
- (void)setSelectedTextRange:(UITextRange*)aSelectedTextRange
|
||||
{
|
||||
CCLOG("UITextRange:setSelectedTextRange");
|
||||
}
|
||||
|
||||
- (UITextRange *)selectedTextRange {
|
||||
- (UITextRange*)selectedTextRange
|
||||
{
|
||||
return [[[UITextRange alloc] init] autorelease];
|
||||
}
|
||||
|
||||
- (void)deleteBackward {
|
||||
if (nil != self.myMarkedText) {
|
||||
- (void)deleteBackward
|
||||
{
|
||||
if (nil != self.myMarkedText)
|
||||
{
|
||||
[self.myMarkedText release];
|
||||
self.myMarkedText = nil;
|
||||
}
|
||||
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
|
||||
}
|
||||
|
||||
- (void)insertText:(nonnull NSString *)text {
|
||||
if (nil != self.myMarkedText) {
|
||||
- (void)insertText:(nonnull NSString*)text
|
||||
{
|
||||
if (nil != self.myMarkedText)
|
||||
{
|
||||
[self.myMarkedText release];
|
||||
self.myMarkedText = nil;
|
||||
}
|
||||
const char * pszText = [text cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
const char* pszText = [text cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(pszText, strlen(pszText));
|
||||
}
|
||||
|
||||
- (NSWritingDirection)baseWritingDirectionForPosition:(nonnull UITextPosition *)position inDirection:(UITextStorageDirection)direction {
|
||||
- (NSWritingDirection)baseWritingDirectionForPosition:(nonnull UITextPosition*)position
|
||||
inDirection:(UITextStorageDirection)direction
|
||||
{
|
||||
CCLOG("baseWritingDirectionForPosition");
|
||||
return NSWritingDirectionLeftToRight;
|
||||
}
|
||||
|
||||
- (CGRect)caretRectForPosition:(nonnull UITextPosition *)position {
|
||||
- (CGRect)caretRectForPosition:(nonnull UITextPosition*)position
|
||||
{
|
||||
CCLOG("caretRectForPosition");
|
||||
return CGRectZero;
|
||||
}
|
||||
|
||||
- (nullable UITextRange *)characterRangeAtPoint:(CGPoint)point {
|
||||
- (nullable UITextRange*)characterRangeAtPoint:(CGPoint)point
|
||||
{
|
||||
CCLOG("characterRangeAtPoint");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UITextRange *)characterRangeByExtendingPosition:(nonnull UITextPosition *)position inDirection:(UITextLayoutDirection)direction {
|
||||
- (nullable UITextRange*)characterRangeByExtendingPosition:(nonnull UITextPosition*)position
|
||||
inDirection:(UITextLayoutDirection)direction
|
||||
{
|
||||
CCLOG("characterRangeByExtendingPosition");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UITextPosition *)closestPositionToPoint:(CGPoint)point {
|
||||
- (nullable UITextPosition*)closestPositionToPoint:(CGPoint)point
|
||||
{
|
||||
CCLOG("closestPositionToPoint");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UITextPosition *)closestPositionToPoint:(CGPoint)point withinRange:(nonnull UITextRange *)range {
|
||||
- (nullable UITextPosition*)closestPositionToPoint:(CGPoint)point withinRange:(nonnull UITextRange*)range
|
||||
{
|
||||
CCLOG("closestPositionToPoint");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSComparisonResult)comparePosition:(nonnull UITextPosition *)position toPosition:(nonnull UITextPosition *)other {
|
||||
- (NSComparisonResult)comparePosition:(nonnull UITextPosition*)position toPosition:(nonnull UITextPosition*)other
|
||||
{
|
||||
CCLOG("comparePosition");
|
||||
return (NSComparisonResult)0;
|
||||
}
|
||||
|
||||
- (CGRect)firstRectForRange:(nonnull UITextRange *)range {
|
||||
- (CGRect)firstRectForRange:(nonnull UITextRange*)range
|
||||
{
|
||||
CCLOG("firstRectForRange");
|
||||
return CGRectNull;
|
||||
}
|
||||
|
||||
- (NSInteger)offsetFromPosition:(nonnull UITextPosition *)from toPosition:(nonnull UITextPosition *)toPosition {
|
||||
- (NSInteger)offsetFromPosition:(nonnull UITextPosition*)from toPosition:(nonnull UITextPosition*)toPosition
|
||||
{
|
||||
CCLOG("offsetFromPosition");
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (nullable UITextPosition *)positionFromPosition:(nonnull UITextPosition *)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset {
|
||||
- (nullable UITextPosition*)positionFromPosition:(nonnull UITextPosition*)position
|
||||
inDirection:(UITextLayoutDirection)direction
|
||||
offset:(NSInteger)offset
|
||||
{
|
||||
CCLOG("positionFromPosition");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UITextPosition *)positionFromPosition:(nonnull UITextPosition *)position offset:(NSInteger)offset {
|
||||
- (nullable UITextPosition*)positionFromPosition:(nonnull UITextPosition*)position offset:(NSInteger)offset
|
||||
{
|
||||
CCLOG("positionFromPosition");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UITextPosition *)positionWithinRange:(nonnull UITextRange *)range farthestInDirection:(UITextLayoutDirection)direction {
|
||||
- (nullable UITextPosition*)positionWithinRange:(nonnull UITextRange*)range
|
||||
farthestInDirection:(UITextLayoutDirection)direction
|
||||
{
|
||||
CCLOG("positionWithinRange");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)replaceRange:(nonnull UITextRange *)range withText:(nonnull NSString *)text {
|
||||
|
||||
}
|
||||
- (void)replaceRange:(nonnull UITextRange*)range withText:(nonnull NSString*)text
|
||||
{}
|
||||
|
||||
- (nonnull NSArray<UITextSelectionRect *> *)selectionRectsForRange:(nonnull UITextRange *)range {
|
||||
- (nonnull NSArray<UITextSelectionRect*>*)selectionRectsForRange:(nonnull UITextRange*)range
|
||||
{
|
||||
CCLOG("selectionRectsForRange");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setBaseWritingDirection:(NSWritingDirection)writingDirection forRange:(nonnull UITextRange *)range {
|
||||
|
||||
}
|
||||
- (void)setBaseWritingDirection:(NSWritingDirection)writingDirection forRange:(nonnull UITextRange*)range
|
||||
{}
|
||||
|
||||
- (void)setMarkedText:(nullable NSString *)markedText selectedRange:(NSRange)selectedRange {
|
||||
- (void)setMarkedText:(nullable NSString*)markedText selectedRange:(NSRange)selectedRange
|
||||
{
|
||||
CCLOG("setMarkedText");
|
||||
if (markedText == self.myMarkedText) {
|
||||
if (markedText == self.myMarkedText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (nil != self.myMarkedText) {
|
||||
if (nil != self.myMarkedText)
|
||||
{
|
||||
[self.myMarkedText release];
|
||||
}
|
||||
self.myMarkedText = markedText;
|
||||
[self.myMarkedText retain];
|
||||
}
|
||||
|
||||
- (UITextRange *)markedTextRange
|
||||
- (UITextRange*)markedTextRange
|
||||
{
|
||||
CCLOG("markedTextRange");
|
||||
if (nil != self.myMarkedText) {
|
||||
if (nil != self.myMarkedText)
|
||||
{
|
||||
return [[[UITextRange alloc] init] autorelease];
|
||||
}
|
||||
return nil; // Nil if no marked text.
|
||||
return nil; // Nil if no marked text.
|
||||
}
|
||||
|
||||
- (nullable NSString *)textInRange:(nonnull UITextRange *)range {
|
||||
- (nullable NSString*)textInRange:(nonnull UITextRange*)range
|
||||
{
|
||||
CCLOG("textInRange");
|
||||
if (nil != self.myMarkedText) {
|
||||
if (nil != self.myMarkedText)
|
||||
{
|
||||
return self.myMarkedText;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UITextRange *)textRangeFromPosition:(nonnull UITextPosition *)fromPosition toPosition:(nonnull UITextPosition *)toPosition {
|
||||
- (nullable UITextRange*)textRangeFromPosition:(nonnull UITextPosition*)fromPosition
|
||||
toPosition:(nonnull UITextPosition*)toPosition
|
||||
{
|
||||
CCLOG("textRangeFromPosition");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)unmarkText {
|
||||
- (void)unmarkText
|
||||
{
|
||||
CCLOG("unmarkText");
|
||||
if (nil == self.myMarkedText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const char * pszText = [self.myMarkedText cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
const char* pszText = [self.myMarkedText cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(pszText, strlen(pszText));
|
||||
[self.myMarkedText release];
|
||||
self.myMarkedText = nil;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
|
||||
}
|
||||
- (void)encodeWithCoder:(nonnull NSCoder*)coder
|
||||
{}
|
||||
|
||||
@end
|
||||
|
|
|
@ -40,18 +40,17 @@ static int32_t getCurrentMillSecond()
|
|||
{
|
||||
int32_t lLastTime = 0;
|
||||
struct timeval stCurrentTime;
|
||||
|
||||
gettimeofday(&stCurrentTime,NULL);
|
||||
lLastTime = stCurrentTime.tv_sec*1000+stCurrentTime.tv_usec*0.001; // milliseconds
|
||||
|
||||
gettimeofday(&stCurrentTime, NULL);
|
||||
lLastTime = stCurrentTime.tv_sec * 1000 + stCurrentTime.tv_usec * 0.001; // milliseconds
|
||||
return lLastTime;
|
||||
}
|
||||
|
||||
Application* Application::sm_pSharedApplication = nullptr;
|
||||
|
||||
Application::Application()
|
||||
: _animationInterval(1.0f/60.0f*1000.0f)
|
||||
Application::Application() : _animationInterval(1.0f / 60.0f * 1000.0f)
|
||||
{
|
||||
CCASSERT(! sm_pSharedApplication, "sm_pSharedApplication already exist");
|
||||
CCASSERT(!sm_pSharedApplication, "sm_pSharedApplication already exist");
|
||||
sm_pSharedApplication = this;
|
||||
}
|
||||
|
||||
|
@ -64,53 +63,53 @@ Application::~Application()
|
|||
int Application::run()
|
||||
{
|
||||
initGLContextAttrs();
|
||||
if(!applicationDidFinishLaunching())
|
||||
if (!applicationDidFinishLaunching())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int32_t lastTime = 0L;
|
||||
int32_t curTime = 0L;
|
||||
|
||||
int32_t curTime = 0L;
|
||||
|
||||
auto director = Director::getInstance();
|
||||
auto glview = director->getOpenGLView();
|
||||
|
||||
auto glview = director->getOpenGLView();
|
||||
|
||||
// Retain glview to avoid glview being released in the while loop
|
||||
glview->retain();
|
||||
|
||||
while (!glview->windowShouldClose())
|
||||
{
|
||||
lastTime = getCurrentMillSecond();
|
||||
|
||||
|
||||
director->mainLoop();
|
||||
glview->pollEvents();
|
||||
|
||||
curTime = getCurrentMillSecond();
|
||||
if (curTime - lastTime < _animationInterval)
|
||||
{
|
||||
usleep(static_cast<useconds_t>((_animationInterval - curTime + lastTime)*1000));
|
||||
usleep(static_cast<useconds_t>((_animationInterval - curTime + lastTime) * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
/* Only work on Desktop
|
||||
* Director::mainLoop is really one frame logic
|
||||
* when we want to close the window, we should call Director::end();
|
||||
* then call Director::mainLoop to do release of internal resources
|
||||
*/
|
||||
* Director::mainLoop is really one frame logic
|
||||
* when we want to close the window, we should call Director::end();
|
||||
* then call Director::mainLoop to do release of internal resources
|
||||
*/
|
||||
if (glview->isOpenGLReady())
|
||||
{
|
||||
director->end();
|
||||
director->mainLoop();
|
||||
}
|
||||
|
||||
|
||||
glview->release();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Application::setAnimationInterval(float interval)
|
||||
{
|
||||
_animationInterval = interval*1000.0f;
|
||||
_animationInterval = interval * 1000.0f;
|
||||
}
|
||||
|
||||
Application::Platform Application::getTargetPlatform()
|
||||
|
@ -118,9 +117,11 @@ Application::Platform Application::getTargetPlatform()
|
|||
return Platform::OS_MAC;
|
||||
}
|
||||
|
||||
std::string Application::getVersion() {
|
||||
std::string Application::getVersion()
|
||||
{
|
||||
NSString* version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
|
||||
if (version) {
|
||||
if (version)
|
||||
{
|
||||
return [version UTF8String];
|
||||
}
|
||||
return "";
|
||||
|
@ -136,39 +137,39 @@ Application* Application::getInstance()
|
|||
return sm_pSharedApplication;
|
||||
}
|
||||
|
||||
const char * Application::getCurrentLanguageCode()
|
||||
const char* Application::getCurrentLanguageCode()
|
||||
{
|
||||
static char code[3]={0};
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString *currentLanguage = [languages objectAtIndex:0];
|
||||
|
||||
static char code[3] = {0};
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray* languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString* currentLanguage = [languages objectAtIndex:0];
|
||||
|
||||
// get the current language code.(such as English is "en", Chinese is "zh" and so on)
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString * languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString* languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
[languageCode getCString:code maxLength:3 encoding:NSASCIIStringEncoding];
|
||||
code[2]='\0';
|
||||
code[2] = '\0';
|
||||
return code;
|
||||
}
|
||||
|
||||
LanguageType Application::getCurrentLanguage()
|
||||
{
|
||||
// get the current language and country config
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString *currentLanguage = [languages objectAtIndex:0];
|
||||
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSArray* languages = [defaults objectForKey:@"AppleLanguages"];
|
||||
NSString* currentLanguage = [languages objectAtIndex:0];
|
||||
|
||||
// get the current language code.(such as English is "en", Chinese is "zh" and so on)
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString * languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
|
||||
NSDictionary* temp = [NSLocale componentsFromLocaleIdentifier:currentLanguage];
|
||||
NSString* languageCode = [temp objectForKey:NSLocaleLanguageCode];
|
||||
|
||||
return utils::getLanguageTypeByISO2([languageCode UTF8String]);
|
||||
}
|
||||
|
||||
bool Application::openURL(const std::string &url)
|
||||
bool Application::openURL(const std::string& url)
|
||||
{
|
||||
NSString* msg = [NSString stringWithCString:url.c_str() encoding:NSUTF8StringEncoding];
|
||||
NSURL* nsUrl = [NSURL URLWithString:msg];
|
||||
NSURL* nsUrl = [NSURL URLWithString:msg];
|
||||
return [[NSWorkspace sharedWorkspace] openURL:nsUrl];
|
||||
}
|
||||
|
||||
|
|
|
@ -33,25 +33,25 @@ THE SOFTWARE.
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
void LuaLog(const char * format)
|
||||
void LuaLog(const char* format)
|
||||
{
|
||||
puts(format);
|
||||
}
|
||||
|
||||
// ios no MessageBox, use log instead
|
||||
void ccMessageBox(const char * msg, const char * title)
|
||||
void ccMessageBox(const char* msg, const char* title)
|
||||
{
|
||||
NSString * tmpTitle = (title) ? [NSString stringWithUTF8String : title] : nil;
|
||||
NSString * tmpMsg = (msg) ? [NSString stringWithUTF8String : msg] : nil;
|
||||
NSString* tmpTitle = (title) ? [NSString stringWithUTF8String:title] : nil;
|
||||
NSString* tmpMsg = (msg) ? [NSString stringWithUTF8String:msg] : nil;
|
||||
|
||||
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
|
||||
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert setMessageText:tmpMsg];
|
||||
[alert setInformativeText:tmpTitle];
|
||||
[alert setAlertStyle:NSAlertStyleWarning];
|
||||
|
||||
auto glview = Director::getInstance()->getOpenGLView();
|
||||
id window = glview->getCocoaWindow();
|
||||
id window = glview->getCocoaWindow();
|
||||
[alert beginSheetModalForWindow:window completionHandler:nil];
|
||||
}
|
||||
|
||||
|
|
|
@ -36,41 +36,37 @@ static NSAttributedString* __attributedStringWithFontSize(NSMutableAttributedStr
|
|||
{
|
||||
{
|
||||
[attributedString beginEditing];
|
||||
|
||||
[attributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
|
||||
|
||||
NSFont* font = value;
|
||||
font = [[NSFontManager sharedFontManager] convertFont:font toSize:fontSize];
|
||||
|
||||
[attributedString removeAttribute:NSFontAttributeName range:range];
|
||||
[attributedString addAttribute:NSFontAttributeName value:font range:range];
|
||||
}];
|
||||
|
||||
|
||||
[attributedString enumerateAttribute:NSFontAttributeName
|
||||
inRange:NSMakeRange(0, attributedString.length)
|
||||
options:0
|
||||
usingBlock:^(id value, NSRange range, BOOL* stop) {
|
||||
NSFont* font = value;
|
||||
font = [[NSFontManager sharedFontManager] convertFont:font toSize:fontSize];
|
||||
|
||||
[attributedString removeAttribute:NSFontAttributeName range:range];
|
||||
[attributedString addAttribute:NSFontAttributeName value:font range:range];
|
||||
}];
|
||||
|
||||
[attributedString endEditing];
|
||||
}
|
||||
|
||||
|
||||
return [[attributedString copy] autorelease];
|
||||
}
|
||||
|
||||
int Device::getDPI()
|
||||
{
|
||||
NSScreen *screen = [NSScreen mainScreen];
|
||||
NSDictionary *description = [screen deviceDescription];
|
||||
NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
|
||||
NSScreen* screen = [NSScreen mainScreen];
|
||||
NSDictionary* description = [screen deviceDescription];
|
||||
NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
|
||||
CGSize displayPhysicalSize = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
|
||||
|
||||
|
||||
return ((displayPixelSize.width / displayPhysicalSize.width) * 25.4f);
|
||||
}
|
||||
|
||||
void Device::setAccelerometerEnabled(bool isEnabled)
|
||||
{
|
||||
void Device::setAccelerometerEnabled(bool isEnabled) {}
|
||||
|
||||
}
|
||||
|
||||
void Device::setAccelerometerInterval(float interval)
|
||||
{
|
||||
|
||||
}
|
||||
void Device::setAccelerometerInterval(float interval) {}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -81,305 +77,359 @@ typedef struct
|
|||
unsigned char* data;
|
||||
} tImageInfo;
|
||||
|
||||
static NSSize _calculateStringSize(NSAttributedString *str, id font, CGSize *constrainSize, bool enableWrap, int overflow)
|
||||
static NSSize _calculateStringSize(NSAttributedString* str,
|
||||
id font,
|
||||
CGSize* constrainSize,
|
||||
bool enableWrap,
|
||||
int overflow)
|
||||
{
|
||||
NSSize textRect = NSZeroSize;
|
||||
textRect.width = constrainSize->width > 0 ? constrainSize->width
|
||||
: CGFLOAT_MAX;
|
||||
textRect.height = constrainSize->height > 0 ? constrainSize->height
|
||||
: CGFLOAT_MAX;
|
||||
|
||||
if (overflow == 1) {
|
||||
if (!enableWrap) {
|
||||
textRect.width = CGFLOAT_MAX;
|
||||
textRect.width = constrainSize->width > 0 ? constrainSize->width : CGFLOAT_MAX;
|
||||
textRect.height = constrainSize->height > 0 ? constrainSize->height : CGFLOAT_MAX;
|
||||
|
||||
if (overflow == 1)
|
||||
{
|
||||
if (!enableWrap)
|
||||
{
|
||||
textRect.width = CGFLOAT_MAX;
|
||||
textRect.height = CGFLOAT_MAX;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
textRect.height = CGFLOAT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NSSize dim;
|
||||
#ifdef __MAC_10_11
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_11
|
||||
dim = [str boundingRectWithSize:textRect options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin) context:nil].size;
|
||||
#else
|
||||
dim = [str boundingRectWithSize:textRect options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin)].size;
|
||||
#endif
|
||||
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_11
|
||||
dim = [str boundingRectWithSize:textRect
|
||||
options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin)context:nil]
|
||||
.size;
|
||||
# else
|
||||
dim = [str boundingRectWithSize:textRect options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin)]
|
||||
.size;
|
||||
# endif
|
||||
#else
|
||||
dim = [str boundingRectWithSize:textRect options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin)].size;
|
||||
dim = [str boundingRectWithSize:textRect options:(NSStringDrawingOptions)(NSStringDrawingUsesLineFragmentOrigin)]
|
||||
.size;
|
||||
#endif
|
||||
|
||||
|
||||
dim.width = ceilf(dim.width);
|
||||
|
||||
dim.width = ceilf(dim.width);
|
||||
dim.height = ceilf(dim.height);
|
||||
|
||||
return dim;
|
||||
}
|
||||
|
||||
static NSSize _calculateRealSizeForString(NSAttributedString **str, id font, NSSize constrainSize, bool enableWrap)
|
||||
static NSSize _calculateRealSizeForString(NSAttributedString** str, id font, NSSize constrainSize, bool enableWrap)
|
||||
{
|
||||
CGRect actualSize = CGRectMake(0, 0, constrainSize.width + 1, constrainSize.height + 1);
|
||||
int fontSize = [font pointSize];
|
||||
fontSize = fontSize + 1;
|
||||
int fontSize = [font pointSize];
|
||||
fontSize = fontSize + 1;
|
||||
|
||||
if (!enableWrap) {
|
||||
while (actualSize.size.width > constrainSize.width ||
|
||||
actualSize.size.height > constrainSize.height) {
|
||||
if (!enableWrap)
|
||||
{
|
||||
while (actualSize.size.width > constrainSize.width || actualSize.size.height > constrainSize.height)
|
||||
{
|
||||
fontSize = fontSize - 1;
|
||||
if (fontSize < 0) {
|
||||
if (fontSize < 0)
|
||||
{
|
||||
actualSize = CGRectMake(0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
NSMutableAttributedString *mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
NSMutableAttributedString* mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
#ifdef __MAC_10_11
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_11
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake( CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
|
||||
#else
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake( CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin].size;
|
||||
#endif
|
||||
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_11
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin
|
||||
context:nil]
|
||||
.size;
|
||||
# else
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin]
|
||||
.size;
|
||||
# endif
|
||||
#else
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake( CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin].size;
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin]
|
||||
.size;
|
||||
#endif
|
||||
|
||||
if(fitSize.width == 0 || fitSize.height == 0) continue;
|
||||
if (fitSize.width == 0 || fitSize.height == 0)
|
||||
continue;
|
||||
actualSize.size = fitSize;
|
||||
|
||||
if (constrainSize.width <= 0) {
|
||||
if (constrainSize.width <= 0)
|
||||
{
|
||||
constrainSize.width = fitSize.width;
|
||||
}
|
||||
if (constrainSize.height <= 0){
|
||||
if (constrainSize.height <= 0)
|
||||
{
|
||||
constrainSize.height = fitSize.height;
|
||||
}
|
||||
if(fontSize <= 0){
|
||||
if (fontSize <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
while (actualSize.size.height > constrainSize.height
|
||||
||actualSize.size.width > constrainSize.width) {
|
||||
else
|
||||
{
|
||||
while (actualSize.size.height > constrainSize.height || actualSize.size.width > constrainSize.width)
|
||||
{
|
||||
fontSize = fontSize - 1;
|
||||
if (fontSize < 0) {
|
||||
if (fontSize < 0)
|
||||
{
|
||||
actualSize = CGRectMake(0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
NSMutableAttributedString *mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
NSMutableAttributedString* mutableString = [[*str mutableCopy] autorelease];
|
||||
*str = __attributedStringWithFontSize(mutableString, fontSize);
|
||||
|
||||
#ifdef __MAC_10_11
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_11
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake( constrainSize.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
|
||||
#else
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake( constrainSize.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin].size;
|
||||
#endif
|
||||
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_11
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(constrainSize.width, CGFLOAT_MAX)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin
|
||||
context:nil]
|
||||
.size;
|
||||
# else
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(constrainSize.width, CGFLOAT_MAX)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin]
|
||||
.size;
|
||||
# endif
|
||||
#else
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake( constrainSize.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin].size;
|
||||
CGSize fitSize = [*str boundingRectWithSize:CGSizeMake(constrainSize.width, CGFLOAT_MAX)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin]
|
||||
.size;
|
||||
#endif
|
||||
|
||||
if(fitSize.width == 0 || fitSize.height == 0) continue;
|
||||
|
||||
if (fitSize.width == 0 || fitSize.height == 0)
|
||||
continue;
|
||||
actualSize.size = fitSize;
|
||||
|
||||
if (constrainSize.width <= 0) {
|
||||
|
||||
if (constrainSize.width <= 0)
|
||||
{
|
||||
constrainSize.width = fitSize.width;
|
||||
}
|
||||
if (constrainSize.height <= 0){
|
||||
if (constrainSize.height <= 0)
|
||||
{
|
||||
constrainSize.height = fitSize.height;
|
||||
}
|
||||
if(fontSize <= 0){
|
||||
if (fontSize <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return CGSizeMake(actualSize.size.width, actualSize.size.height);
|
||||
}
|
||||
|
||||
static NSFont* _createSystemFont(const char* fontName, int size)
|
||||
{
|
||||
NSString * fntName = [NSString stringWithUTF8String:fontName];
|
||||
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
|
||||
|
||||
NSString* fntName = [NSString stringWithUTF8String:fontName];
|
||||
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
|
||||
|
||||
// font
|
||||
NSFont *font = [NSFont fontWithName:fntName size:size];
|
||||
|
||||
if (font == nil) {
|
||||
NSFont* font = [NSFont fontWithName:fntName size:size];
|
||||
|
||||
if (font == nil)
|
||||
{
|
||||
font = [NSFont systemFontOfSize:size];
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
static CGFloat _calculateTextDrawStartHeight(cocos2d::Device::TextAlign align, CGSize realDimensions, CGSize dimensions)
|
||||
{
|
||||
float startH = 0;
|
||||
// vertical alignment
|
||||
unsigned int vAlignment = ((int)align >> 4) & 0x0F;
|
||||
switch (vAlignment) {
|
||||
//bottom
|
||||
case 1:startH = dimensions.height - realDimensions.height;break;
|
||||
//top
|
||||
case 2:startH = 0;break;
|
||||
//center
|
||||
case 3: startH = (dimensions.height - realDimensions.height) / 2;break;
|
||||
default:
|
||||
break;
|
||||
switch (vAlignment)
|
||||
{
|
||||
// bottom
|
||||
case 1:
|
||||
startH = dimensions.height - realDimensions.height;
|
||||
break;
|
||||
// top
|
||||
case 2:
|
||||
startH = 0;
|
||||
break;
|
||||
// center
|
||||
case 3:
|
||||
startH = (dimensions.height - realDimensions.height) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return startH;
|
||||
}
|
||||
|
||||
static bool _initWithString(const char * text, Device::TextAlign align, const char * fontName, int size, tImageInfo* info, const Color3B* fontColor, int fontAlpha, bool enableWrap, int overflow, const FontStroke &stroke)
|
||||
static bool _initWithString(const char* text,
|
||||
Device::TextAlign align,
|
||||
const char* fontName,
|
||||
int size,
|
||||
tImageInfo* info,
|
||||
const Color3B* fontColor,
|
||||
int fontAlpha,
|
||||
bool enableWrap,
|
||||
int overflow,
|
||||
const FontStroke& stroke)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
|
||||
CCASSERT(text, "Invalid text");
|
||||
CCASSERT(info, "Invalid info");
|
||||
|
||||
do {
|
||||
NSString * string = [NSString stringWithUTF8String:text];
|
||||
|
||||
do
|
||||
{
|
||||
NSString* string = [NSString stringWithUTF8String:text];
|
||||
CC_BREAK_IF(!string);
|
||||
|
||||
|
||||
id font = _createSystemFont(fontName, size);
|
||||
CC_BREAK_IF(!font);
|
||||
|
||||
|
||||
// color
|
||||
NSColor* foregroundColor;
|
||||
if (fontColor) {
|
||||
foregroundColor = [NSColor colorWithDeviceRed:fontColor->r/255.0
|
||||
green:fontColor->g/255.0
|
||||
blue:fontColor->b/255.0
|
||||
alpha:fontAlpha/255.0];
|
||||
} else {
|
||||
if (fontColor)
|
||||
{
|
||||
foregroundColor = [NSColor colorWithDeviceRed:fontColor->r / 255.0
|
||||
green:fontColor->g / 255.0
|
||||
blue:fontColor->b / 255.0
|
||||
alpha:fontAlpha / 255.0];
|
||||
}
|
||||
else
|
||||
{
|
||||
foregroundColor = [NSColor whiteColor];
|
||||
}
|
||||
|
||||
|
||||
// alignment
|
||||
NSTextAlignment textAlign = FontUtils::_calculateTextAlignment(align);
|
||||
NSMutableParagraphStyle *paragraphStyle = FontUtils::_calculateParagraphStyle(enableWrap, overflow);
|
||||
NSTextAlignment textAlign = FontUtils::_calculateTextAlignment(align);
|
||||
NSMutableParagraphStyle* paragraphStyle = FontUtils::_calculateParagraphStyle(enableWrap, overflow);
|
||||
[paragraphStyle setAlignment:textAlign];
|
||||
|
||||
|
||||
// attribute
|
||||
NSDictionary* tokenAttributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
foregroundColor,NSForegroundColorAttributeName,
|
||||
font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
||||
NSAttributedString *stringWithAttributes =[[[NSAttributedString alloc] initWithString:string
|
||||
attributes:tokenAttributesDict] autorelease];
|
||||
|
||||
NSDictionary* tokenAttributesDict = [NSDictionary
|
||||
dictionaryWithObjectsAndKeys:foregroundColor, NSForegroundColorAttributeName, font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, nil];
|
||||
NSAttributedString* stringWithAttributes =
|
||||
[[[NSAttributedString alloc] initWithString:string attributes:tokenAttributesDict] autorelease];
|
||||
|
||||
CGSize dimensions = CGSizeMake(info->width, info->height);
|
||||
|
||||
NSSize realDimensions;
|
||||
|
||||
|
||||
if (overflow == 2)
|
||||
realDimensions = _calculateRealSizeForString(&stringWithAttributes, font, dimensions, enableWrap);
|
||||
else
|
||||
realDimensions = _calculateStringSize(stringWithAttributes, font, &dimensions, enableWrap, overflow);
|
||||
realDimensions = _calculateStringSize(stringWithAttributes, font, &dimensions, enableWrap, overflow);
|
||||
|
||||
// Mac crashes if the width or height is 0
|
||||
CC_BREAK_IF(realDimensions.width <= 0 || realDimensions.height <= 0);
|
||||
|
||||
if(dimensions.width <= 0.f)
|
||||
|
||||
if (dimensions.width <= 0.f)
|
||||
dimensions.width = realDimensions.width;
|
||||
if (dimensions.height <= 0.f)
|
||||
dimensions.height = realDimensions.height;
|
||||
|
||||
//Alignment
|
||||
dimensions.height = realDimensions.height;
|
||||
|
||||
// Alignment
|
||||
CGFloat xPadding = FontUtils::_calculateTextDrawStartWidth(align, realDimensions, dimensions);
|
||||
|
||||
CGFloat yPadding = _calculateTextDrawStartHeight(align, realDimensions, dimensions);
|
||||
|
||||
NSInteger POTWide = dimensions.width;
|
||||
NSInteger POTHigh = dimensions.height;
|
||||
NSRect textRect = NSMakeRect(xPadding, POTHigh - dimensions.height + yPadding,
|
||||
realDimensions.width, realDimensions.height);
|
||||
NSRect textRect =
|
||||
NSMakeRect(xPadding, POTHigh - dimensions.height + yPadding, realDimensions.width, realDimensions.height);
|
||||
|
||||
NSBitmapImageRep* offscreenRep = [[[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes:NULL
|
||||
pixelsWide:POTWide
|
||||
pixelsHigh:POTHigh
|
||||
bitsPerSample:8
|
||||
samplesPerPixel:4
|
||||
hasAlpha:YES
|
||||
isPlanar:NO
|
||||
colorSpaceName:NSDeviceRGBColorSpace
|
||||
bitmapFormat: 0
|
||||
bytesPerRow:4 * POTWide
|
||||
bitsPerPixel:32] autorelease];
|
||||
NSBitmapImageRep* offscreenRep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||
pixelsWide:POTWide
|
||||
pixelsHigh:POTHigh
|
||||
bitsPerSample:8
|
||||
samplesPerPixel:4
|
||||
hasAlpha:YES
|
||||
isPlanar:NO
|
||||
colorSpaceName:NSDeviceRGBColorSpace
|
||||
bitmapFormat:0
|
||||
bytesPerRow:4 * POTWide
|
||||
bitsPerPixel:32] autorelease];
|
||||
|
||||
NSGraphicsContext* g = [NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep];
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext:g];
|
||||
|
||||
if (stroke._strokeSize > 0) {
|
||||
NSColor *strokeColor = [NSColor colorWithDeviceRed:stroke._strokeColor.r/255.0
|
||||
green:stroke._strokeColor.g/255.0
|
||||
blue:stroke._strokeColor.b/255.0
|
||||
alpha:stroke._strokeAlpha/255.0];
|
||||
NSNumber *strokeSize = [NSNumber numberWithFloat:stroke._strokeSize / size * 100.0];
|
||||
NSDictionary *tokenAttributesDict2 = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
foregroundColor,NSForegroundColorAttributeName,
|
||||
font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName,
|
||||
strokeSize, NSStrokeWidthAttributeName,
|
||||
strokeColor, NSStrokeColorAttributeName,
|
||||
nil];
|
||||
NSAttributedString *strokeString = [[[NSAttributedString alloc] initWithString:string
|
||||
attributes:tokenAttributesDict2] autorelease];
|
||||
|
||||
if (stroke._strokeSize > 0)
|
||||
{
|
||||
NSColor* strokeColor = [NSColor colorWithDeviceRed:stroke._strokeColor.r / 255.0
|
||||
green:stroke._strokeColor.g / 255.0
|
||||
blue:stroke._strokeColor.b / 255.0
|
||||
alpha:stroke._strokeAlpha / 255.0];
|
||||
NSNumber* strokeSize = [NSNumber numberWithFloat:stroke._strokeSize / size * 100.0];
|
||||
NSDictionary* tokenAttributesDict2 = [NSDictionary
|
||||
dictionaryWithObjectsAndKeys:foregroundColor, NSForegroundColorAttributeName, font, NSFontAttributeName,
|
||||
paragraphStyle, NSParagraphStyleAttributeName, strokeSize,
|
||||
NSStrokeWidthAttributeName, strokeColor, NSStrokeColorAttributeName, nil];
|
||||
NSAttributedString* strokeString =
|
||||
[[[NSAttributedString alloc] initWithString:string attributes:tokenAttributesDict2] autorelease];
|
||||
[strokeString drawInRect:textRect];
|
||||
}
|
||||
|
||||
|
||||
[stringWithAttributes drawInRect:textRect];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
auto data = (unsigned char*) [offscreenRep bitmapData]; //Use the same buffer to improve the performance.
|
||||
auto data = (unsigned char*)[offscreenRep bitmapData]; // Use the same buffer to improve the performance.
|
||||
|
||||
NSUInteger textureSize = POTWide * POTHigh * 4;
|
||||
auto dataNew = (unsigned char*)malloc(sizeof(unsigned char) * textureSize);
|
||||
if (dataNew) {
|
||||
auto dataNew = (unsigned char*)malloc(sizeof(unsigned char) * textureSize);
|
||||
if (dataNew)
|
||||
{
|
||||
memcpy(dataNew, data, textureSize);
|
||||
// output params
|
||||
info->width = static_cast<int>(POTWide);
|
||||
info->height = static_cast<int>(POTHigh);
|
||||
info->data = dataNew;
|
||||
info->hasAlpha = true;
|
||||
info->width = static_cast<int>(POTWide);
|
||||
info->height = static_cast<int>(POTHigh);
|
||||
info->data = dataNew;
|
||||
info->hasAlpha = true;
|
||||
info->isPremultipliedAlpha = true;
|
||||
ret = true;
|
||||
ret = true;
|
||||
}
|
||||
} while (0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Data Device::getTextureDataForText(const char * text, const FontDefinition& textDefinition, TextAlign align, int &width, int &height, bool& hasPremultipliedAlpha)
|
||||
Data Device::getTextureDataForText(const char* text,
|
||||
const FontDefinition& textDefinition,
|
||||
TextAlign align,
|
||||
int& width,
|
||||
int& height,
|
||||
bool& hasPremultipliedAlpha)
|
||||
{
|
||||
Data ret;
|
||||
do {
|
||||
do
|
||||
{
|
||||
tImageInfo info = {0};
|
||||
info.width = textDefinition._dimensions.width;
|
||||
info.height = textDefinition._dimensions.height;
|
||||
info.width = textDefinition._dimensions.width;
|
||||
info.height = textDefinition._dimensions.height;
|
||||
|
||||
if (! _initWithString(text, align, textDefinition._fontName.c_str(), textDefinition._fontSize, &info, &textDefinition._fontFillColor, textDefinition._fontAlpha, textDefinition._enableWrap, textDefinition._overflow, textDefinition._stroke))
|
||||
if (!_initWithString(text, align, textDefinition._fontName.c_str(), textDefinition._fontSize, &info,
|
||||
&textDefinition._fontFillColor, textDefinition._fontAlpha, textDefinition._enableWrap,
|
||||
textDefinition._overflow, textDefinition._stroke))
|
||||
{
|
||||
break;
|
||||
}
|
||||
height = (short)info.height;
|
||||
width = (short)info.width;
|
||||
ret.fastSet(info.data,width * height * 4);
|
||||
width = (short)info.width;
|
||||
ret.fastSet(info.data, width * height * 4);
|
||||
hasPremultipliedAlpha = true;
|
||||
} while (0);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Device::setKeepScreenOn(bool value)
|
||||
{
|
||||
}
|
||||
void Device::setKeepScreenOn(bool value) {}
|
||||
|
||||
void Device::vibrate(float duration)
|
||||
{
|
||||
}
|
||||
void Device::vibrate(float duration) {}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -40,7 +40,7 @@ THE SOFTWARE.
|
|||
#include "base/ccUTF8.h"
|
||||
#include "2d/CCCamera.h"
|
||||
#if CC_ICON_SET_SUPPORT
|
||||
#include "platform/CCImage.h"
|
||||
# include "platform/CCImage.h"
|
||||
#endif /* CC_ICON_SET_SUPPORT */
|
||||
#include "renderer/backend/metal/DeviceMTL.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
|
@ -100,16 +100,13 @@ public:
|
|||
// _view->onGLFWframebufferSize(window, w, h);
|
||||
// }
|
||||
|
||||
static void onGLFWWindowSizeCallback(GLFWwindow *window, int width, int height)
|
||||
static void onGLFWWindowSizeCallback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
if (_view)
|
||||
_view->onGLFWWindowSizeCallback(window, width, height);
|
||||
}
|
||||
|
||||
static void setGLViewImpl(GLViewImpl* view)
|
||||
{
|
||||
_view = view;
|
||||
}
|
||||
static void setGLViewImpl(GLViewImpl* view) { _view = view; }
|
||||
|
||||
static void onGLFWWindowIconifyCallback(GLFWwindow* window, int iconified)
|
||||
{
|
||||
|
@ -132,8 +129,8 @@ private:
|
|||
};
|
||||
GLViewImpl* GLFWEventHandler::_view = nullptr;
|
||||
|
||||
const std::string GLViewImpl::EVENT_WINDOW_RESIZED = "glview_window_resized";
|
||||
const std::string GLViewImpl::EVENT_WINDOW_FOCUSED = "glview_window_focused";
|
||||
const std::string GLViewImpl::EVENT_WINDOW_RESIZED = "glview_window_resized";
|
||||
const std::string GLViewImpl::EVENT_WINDOW_FOCUSED = "glview_window_focused";
|
||||
const std::string GLViewImpl::EVENT_WINDOW_UNFOCUSED = "glview_window_unfocused";
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -148,149 +145,147 @@ static std::unordered_map<int, EventKeyboard::KeyCode> g_keyCodeMap;
|
|||
|
||||
static keyCodeItem g_keyCodeStructArray[] = {
|
||||
/* The unknown key */
|
||||
{ GLFW_KEY_UNKNOWN , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{GLFW_KEY_UNKNOWN, EventKeyboard::KeyCode::KEY_NONE},
|
||||
|
||||
/* Printable keys */
|
||||
{ GLFW_KEY_SPACE , EventKeyboard::KeyCode::KEY_SPACE },
|
||||
{ GLFW_KEY_APOSTROPHE , EventKeyboard::KeyCode::KEY_APOSTROPHE },
|
||||
{ GLFW_KEY_COMMA , EventKeyboard::KeyCode::KEY_COMMA },
|
||||
{ GLFW_KEY_MINUS , EventKeyboard::KeyCode::KEY_MINUS },
|
||||
{ GLFW_KEY_PERIOD , EventKeyboard::KeyCode::KEY_PERIOD },
|
||||
{ GLFW_KEY_SLASH , EventKeyboard::KeyCode::KEY_SLASH },
|
||||
{ GLFW_KEY_0 , EventKeyboard::KeyCode::KEY_0 },
|
||||
{ GLFW_KEY_1 , EventKeyboard::KeyCode::KEY_1 },
|
||||
{ GLFW_KEY_2 , EventKeyboard::KeyCode::KEY_2 },
|
||||
{ GLFW_KEY_3 , EventKeyboard::KeyCode::KEY_3 },
|
||||
{ GLFW_KEY_4 , EventKeyboard::KeyCode::KEY_4 },
|
||||
{ GLFW_KEY_5 , EventKeyboard::KeyCode::KEY_5 },
|
||||
{ GLFW_KEY_6 , EventKeyboard::KeyCode::KEY_6 },
|
||||
{ GLFW_KEY_7 , EventKeyboard::KeyCode::KEY_7 },
|
||||
{ GLFW_KEY_8 , EventKeyboard::KeyCode::KEY_8 },
|
||||
{ GLFW_KEY_9 , EventKeyboard::KeyCode::KEY_9 },
|
||||
{ GLFW_KEY_SEMICOLON , EventKeyboard::KeyCode::KEY_SEMICOLON },
|
||||
{ GLFW_KEY_EQUAL , EventKeyboard::KeyCode::KEY_EQUAL },
|
||||
{ GLFW_KEY_A , EventKeyboard::KeyCode::KEY_A },
|
||||
{ GLFW_KEY_B , EventKeyboard::KeyCode::KEY_B },
|
||||
{ GLFW_KEY_C , EventKeyboard::KeyCode::KEY_C },
|
||||
{ GLFW_KEY_D , EventKeyboard::KeyCode::KEY_D },
|
||||
{ GLFW_KEY_E , EventKeyboard::KeyCode::KEY_E },
|
||||
{ GLFW_KEY_F , EventKeyboard::KeyCode::KEY_F },
|
||||
{ GLFW_KEY_G , EventKeyboard::KeyCode::KEY_G },
|
||||
{ GLFW_KEY_H , EventKeyboard::KeyCode::KEY_H },
|
||||
{ GLFW_KEY_I , EventKeyboard::KeyCode::KEY_I },
|
||||
{ GLFW_KEY_J , EventKeyboard::KeyCode::KEY_J },
|
||||
{ GLFW_KEY_K , EventKeyboard::KeyCode::KEY_K },
|
||||
{ GLFW_KEY_L , EventKeyboard::KeyCode::KEY_L },
|
||||
{ GLFW_KEY_M , EventKeyboard::KeyCode::KEY_M },
|
||||
{ GLFW_KEY_N , EventKeyboard::KeyCode::KEY_N },
|
||||
{ GLFW_KEY_O , EventKeyboard::KeyCode::KEY_O },
|
||||
{ GLFW_KEY_P , EventKeyboard::KeyCode::KEY_P },
|
||||
{ GLFW_KEY_Q , EventKeyboard::KeyCode::KEY_Q },
|
||||
{ GLFW_KEY_R , EventKeyboard::KeyCode::KEY_R },
|
||||
{ GLFW_KEY_S , EventKeyboard::KeyCode::KEY_S },
|
||||
{ GLFW_KEY_T , EventKeyboard::KeyCode::KEY_T },
|
||||
{ GLFW_KEY_U , EventKeyboard::KeyCode::KEY_U },
|
||||
{ GLFW_KEY_V , EventKeyboard::KeyCode::KEY_V },
|
||||
{ GLFW_KEY_W , EventKeyboard::KeyCode::KEY_W },
|
||||
{ GLFW_KEY_X , EventKeyboard::KeyCode::KEY_X },
|
||||
{ GLFW_KEY_Y , EventKeyboard::KeyCode::KEY_Y },
|
||||
{ GLFW_KEY_Z , EventKeyboard::KeyCode::KEY_Z },
|
||||
{ GLFW_KEY_LEFT_BRACKET , EventKeyboard::KeyCode::KEY_LEFT_BRACKET },
|
||||
{ GLFW_KEY_BACKSLASH , EventKeyboard::KeyCode::KEY_BACK_SLASH },
|
||||
{ GLFW_KEY_RIGHT_BRACKET , EventKeyboard::KeyCode::KEY_RIGHT_BRACKET },
|
||||
{ GLFW_KEY_GRAVE_ACCENT , EventKeyboard::KeyCode::KEY_GRAVE },
|
||||
{ GLFW_KEY_WORLD_1 , EventKeyboard::KeyCode::KEY_GRAVE },
|
||||
{ GLFW_KEY_WORLD_2 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{GLFW_KEY_SPACE, EventKeyboard::KeyCode::KEY_SPACE},
|
||||
{GLFW_KEY_APOSTROPHE, EventKeyboard::KeyCode::KEY_APOSTROPHE},
|
||||
{GLFW_KEY_COMMA, EventKeyboard::KeyCode::KEY_COMMA},
|
||||
{GLFW_KEY_MINUS, EventKeyboard::KeyCode::KEY_MINUS},
|
||||
{GLFW_KEY_PERIOD, EventKeyboard::KeyCode::KEY_PERIOD},
|
||||
{GLFW_KEY_SLASH, EventKeyboard::KeyCode::KEY_SLASH},
|
||||
{GLFW_KEY_0, EventKeyboard::KeyCode::KEY_0},
|
||||
{GLFW_KEY_1, EventKeyboard::KeyCode::KEY_1},
|
||||
{GLFW_KEY_2, EventKeyboard::KeyCode::KEY_2},
|
||||
{GLFW_KEY_3, EventKeyboard::KeyCode::KEY_3},
|
||||
{GLFW_KEY_4, EventKeyboard::KeyCode::KEY_4},
|
||||
{GLFW_KEY_5, EventKeyboard::KeyCode::KEY_5},
|
||||
{GLFW_KEY_6, EventKeyboard::KeyCode::KEY_6},
|
||||
{GLFW_KEY_7, EventKeyboard::KeyCode::KEY_7},
|
||||
{GLFW_KEY_8, EventKeyboard::KeyCode::KEY_8},
|
||||
{GLFW_KEY_9, EventKeyboard::KeyCode::KEY_9},
|
||||
{GLFW_KEY_SEMICOLON, EventKeyboard::KeyCode::KEY_SEMICOLON},
|
||||
{GLFW_KEY_EQUAL, EventKeyboard::KeyCode::KEY_EQUAL},
|
||||
{GLFW_KEY_A, EventKeyboard::KeyCode::KEY_A},
|
||||
{GLFW_KEY_B, EventKeyboard::KeyCode::KEY_B},
|
||||
{GLFW_KEY_C, EventKeyboard::KeyCode::KEY_C},
|
||||
{GLFW_KEY_D, EventKeyboard::KeyCode::KEY_D},
|
||||
{GLFW_KEY_E, EventKeyboard::KeyCode::KEY_E},
|
||||
{GLFW_KEY_F, EventKeyboard::KeyCode::KEY_F},
|
||||
{GLFW_KEY_G, EventKeyboard::KeyCode::KEY_G},
|
||||
{GLFW_KEY_H, EventKeyboard::KeyCode::KEY_H},
|
||||
{GLFW_KEY_I, EventKeyboard::KeyCode::KEY_I},
|
||||
{GLFW_KEY_J, EventKeyboard::KeyCode::KEY_J},
|
||||
{GLFW_KEY_K, EventKeyboard::KeyCode::KEY_K},
|
||||
{GLFW_KEY_L, EventKeyboard::KeyCode::KEY_L},
|
||||
{GLFW_KEY_M, EventKeyboard::KeyCode::KEY_M},
|
||||
{GLFW_KEY_N, EventKeyboard::KeyCode::KEY_N},
|
||||
{GLFW_KEY_O, EventKeyboard::KeyCode::KEY_O},
|
||||
{GLFW_KEY_P, EventKeyboard::KeyCode::KEY_P},
|
||||
{GLFW_KEY_Q, EventKeyboard::KeyCode::KEY_Q},
|
||||
{GLFW_KEY_R, EventKeyboard::KeyCode::KEY_R},
|
||||
{GLFW_KEY_S, EventKeyboard::KeyCode::KEY_S},
|
||||
{GLFW_KEY_T, EventKeyboard::KeyCode::KEY_T},
|
||||
{GLFW_KEY_U, EventKeyboard::KeyCode::KEY_U},
|
||||
{GLFW_KEY_V, EventKeyboard::KeyCode::KEY_V},
|
||||
{GLFW_KEY_W, EventKeyboard::KeyCode::KEY_W},
|
||||
{GLFW_KEY_X, EventKeyboard::KeyCode::KEY_X},
|
||||
{GLFW_KEY_Y, EventKeyboard::KeyCode::KEY_Y},
|
||||
{GLFW_KEY_Z, EventKeyboard::KeyCode::KEY_Z},
|
||||
{GLFW_KEY_LEFT_BRACKET, EventKeyboard::KeyCode::KEY_LEFT_BRACKET},
|
||||
{GLFW_KEY_BACKSLASH, EventKeyboard::KeyCode::KEY_BACK_SLASH},
|
||||
{GLFW_KEY_RIGHT_BRACKET, EventKeyboard::KeyCode::KEY_RIGHT_BRACKET},
|
||||
{GLFW_KEY_GRAVE_ACCENT, EventKeyboard::KeyCode::KEY_GRAVE},
|
||||
{GLFW_KEY_WORLD_1, EventKeyboard::KeyCode::KEY_GRAVE},
|
||||
{GLFW_KEY_WORLD_2, EventKeyboard::KeyCode::KEY_NONE},
|
||||
|
||||
/* Function keys */
|
||||
{ GLFW_KEY_ESCAPE , EventKeyboard::KeyCode::KEY_ESCAPE },
|
||||
{ GLFW_KEY_ENTER , EventKeyboard::KeyCode::KEY_ENTER },
|
||||
{ GLFW_KEY_TAB , EventKeyboard::KeyCode::KEY_TAB },
|
||||
{ GLFW_KEY_BACKSPACE , EventKeyboard::KeyCode::KEY_BACKSPACE },
|
||||
{ GLFW_KEY_INSERT , EventKeyboard::KeyCode::KEY_INSERT },
|
||||
{ GLFW_KEY_DELETE , EventKeyboard::KeyCode::KEY_DELETE },
|
||||
{ GLFW_KEY_RIGHT , EventKeyboard::KeyCode::KEY_RIGHT_ARROW },
|
||||
{ GLFW_KEY_LEFT , EventKeyboard::KeyCode::KEY_LEFT_ARROW },
|
||||
{ GLFW_KEY_DOWN , EventKeyboard::KeyCode::KEY_DOWN_ARROW },
|
||||
{ GLFW_KEY_UP , EventKeyboard::KeyCode::KEY_UP_ARROW },
|
||||
{ GLFW_KEY_PAGE_UP , EventKeyboard::KeyCode::KEY_PG_UP },
|
||||
{ GLFW_KEY_PAGE_DOWN , EventKeyboard::KeyCode::KEY_PG_DOWN },
|
||||
{ GLFW_KEY_HOME , EventKeyboard::KeyCode::KEY_HOME },
|
||||
{ GLFW_KEY_END , EventKeyboard::KeyCode::KEY_END },
|
||||
{ GLFW_KEY_CAPS_LOCK , EventKeyboard::KeyCode::KEY_CAPS_LOCK },
|
||||
{ GLFW_KEY_SCROLL_LOCK , EventKeyboard::KeyCode::KEY_SCROLL_LOCK },
|
||||
{ GLFW_KEY_NUM_LOCK , EventKeyboard::KeyCode::KEY_NUM_LOCK },
|
||||
{ GLFW_KEY_PRINT_SCREEN , EventKeyboard::KeyCode::KEY_PRINT },
|
||||
{ GLFW_KEY_PAUSE , EventKeyboard::KeyCode::KEY_PAUSE },
|
||||
{ GLFW_KEY_F1 , EventKeyboard::KeyCode::KEY_F1 },
|
||||
{ GLFW_KEY_F2 , EventKeyboard::KeyCode::KEY_F2 },
|
||||
{ GLFW_KEY_F3 , EventKeyboard::KeyCode::KEY_F3 },
|
||||
{ GLFW_KEY_F4 , EventKeyboard::KeyCode::KEY_F4 },
|
||||
{ GLFW_KEY_F5 , EventKeyboard::KeyCode::KEY_F5 },
|
||||
{ GLFW_KEY_F6 , EventKeyboard::KeyCode::KEY_F6 },
|
||||
{ GLFW_KEY_F7 , EventKeyboard::KeyCode::KEY_F7 },
|
||||
{ GLFW_KEY_F8 , EventKeyboard::KeyCode::KEY_F8 },
|
||||
{ GLFW_KEY_F9 , EventKeyboard::KeyCode::KEY_F9 },
|
||||
{ GLFW_KEY_F10 , EventKeyboard::KeyCode::KEY_F10 },
|
||||
{ GLFW_KEY_F11 , EventKeyboard::KeyCode::KEY_F11 },
|
||||
{ GLFW_KEY_F12 , EventKeyboard::KeyCode::KEY_F12 },
|
||||
{ GLFW_KEY_F13 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F14 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F15 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F16 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F17 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F18 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F19 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F20 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F21 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F22 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F23 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F24 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_F25 , EventKeyboard::KeyCode::KEY_NONE },
|
||||
{ GLFW_KEY_KP_0 , EventKeyboard::KeyCode::KEY_0 },
|
||||
{ GLFW_KEY_KP_1 , EventKeyboard::KeyCode::KEY_1 },
|
||||
{ GLFW_KEY_KP_2 , EventKeyboard::KeyCode::KEY_2 },
|
||||
{ GLFW_KEY_KP_3 , EventKeyboard::KeyCode::KEY_3 },
|
||||
{ GLFW_KEY_KP_4 , EventKeyboard::KeyCode::KEY_4 },
|
||||
{ GLFW_KEY_KP_5 , EventKeyboard::KeyCode::KEY_5 },
|
||||
{ GLFW_KEY_KP_6 , EventKeyboard::KeyCode::KEY_6 },
|
||||
{ GLFW_KEY_KP_7 , EventKeyboard::KeyCode::KEY_7 },
|
||||
{ GLFW_KEY_KP_8 , EventKeyboard::KeyCode::KEY_8 },
|
||||
{ GLFW_KEY_KP_9 , EventKeyboard::KeyCode::KEY_9 },
|
||||
{ GLFW_KEY_KP_DECIMAL , EventKeyboard::KeyCode::KEY_PERIOD },
|
||||
{ GLFW_KEY_KP_DIVIDE , EventKeyboard::KeyCode::KEY_KP_DIVIDE },
|
||||
{ GLFW_KEY_KP_MULTIPLY , EventKeyboard::KeyCode::KEY_KP_MULTIPLY },
|
||||
{ GLFW_KEY_KP_SUBTRACT , EventKeyboard::KeyCode::KEY_KP_MINUS },
|
||||
{ GLFW_KEY_KP_ADD , EventKeyboard::KeyCode::KEY_KP_PLUS },
|
||||
{ GLFW_KEY_KP_ENTER , EventKeyboard::KeyCode::KEY_KP_ENTER },
|
||||
{ GLFW_KEY_KP_EQUAL , EventKeyboard::KeyCode::KEY_EQUAL },
|
||||
{ GLFW_KEY_LEFT_SHIFT , EventKeyboard::KeyCode::KEY_LEFT_SHIFT },
|
||||
{ GLFW_KEY_LEFT_CONTROL , EventKeyboard::KeyCode::KEY_LEFT_CTRL },
|
||||
{ GLFW_KEY_LEFT_ALT , EventKeyboard::KeyCode::KEY_LEFT_ALT },
|
||||
{ GLFW_KEY_LEFT_SUPER , EventKeyboard::KeyCode::KEY_HYPER },
|
||||
{ GLFW_KEY_RIGHT_SHIFT , EventKeyboard::KeyCode::KEY_RIGHT_SHIFT },
|
||||
{ GLFW_KEY_RIGHT_CONTROL , EventKeyboard::KeyCode::KEY_RIGHT_CTRL },
|
||||
{ GLFW_KEY_RIGHT_ALT , EventKeyboard::KeyCode::KEY_RIGHT_ALT },
|
||||
{ GLFW_KEY_RIGHT_SUPER , EventKeyboard::KeyCode::KEY_HYPER },
|
||||
{ GLFW_KEY_MENU , EventKeyboard::KeyCode::KEY_MENU },
|
||||
{ GLFW_KEY_LAST , EventKeyboard::KeyCode::KEY_NONE }
|
||||
};
|
||||
{GLFW_KEY_ESCAPE, EventKeyboard::KeyCode::KEY_ESCAPE},
|
||||
{GLFW_KEY_ENTER, EventKeyboard::KeyCode::KEY_ENTER},
|
||||
{GLFW_KEY_TAB, EventKeyboard::KeyCode::KEY_TAB},
|
||||
{GLFW_KEY_BACKSPACE, EventKeyboard::KeyCode::KEY_BACKSPACE},
|
||||
{GLFW_KEY_INSERT, EventKeyboard::KeyCode::KEY_INSERT},
|
||||
{GLFW_KEY_DELETE, EventKeyboard::KeyCode::KEY_DELETE},
|
||||
{GLFW_KEY_RIGHT, EventKeyboard::KeyCode::KEY_RIGHT_ARROW},
|
||||
{GLFW_KEY_LEFT, EventKeyboard::KeyCode::KEY_LEFT_ARROW},
|
||||
{GLFW_KEY_DOWN, EventKeyboard::KeyCode::KEY_DOWN_ARROW},
|
||||
{GLFW_KEY_UP, EventKeyboard::KeyCode::KEY_UP_ARROW},
|
||||
{GLFW_KEY_PAGE_UP, EventKeyboard::KeyCode::KEY_PG_UP},
|
||||
{GLFW_KEY_PAGE_DOWN, EventKeyboard::KeyCode::KEY_PG_DOWN},
|
||||
{GLFW_KEY_HOME, EventKeyboard::KeyCode::KEY_HOME},
|
||||
{GLFW_KEY_END, EventKeyboard::KeyCode::KEY_END},
|
||||
{GLFW_KEY_CAPS_LOCK, EventKeyboard::KeyCode::KEY_CAPS_LOCK},
|
||||
{GLFW_KEY_SCROLL_LOCK, EventKeyboard::KeyCode::KEY_SCROLL_LOCK},
|
||||
{GLFW_KEY_NUM_LOCK, EventKeyboard::KeyCode::KEY_NUM_LOCK},
|
||||
{GLFW_KEY_PRINT_SCREEN, EventKeyboard::KeyCode::KEY_PRINT},
|
||||
{GLFW_KEY_PAUSE, EventKeyboard::KeyCode::KEY_PAUSE},
|
||||
{GLFW_KEY_F1, EventKeyboard::KeyCode::KEY_F1},
|
||||
{GLFW_KEY_F2, EventKeyboard::KeyCode::KEY_F2},
|
||||
{GLFW_KEY_F3, EventKeyboard::KeyCode::KEY_F3},
|
||||
{GLFW_KEY_F4, EventKeyboard::KeyCode::KEY_F4},
|
||||
{GLFW_KEY_F5, EventKeyboard::KeyCode::KEY_F5},
|
||||
{GLFW_KEY_F6, EventKeyboard::KeyCode::KEY_F6},
|
||||
{GLFW_KEY_F7, EventKeyboard::KeyCode::KEY_F7},
|
||||
{GLFW_KEY_F8, EventKeyboard::KeyCode::KEY_F8},
|
||||
{GLFW_KEY_F9, EventKeyboard::KeyCode::KEY_F9},
|
||||
{GLFW_KEY_F10, EventKeyboard::KeyCode::KEY_F10},
|
||||
{GLFW_KEY_F11, EventKeyboard::KeyCode::KEY_F11},
|
||||
{GLFW_KEY_F12, EventKeyboard::KeyCode::KEY_F12},
|
||||
{GLFW_KEY_F13, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F14, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F15, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F16, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F17, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F18, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F19, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F20, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F21, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F22, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F23, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F24, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_F25, EventKeyboard::KeyCode::KEY_NONE},
|
||||
{GLFW_KEY_KP_0, EventKeyboard::KeyCode::KEY_0},
|
||||
{GLFW_KEY_KP_1, EventKeyboard::KeyCode::KEY_1},
|
||||
{GLFW_KEY_KP_2, EventKeyboard::KeyCode::KEY_2},
|
||||
{GLFW_KEY_KP_3, EventKeyboard::KeyCode::KEY_3},
|
||||
{GLFW_KEY_KP_4, EventKeyboard::KeyCode::KEY_4},
|
||||
{GLFW_KEY_KP_5, EventKeyboard::KeyCode::KEY_5},
|
||||
{GLFW_KEY_KP_6, EventKeyboard::KeyCode::KEY_6},
|
||||
{GLFW_KEY_KP_7, EventKeyboard::KeyCode::KEY_7},
|
||||
{GLFW_KEY_KP_8, EventKeyboard::KeyCode::KEY_8},
|
||||
{GLFW_KEY_KP_9, EventKeyboard::KeyCode::KEY_9},
|
||||
{GLFW_KEY_KP_DECIMAL, EventKeyboard::KeyCode::KEY_PERIOD},
|
||||
{GLFW_KEY_KP_DIVIDE, EventKeyboard::KeyCode::KEY_KP_DIVIDE},
|
||||
{GLFW_KEY_KP_MULTIPLY, EventKeyboard::KeyCode::KEY_KP_MULTIPLY},
|
||||
{GLFW_KEY_KP_SUBTRACT, EventKeyboard::KeyCode::KEY_KP_MINUS},
|
||||
{GLFW_KEY_KP_ADD, EventKeyboard::KeyCode::KEY_KP_PLUS},
|
||||
{GLFW_KEY_KP_ENTER, EventKeyboard::KeyCode::KEY_KP_ENTER},
|
||||
{GLFW_KEY_KP_EQUAL, EventKeyboard::KeyCode::KEY_EQUAL},
|
||||
{GLFW_KEY_LEFT_SHIFT, EventKeyboard::KeyCode::KEY_LEFT_SHIFT},
|
||||
{GLFW_KEY_LEFT_CONTROL, EventKeyboard::KeyCode::KEY_LEFT_CTRL},
|
||||
{GLFW_KEY_LEFT_ALT, EventKeyboard::KeyCode::KEY_LEFT_ALT},
|
||||
{GLFW_KEY_LEFT_SUPER, EventKeyboard::KeyCode::KEY_HYPER},
|
||||
{GLFW_KEY_RIGHT_SHIFT, EventKeyboard::KeyCode::KEY_RIGHT_SHIFT},
|
||||
{GLFW_KEY_RIGHT_CONTROL, EventKeyboard::KeyCode::KEY_RIGHT_CTRL},
|
||||
{GLFW_KEY_RIGHT_ALT, EventKeyboard::KeyCode::KEY_RIGHT_ALT},
|
||||
{GLFW_KEY_RIGHT_SUPER, EventKeyboard::KeyCode::KEY_HYPER},
|
||||
{GLFW_KEY_MENU, EventKeyboard::KeyCode::KEY_MENU},
|
||||
{GLFW_KEY_LAST, EventKeyboard::KeyCode::KEY_NONE}};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// implement GLViewImpl
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
GLViewImpl::GLViewImpl(bool initglfw)
|
||||
: _captured(false)
|
||||
, _isInRetinaMonitor(false)
|
||||
, _isRetinaEnabled(false)
|
||||
, _retinaFactor(1)
|
||||
, _frameZoomFactor(1.0f)
|
||||
, _mainWindow(nullptr)
|
||||
, _monitor(nullptr)
|
||||
, _mouseX(0.0f)
|
||||
, _mouseY(0.0f)
|
||||
: _captured(false)
|
||||
, _isInRetinaMonitor(false)
|
||||
, _isRetinaEnabled(false)
|
||||
, _retinaFactor(1)
|
||||
, _frameZoomFactor(1.0f)
|
||||
, _mainWindow(nullptr)
|
||||
, _monitor(nullptr)
|
||||
, _mouseX(0.0f)
|
||||
, _mouseY(0.0f)
|
||||
{
|
||||
_viewName = "cocos2dx";
|
||||
g_keyCodeMap.clear();
|
||||
|
@ -322,7 +317,8 @@ GLViewImpl* GLViewImpl::create(std::string_view viewName)
|
|||
GLViewImpl* GLViewImpl::create(std::string_view viewName, bool resizable)
|
||||
{
|
||||
auto ret = new GLViewImpl;
|
||||
if(ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1.0f, resizable)) {
|
||||
if (ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1.0f, resizable))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -333,7 +329,8 @@ GLViewImpl* GLViewImpl::create(std::string_view viewName, bool resizable)
|
|||
GLViewImpl* GLViewImpl::createWithRect(std::string_view viewName, Rect rect, float frameZoomFactor, bool resizable)
|
||||
{
|
||||
auto ret = new GLViewImpl;
|
||||
if(ret->initWithRect(viewName, rect, frameZoomFactor, resizable)) {
|
||||
if (ret->initWithRect(viewName, rect, frameZoomFactor, resizable))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -344,7 +341,8 @@ GLViewImpl* GLViewImpl::createWithRect(std::string_view viewName, Rect rect, flo
|
|||
GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName)
|
||||
{
|
||||
auto ret = new GLViewImpl();
|
||||
if(ret->initWithFullScreen(viewName)) {
|
||||
if (ret->initWithFullScreen(viewName))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -352,10 +350,13 @@ GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName, const GLFWvidmode &videoMode, GLFWmonitor *monitor)
|
||||
GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName,
|
||||
const GLFWvidmode& videoMode,
|
||||
GLFWmonitor* monitor)
|
||||
{
|
||||
auto ret = new GLViewImpl();
|
||||
if(ret->initWithFullscreen(viewName, videoMode, monitor)) {
|
||||
if (ret->initWithFullscreen(viewName, videoMode, monitor))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -369,22 +370,22 @@ bool GLViewImpl::initWithRect(std::string_view viewName, Rect rect, float frameZ
|
|||
|
||||
_frameZoomFactor = frameZoomFactor;
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE,resizable?GL_TRUE:GL_FALSE);
|
||||
glfwWindowHint(GLFW_RED_BITS,_glContextAttrs.redBits);
|
||||
glfwWindowHint(GLFW_GREEN_BITS,_glContextAttrs.greenBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS,_glContextAttrs.blueBits);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS,_glContextAttrs.alphaBits);
|
||||
glfwWindowHint(GLFW_DEPTH_BITS,_glContextAttrs.depthBits);
|
||||
glfwWindowHint(GLFW_STENCIL_BITS,_glContextAttrs.stencilBits);
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, resizable ? GL_TRUE : GL_FALSE);
|
||||
glfwWindowHint(GLFW_RED_BITS, _glContextAttrs.redBits);
|
||||
glfwWindowHint(GLFW_GREEN_BITS, _glContextAttrs.greenBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, _glContextAttrs.blueBits);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, _glContextAttrs.alphaBits);
|
||||
glfwWindowHint(GLFW_DEPTH_BITS, _glContextAttrs.depthBits);
|
||||
glfwWindowHint(GLFW_STENCIL_BITS, _glContextAttrs.stencilBits);
|
||||
|
||||
glfwWindowHint(GLFW_SAMPLES, _glContextAttrs.multisamplingCount);
|
||||
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
// Don't create gl context.
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
#endif
|
||||
|
||||
int neededWidth = rect.size.width * _frameZoomFactor;
|
||||
int neededWidth = rect.size.width * _frameZoomFactor;
|
||||
int neededHeight = rect.size.height * _frameZoomFactor;
|
||||
|
||||
_mainWindow = glfwCreateWindow(neededWidth, neededHeight, _viewName.c_str(), _monitor, nullptr);
|
||||
|
@ -401,13 +402,12 @@ bool GLViewImpl::initWithRect(std::string_view viewName, Rect rect, float frameZ
|
|||
ccMessageBox(message.c_str(), "Error launch application");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int fbWidth, fbHeight;
|
||||
glfwGetFramebufferSize(_mainWindow, &fbWidth, &fbHeight);
|
||||
|
||||
|
||||
|
||||
CGSize size;
|
||||
size.width = static_cast<CGFloat>(fbWidth);
|
||||
size.width = static_cast<CGFloat>(fbWidth);
|
||||
size.height = static_cast<CGFloat>(fbHeight);
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
|
@ -420,7 +420,7 @@ bool GLViewImpl::initWithRect(std::string_view viewName, Rect rect, float frameZ
|
|||
}
|
||||
|
||||
NSView* contentView = [getCocoaWindow() contentView];
|
||||
[contentView setWantsLayer: YES];
|
||||
[contentView setWantsLayer:YES];
|
||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||
[layer setDevice:device];
|
||||
[layer setPixelFormat:MTLPixelFormatBGRA8Unorm];
|
||||
|
@ -431,15 +431,15 @@ bool GLViewImpl::initWithRect(std::string_view viewName, Rect rect, float frameZ
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Note that the created window and context may differ from what you requested,
|
||||
* as not all parameters and hints are
|
||||
* [hard constraints](@ref window_hints_hard). This includes the size of the
|
||||
* window, especially for full screen windows. To retrieve the actual
|
||||
* attributes of the created window and context, use queries like @ref
|
||||
* glfwGetWindowAttrib and @ref glfwGetWindowSize.
|
||||
*
|
||||
* see declaration glfwCreateWindow
|
||||
*/
|
||||
* Note that the created window and context may differ from what you requested,
|
||||
* as not all parameters and hints are
|
||||
* [hard constraints](@ref window_hints_hard). This includes the size of the
|
||||
* window, especially for full screen windows. To retrieve the actual
|
||||
* attributes of the created window and context, use queries like @ref
|
||||
* glfwGetWindowAttrib and @ref glfwGetWindowSize.
|
||||
*
|
||||
* see declaration glfwCreateWindow
|
||||
*/
|
||||
int realW = 0, realH = 0;
|
||||
glfwGetWindowSize(_mainWindow, &realW, &realH);
|
||||
if (realW != neededWidth)
|
||||
|
@ -472,7 +472,7 @@ bool GLViewImpl::initWithRect(std::string_view viewName, Rect rect, float frameZ
|
|||
|
||||
bool GLViewImpl::initWithFullScreen(std::string_view viewName)
|
||||
{
|
||||
//Create fullscreen window on primary monitor at its current video mode.
|
||||
// Create fullscreen window on primary monitor at its current video mode.
|
||||
_monitor = glfwGetPrimaryMonitor();
|
||||
if (nullptr == _monitor)
|
||||
return false;
|
||||
|
@ -481,19 +481,21 @@ bool GLViewImpl::initWithFullScreen(std::string_view viewName)
|
|||
return initWithRect(viewName, Rect(0, 0, (float)videoMode->width, (float)videoMode->height), 1.0f, false);
|
||||
}
|
||||
|
||||
bool GLViewImpl::initWithFullscreen(const std::string &viewname, const GLFWvidmode &videoMode, GLFWmonitor *monitor)
|
||||
bool GLViewImpl::initWithFullscreen(const std::string& viewname, const GLFWvidmode& videoMode, GLFWmonitor* monitor)
|
||||
{
|
||||
//Create fullscreen on specified monitor at the specified video mode.
|
||||
// Create fullscreen on specified monitor at the specified video mode.
|
||||
_monitor = monitor;
|
||||
if (nullptr == _monitor)
|
||||
return false;
|
||||
|
||||
//These are soft constraints. If the video mode is retrieved at runtime, the resulting window and context should match these exactly. If invalid attribs are passed (eg. from an outdated cache), window creation will NOT fail but the actual window/context may differ.
|
||||
|
||||
// These are soft constraints. If the video mode is retrieved at runtime, the resulting window and context should
|
||||
// match these exactly. If invalid attribs are passed (eg. from an outdated cache), window creation will NOT fail
|
||||
// but the actual window/context may differ.
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, videoMode.refreshRate);
|
||||
glfwWindowHint(GLFW_RED_BITS, videoMode.redBits);
|
||||
glfwWindowHint(GLFW_BLUE_BITS, videoMode.blueBits);
|
||||
glfwWindowHint(GLFW_GREEN_BITS, videoMode.greenBits);
|
||||
|
||||
|
||||
return initWithRect(viewname, Rect(0, 0, (float)videoMode.width, (float)videoMode.height), 1.0f, false);
|
||||
}
|
||||
|
||||
|
@ -504,9 +506,9 @@ bool GLViewImpl::isOpenGLReady()
|
|||
|
||||
void GLViewImpl::end()
|
||||
{
|
||||
if(_mainWindow)
|
||||
if (_mainWindow)
|
||||
{
|
||||
glfwSetWindowShouldClose(_mainWindow,1);
|
||||
glfwSetWindowShouldClose(_mainWindow, 1);
|
||||
_mainWindow = nullptr;
|
||||
}
|
||||
// Release self. Otherwise, GLViewImpl could not be freed.
|
||||
|
@ -516,14 +518,14 @@ void GLViewImpl::end()
|
|||
void GLViewImpl::swapBuffers()
|
||||
{
|
||||
#if defined(CC_USE_GL)
|
||||
if(_mainWindow)
|
||||
if (_mainWindow)
|
||||
glfwSwapBuffers(_mainWindow);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GLViewImpl::windowShouldClose()
|
||||
{
|
||||
if(_mainWindow)
|
||||
if (_mainWindow)
|
||||
return glfwWindowShouldClose(_mainWindow) ? true : false;
|
||||
else
|
||||
return true;
|
||||
|
@ -536,49 +538,54 @@ void GLViewImpl::pollEvents()
|
|||
|
||||
void GLViewImpl::enableRetina(bool enabled)
|
||||
{
|
||||
_isRetinaEnabled = enabled;
|
||||
if (_isRetinaEnabled)
|
||||
{
|
||||
_retinaFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_retinaFactor = 2;
|
||||
}
|
||||
updateFrameSize();
|
||||
_isRetinaEnabled = enabled;
|
||||
if (_isRetinaEnabled)
|
||||
{
|
||||
_retinaFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_retinaFactor = 2;
|
||||
}
|
||||
updateFrameSize();
|
||||
}
|
||||
|
||||
|
||||
void GLViewImpl::setIMEKeyboardState(bool /*bOpen*/)
|
||||
{
|
||||
|
||||
}
|
||||
void GLViewImpl::setIMEKeyboardState(bool /*bOpen*/) {}
|
||||
|
||||
#if CC_ICON_SET_SUPPORT
|
||||
void GLViewImpl::setIcon(std::string_view filename) const {
|
||||
void GLViewImpl::setIcon(std::string_view filename) const
|
||||
{
|
||||
std::vector<std::string> vec = {filename};
|
||||
this->setIcon(vec);
|
||||
}
|
||||
|
||||
void GLViewImpl::setIcon(const std::vector<std::string>& filelist) const {
|
||||
if (filelist.empty()) return;
|
||||
void GLViewImpl::setIcon(const std::vector<std::string>& filelist) const
|
||||
{
|
||||
if (filelist.empty())
|
||||
return;
|
||||
std::vector<Image*> icons;
|
||||
for (auto const& filename: filelist) {
|
||||
for (auto const& filename : filelist)
|
||||
{
|
||||
Image* icon = new Image();
|
||||
if (icon->initWithImageFile(filename)) {
|
||||
if (icon->initWithImageFile(filename))
|
||||
{
|
||||
icons.push_back(icon);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
CC_SAFE_DELETE(icon);
|
||||
}
|
||||
}
|
||||
|
||||
if (icons.empty()) return; // No valid images
|
||||
if (icons.empty())
|
||||
return; // No valid images
|
||||
size_t iconsCount = icons.size();
|
||||
auto images = new GLFWimage[iconsCount];
|
||||
for (size_t i = 0; i < iconsCount; i++) {
|
||||
auto& image = images[i];
|
||||
auto& icon = icons[i];
|
||||
image.width = icon->getWidth();
|
||||
auto images = new GLFWimage[iconsCount];
|
||||
for (size_t i = 0; i < iconsCount; i++)
|
||||
{
|
||||
auto& image = images[i];
|
||||
auto& icon = icons[i];
|
||||
image.width = icon->getWidth();
|
||||
image.height = icon->getHeight();
|
||||
image.pixels = icon->getData();
|
||||
};
|
||||
|
@ -587,23 +594,25 @@ void GLViewImpl::setIcon(const std::vector<std::string>& filelist) const {
|
|||
glfwSetWindowIcon(window, iconsCount, images);
|
||||
|
||||
CC_SAFE_DELETE_ARRAY(images);
|
||||
for (auto& icon: icons) {
|
||||
for (auto& icon : icons)
|
||||
{
|
||||
CC_SAFE_DELETE(icon);
|
||||
}
|
||||
}
|
||||
|
||||
void GLViewImpl::setDefaultIcon() const {
|
||||
void GLViewImpl::setDefaultIcon() const
|
||||
{
|
||||
GLFWwindow* window = this->getWindow();
|
||||
glfwSetWindowIcon(window, 0, nullptr);
|
||||
}
|
||||
#endif /* CC_ICON_SET_SUPPORT */
|
||||
|
||||
void GLViewImpl::setCursorVisible( bool isVisible )
|
||||
void GLViewImpl::setCursorVisible(bool isVisible)
|
||||
{
|
||||
if( _mainWindow == NULL )
|
||||
if (_mainWindow == NULL)
|
||||
return;
|
||||
|
||||
if( isVisible )
|
||||
|
||||
if (isVisible)
|
||||
glfwSetInputMode(_mainWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
else
|
||||
glfwSetInputMode(_mainWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
|
@ -627,7 +636,8 @@ float GLViewImpl::getFrameZoomFactor() const
|
|||
return _frameZoomFactor;
|
||||
}
|
||||
|
||||
bool GLViewImpl::isFullscreen() const {
|
||||
bool GLViewImpl::isFullscreen() const
|
||||
{
|
||||
return (_monitor != nullptr);
|
||||
}
|
||||
|
||||
|
@ -636,9 +646,11 @@ void GLViewImpl::setFullscreen()
|
|||
setFullscreen(-1, -1, -1);
|
||||
}
|
||||
|
||||
void GLViewImpl::setFullscreen(int w, int h, int refreshRate) {
|
||||
void GLViewImpl::setFullscreen(int w, int h, int refreshRate)
|
||||
{
|
||||
auto monitor = glfwGetPrimaryMonitor();
|
||||
if (nullptr == monitor || monitor == _monitor) {
|
||||
if (nullptr == monitor || monitor == _monitor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->setFullscreen(monitor, w, h, refreshRate);
|
||||
|
@ -649,20 +661,24 @@ void GLViewImpl::setFullscreen(int monitorIndex)
|
|||
setFullscreen(monitorIndex, -1, -1, -1);
|
||||
}
|
||||
|
||||
void GLViewImpl::setFullscreen(int monitorIndex, int w, int h, int refreshRate) {
|
||||
int count = 0;
|
||||
void GLViewImpl::setFullscreen(int monitorIndex, int w, int h, int refreshRate)
|
||||
{
|
||||
int count = 0;
|
||||
GLFWmonitor** monitors = glfwGetMonitors(&count);
|
||||
if (monitorIndex < 0 || monitorIndex >= count) {
|
||||
if (monitorIndex < 0 || monitorIndex >= count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GLFWmonitor* monitor = monitors[monitorIndex];
|
||||
if (nullptr == monitor || _monitor == monitor) {
|
||||
if (nullptr == monitor || _monitor == monitor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->setFullscreen(monitor, w, h, refreshRate);
|
||||
}
|
||||
|
||||
void GLViewImpl::setFullscreen(GLFWmonitor *monitor, int w, int h, int refreshRate) {
|
||||
void GLViewImpl::setFullscreen(GLFWmonitor* monitor, int w, int h, int refreshRate)
|
||||
{
|
||||
_monitor = monitor;
|
||||
|
||||
const GLFWvidmode* videoMode = glfwGetVideoMode(_monitor);
|
||||
|
@ -678,10 +694,14 @@ void GLViewImpl::setFullscreen(GLFWmonitor *monitor, int w, int h, int refreshRa
|
|||
updateWindowSize();
|
||||
}
|
||||
|
||||
void GLViewImpl::setWindowed(int width, int height) {
|
||||
if (!this->isFullscreen()) {
|
||||
void GLViewImpl::setWindowed(int width, int height)
|
||||
{
|
||||
if (!this->isFullscreen())
|
||||
{
|
||||
this->setFrameSize((float)width, (float)height);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLFWvidmode* videoMode = glfwGetVideoMode(_monitor);
|
||||
int xpos = 0, ypos = 0;
|
||||
glfwGetMonitorPos(_monitor, &xpos, &ypos);
|
||||
|
@ -702,31 +722,36 @@ void GLViewImpl::updateWindowSize()
|
|||
{
|
||||
int w = 0, h = 0;
|
||||
glfwGetFramebufferSize(_mainWindow, &w, &h);
|
||||
int frameWidth = w / _frameZoomFactor;
|
||||
int frameWidth = w / _frameZoomFactor;
|
||||
int frameHeight = h / _frameZoomFactor;
|
||||
setFrameSize(frameWidth, frameHeight);
|
||||
updateDesignResolutionSize();
|
||||
Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(GLViewImpl::EVENT_WINDOW_RESIZED, nullptr);
|
||||
}
|
||||
|
||||
int GLViewImpl::getMonitorCount() const {
|
||||
int GLViewImpl::getMonitorCount() const
|
||||
{
|
||||
int count = 0;
|
||||
glfwGetMonitors(&count);
|
||||
return count;
|
||||
}
|
||||
|
||||
Size GLViewImpl::getMonitorSize() const {
|
||||
Size GLViewImpl::getMonitorSize() const
|
||||
{
|
||||
GLFWmonitor* monitor = _monitor;
|
||||
if (nullptr == monitor) {
|
||||
if (nullptr == monitor)
|
||||
{
|
||||
GLFWwindow* window = this->getWindow();
|
||||
monitor = glfwGetWindowMonitor(window);
|
||||
monitor = glfwGetWindowMonitor(window);
|
||||
}
|
||||
if (nullptr == monitor) {
|
||||
if (nullptr == monitor)
|
||||
{
|
||||
monitor = glfwGetPrimaryMonitor();
|
||||
}
|
||||
if (nullptr != monitor) {
|
||||
if (nullptr != monitor)
|
||||
{
|
||||
const GLFWvidmode* videoMode = glfwGetVideoMode(monitor);
|
||||
Size size = Size((float)videoMode->width, (float)videoMode->height);
|
||||
Size size = Size((float)videoMode->width, (float)videoMode->height);
|
||||
return size;
|
||||
}
|
||||
return Size::ZERO;
|
||||
|
@ -752,7 +777,8 @@ void GLViewImpl::updateFrameSize()
|
|||
{
|
||||
_retinaFactor = 2;
|
||||
}
|
||||
glfwSetWindowSize(_mainWindow, _screenSize.width/2 * _retinaFactor * _frameZoomFactor, _screenSize.height/2 * _retinaFactor * _frameZoomFactor);
|
||||
glfwSetWindowSize(_mainWindow, _screenSize.width / 2 * _retinaFactor * _frameZoomFactor,
|
||||
_screenSize.height / 2 * _retinaFactor * _frameZoomFactor);
|
||||
|
||||
_isInRetinaMonitor = true;
|
||||
}
|
||||
|
@ -762,7 +788,8 @@ void GLViewImpl::updateFrameSize()
|
|||
{
|
||||
_retinaFactor = 1;
|
||||
}
|
||||
glfwSetWindowSize(_mainWindow, (int)(_screenSize.width * _retinaFactor * _frameZoomFactor), (int)(_screenSize.height *_retinaFactor * _frameZoomFactor));
|
||||
glfwSetWindowSize(_mainWindow, (int)(_screenSize.width * _retinaFactor * _frameZoomFactor),
|
||||
(int)(_screenSize.height * _retinaFactor * _frameZoomFactor));
|
||||
|
||||
_isInRetinaMonitor = false;
|
||||
}
|
||||
|
@ -775,22 +802,26 @@ void GLViewImpl::setFrameSize(float width, float height)
|
|||
updateFrameSize();
|
||||
}
|
||||
|
||||
void GLViewImpl::setViewPortInPoints(float x , float y , float w , float h)
|
||||
void GLViewImpl::setViewPortInPoints(float x, float y, float w, float h)
|
||||
{
|
||||
Viewport vp;
|
||||
vp.x = (int)(x * _scaleX * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.x * _retinaFactor * _frameZoomFactor);
|
||||
vp.y = (int)(y * _scaleY * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.y * _retinaFactor * _frameZoomFactor);
|
||||
vp.x = (int)(x * _scaleX * _retinaFactor * _frameZoomFactor +
|
||||
_viewPortRect.origin.x * _retinaFactor * _frameZoomFactor);
|
||||
vp.y = (int)(y * _scaleY * _retinaFactor * _frameZoomFactor +
|
||||
_viewPortRect.origin.y * _retinaFactor * _frameZoomFactor);
|
||||
vp.w = (unsigned int)(w * _scaleX * _retinaFactor * _frameZoomFactor);
|
||||
vp.h = (unsigned int)(h * _scaleY * _retinaFactor * _frameZoomFactor);
|
||||
Camera::setDefaultViewport(vp);
|
||||
}
|
||||
|
||||
void GLViewImpl::setScissorInPoints(float x , float y , float w , float h)
|
||||
void GLViewImpl::setScissorInPoints(float x, float y, float w, float h)
|
||||
{
|
||||
auto x1 = (int)(x * _scaleX * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.x * _retinaFactor * _frameZoomFactor);
|
||||
auto y1 = (int)(y * _scaleY * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.y * _retinaFactor * _frameZoomFactor);
|
||||
auto width1 = (unsigned int)(w * _scaleX * _retinaFactor * _frameZoomFactor);
|
||||
auto height1 = (unsigned int)(h * _scaleY * _retinaFactor * _frameZoomFactor);
|
||||
auto x1 = (int)(x * _scaleX * _retinaFactor * _frameZoomFactor +
|
||||
_viewPortRect.origin.x * _retinaFactor * _frameZoomFactor);
|
||||
auto y1 = (int)(y * _scaleY * _retinaFactor * _frameZoomFactor +
|
||||
_viewPortRect.origin.y * _retinaFactor * _frameZoomFactor);
|
||||
auto width1 = (unsigned int)(w * _scaleX * _retinaFactor * _frameZoomFactor);
|
||||
auto height1 = (unsigned int)(h * _scaleY * _retinaFactor * _frameZoomFactor);
|
||||
auto renderer = Director::getInstance()->getRenderer();
|
||||
renderer->setScissorRect(x1, y1, width1, height1);
|
||||
}
|
||||
|
@ -798,12 +829,14 @@ void GLViewImpl::setScissorInPoints(float x , float y , float w , float h)
|
|||
Rect GLViewImpl::getScissorRect() const
|
||||
{
|
||||
auto renderer = Director::getInstance()->getRenderer();
|
||||
auto& rect = renderer->getScissorRect();
|
||||
auto& rect = renderer->getScissorRect();
|
||||
|
||||
float x = (rect.x - _viewPortRect.origin.x * _retinaFactor * _frameZoomFactor) / (_scaleX * _retinaFactor * _frameZoomFactor);
|
||||
float y = (rect.y - _viewPortRect.origin.y * _retinaFactor * _frameZoomFactor) / (_scaleY * _retinaFactor * _frameZoomFactor);
|
||||
float x = (rect.x - _viewPortRect.origin.x * _retinaFactor * _frameZoomFactor) /
|
||||
(_scaleX * _retinaFactor * _frameZoomFactor);
|
||||
float y = (rect.y - _viewPortRect.origin.y * _retinaFactor * _frameZoomFactor) /
|
||||
(_scaleY * _retinaFactor * _frameZoomFactor);
|
||||
float w = rect.width / (_scaleX * _retinaFactor * _frameZoomFactor);
|
||||
float h = rect.height / (_scaleY * _retinaFactor * _frameZoomFactor);
|
||||
float h = rect.height / (_scaleY * _retinaFactor * _frameZoomFactor);
|
||||
return Rect(x, y, w, h);
|
||||
}
|
||||
|
||||
|
@ -822,40 +855,41 @@ void GLViewImpl::onGLFWError(int errorID, const char* errorDesc)
|
|||
|
||||
void GLViewImpl::onGLFWMouseCallBack(GLFWwindow* /*window*/, int button, int action, int /*modify*/)
|
||||
{
|
||||
if(GLFW_MOUSE_BUTTON_LEFT == button)
|
||||
if (GLFW_MOUSE_BUTTON_LEFT == button)
|
||||
{
|
||||
if(GLFW_PRESS == action)
|
||||
if (GLFW_PRESS == action)
|
||||
{
|
||||
_captured = true;
|
||||
if (this->getViewPortRect().equals(Rect::ZERO) || this->getViewPortRect().containsPoint(Vec2(_mouseX,_mouseY)))
|
||||
if (this->getViewPortRect().equals(Rect::ZERO) ||
|
||||
this->getViewPortRect().containsPoint(Vec2(_mouseX, _mouseY)))
|
||||
{
|
||||
intptr_t id = 0;
|
||||
this->handleTouchesBegin(1, &id, &_mouseX, &_mouseY);
|
||||
}
|
||||
}
|
||||
else if(GLFW_RELEASE == action)
|
||||
else if (GLFW_RELEASE == action)
|
||||
{
|
||||
if (_captured)
|
||||
{
|
||||
_captured = false;
|
||||
_captured = false;
|
||||
intptr_t id = 0;
|
||||
this->handleTouchesEnd(1, &id, &_mouseX, &_mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
|
||||
|
||||
// Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
|
||||
float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;
|
||||
float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;
|
||||
|
||||
if(GLFW_PRESS == action)
|
||||
if (GLFW_PRESS == action)
|
||||
{
|
||||
EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN);
|
||||
event.setCursorPosition(cursorX, cursorY);
|
||||
event.setMouseButton(static_cast<cocos2d::EventMouse::MouseButton>(button));
|
||||
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
|
||||
}
|
||||
else if(GLFW_RELEASE == action)
|
||||
else if (GLFW_RELEASE == action)
|
||||
{
|
||||
EventMouse event(EventMouse::MouseEventType::MOUSE_UP);
|
||||
event.setCursorPosition(cursorX, cursorY);
|
||||
|
@ -886,8 +920,8 @@ void GLViewImpl::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
|
|||
intptr_t id = 0;
|
||||
this->handleTouchesMove(1, &id, &_mouseX, &_mouseY);
|
||||
}
|
||||
|
||||
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
|
||||
|
||||
// Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
|
||||
float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;
|
||||
float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;
|
||||
|
||||
|
@ -912,7 +946,7 @@ void GLViewImpl::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
|
|||
void GLViewImpl::onGLFWMouseScrollCallback(GLFWwindow* /*window*/, double x, double y)
|
||||
{
|
||||
EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL);
|
||||
//Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
|
||||
// Because OpenGL and cocos2d-x uses different Y axis, we need to convert the coordinate here
|
||||
float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX;
|
||||
float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY;
|
||||
event.setScrollData((float)x, -(float)y);
|
||||
|
@ -952,26 +986,26 @@ void GLViewImpl::onGLFWKeyCallback(GLFWwindow* /*window*/, int key, int /*scanco
|
|||
|
||||
void GLViewImpl::onGLFWCharCallback(GLFWwindow* /*window*/, unsigned int character)
|
||||
{
|
||||
char16_t wcharString[2] = { (char16_t) character, 0 };
|
||||
char16_t wcharString[2] = {(char16_t)character, 0};
|
||||
std::string utf8String;
|
||||
|
||||
StringUtils::UTF16ToUTF8( wcharString, utf8String );
|
||||
StringUtils::UTF16ToUTF8(wcharString, utf8String);
|
||||
static std::set<std::string> controlUnicode = {
|
||||
"\xEF\x9C\x80", // up
|
||||
"\xEF\x9C\x81", // down
|
||||
"\xEF\x9C\x82", // left
|
||||
"\xEF\x9C\x83", // right
|
||||
"\xEF\x9C\xA8", // delete
|
||||
"\xEF\x9C\xA9", // home
|
||||
"\xEF\x9C\xAB", // end
|
||||
"\xEF\x9C\xAC", // pageup
|
||||
"\xEF\x9C\xAD", // pagedown
|
||||
"\xEF\x9C\xB9" // clear
|
||||
"\xEF\x9C\x80", // up
|
||||
"\xEF\x9C\x81", // down
|
||||
"\xEF\x9C\x82", // left
|
||||
"\xEF\x9C\x83", // right
|
||||
"\xEF\x9C\xA8", // delete
|
||||
"\xEF\x9C\xA9", // home
|
||||
"\xEF\x9C\xAB", // end
|
||||
"\xEF\x9C\xAC", // pageup
|
||||
"\xEF\x9C\xAD", // pagedown
|
||||
"\xEF\x9C\xB9" // clear
|
||||
};
|
||||
// Check for send control key
|
||||
if (controlUnicode.find(utf8String) == controlUnicode.end())
|
||||
{
|
||||
IMEDispatcher::sharedDispatcher()->dispatchInsertText( utf8String.c_str(), utf8String.size() );
|
||||
IMEDispatcher::sharedDispatcher()->dispatchInsertText(utf8String.c_str(), utf8String.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -984,18 +1018,18 @@ void GLViewImpl::onGLFWWindowSizeCallback(GLFWwindow* /*window*/, int width, int
|
|||
{
|
||||
if (width && height && _resolutionPolicy != ResolutionPolicy::UNKNOWN)
|
||||
{
|
||||
Size baseDesignSize = _designResolutionSize;
|
||||
Size baseDesignSize = _designResolutionSize;
|
||||
ResolutionPolicy baseResolutionPolicy = _resolutionPolicy;
|
||||
|
||||
int frameWidth = width / _frameZoomFactor;
|
||||
int frameWidth = width / _frameZoomFactor;
|
||||
int frameHeight = height / _frameZoomFactor;
|
||||
setFrameSize(frameWidth, frameHeight);
|
||||
setDesignResolutionSize(baseDesignSize.width, baseDesignSize.height, baseResolutionPolicy);
|
||||
Director::getInstance()->setViewport();
|
||||
Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(GLViewImpl::EVENT_WINDOW_RESIZED, nullptr);
|
||||
|
||||
|
||||
#if defined(CC_USE_METAL)
|
||||
//update metal attachment texture size.
|
||||
// update metal attachment texture size.
|
||||
int fbWidth, fbHeight;
|
||||
glfwGetFramebufferSize(_mainWindow, &fbWidth, &fbHeight);
|
||||
backend::UtilsMTL::resizeDefaultAttachmentTexture(fbWidth, fbHeight);
|
||||
|
@ -1027,4 +1061,4 @@ void GLViewImpl::onGLFWWindowFocusCallback(GLFWwindow* /*window*/, int focused)
|
|||
}
|
||||
}
|
||||
|
||||
NS_CC_END // end of namespace cocos2d;
|
||||
NS_CC_END // end of namespace cocos2d;
|
||||
|
|
|
@ -52,7 +52,7 @@ static std::string s_exePath;
|
|||
static std::string convertPathFormatToUnixStyle(std::string_view path)
|
||||
{
|
||||
std::string ret{path};
|
||||
int len = ret.length();
|
||||
int len = ret.length();
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if (ret[i] == '\\')
|
||||
|
@ -129,7 +129,7 @@ bool FileUtilsWin32::init()
|
|||
DECLARE_GUARD;
|
||||
|
||||
_checkWorkingPath();
|
||||
_defaultResRootPath = ntcvt::from_chars(s_workingPath);
|
||||
_defaultResRootPath = ntcvt::from_chars(s_workingPath);
|
||||
_defaultResRootPathUtf16 = s_workingPath;
|
||||
|
||||
bool bRet = FileUtils::init();
|
||||
|
|
|
@ -63,9 +63,7 @@ protected:
|
|||
* @param name The new name of the file.
|
||||
* @return True if the file have been renamed successfully, false if not.
|
||||
*/
|
||||
virtual bool renameFile(std::string_view path,
|
||||
std::string_view oldname,
|
||||
std::string_view name) const override;
|
||||
virtual bool renameFile(std::string_view path, std::string_view oldname, std::string_view name) const override;
|
||||
|
||||
/**
|
||||
* Renames a file under the given directory.
|
||||
|
|
|
@ -741,7 +741,7 @@ void Texture2D::initProgram()
|
|||
|
||||
// setup vertex layout
|
||||
auto vertexLayout = _programState->getVertexLayout();
|
||||
auto attributes = _programState->getProgram()->getActiveAttributes();
|
||||
auto attributes = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributes.find("a_position");
|
||||
if (iter != attributes.end())
|
||||
vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
|
||||
|
|
|
@ -588,12 +588,12 @@ void TextureCache::removeTexture(Texture2D* texture)
|
|||
|
||||
void TextureCache::removeTextureForKey(std::string_view textureKeyName)
|
||||
{
|
||||
auto it = _textures.find(textureKeyName);
|
||||
auto it = _textures.find(textureKeyName);
|
||||
|
||||
if (it == _textures.end())
|
||||
{
|
||||
auto key = FileUtils::getInstance()->fullPathForFilename(textureKeyName);
|
||||
it = _textures.find(key);
|
||||
it = _textures.find(key);
|
||||
}
|
||||
|
||||
if (it != _textures.end())
|
||||
|
@ -605,12 +605,12 @@ void TextureCache::removeTextureForKey(std::string_view textureKeyName)
|
|||
|
||||
Texture2D* TextureCache::getTextureForKey(std::string_view textureKeyName) const
|
||||
{
|
||||
auto it = _textures.find(textureKeyName);
|
||||
auto it = _textures.find(textureKeyName);
|
||||
|
||||
if (it == _textures.end())
|
||||
{
|
||||
auto key = FileUtils::getInstance()->fullPathForFilename(textureKeyName);
|
||||
it = _textures.find(key);
|
||||
it = _textures.find(key);
|
||||
}
|
||||
|
||||
if (it != _textures.end())
|
||||
|
@ -677,12 +677,12 @@ std::string TextureCache::getCachedTextureInfo() const
|
|||
|
||||
void TextureCache::renameTextureWithKey(std::string_view srcName, std::string_view dstName)
|
||||
{
|
||||
auto it = _textures.find(srcName);
|
||||
auto it = _textures.find(srcName);
|
||||
|
||||
if (it == _textures.end())
|
||||
{
|
||||
auto key = FileUtils::getInstance()->fullPathForFilename(srcName);
|
||||
it = _textures.find(key);
|
||||
it = _textures.find(key);
|
||||
}
|
||||
|
||||
if (it != _textures.end())
|
||||
|
@ -864,9 +864,7 @@ void VolatileTextureMgr::reloadAllTextures()
|
|||
_isReloading = false;
|
||||
}
|
||||
|
||||
void VolatileTextureMgr::reloadTexture(Texture2D* texture,
|
||||
std::string_view filename,
|
||||
backend::PixelFormat pixelFormat)
|
||||
void VolatileTextureMgr::reloadTexture(Texture2D* texture, std::string_view filename, backend::PixelFormat pixelFormat)
|
||||
{
|
||||
if (!texture)
|
||||
return;
|
||||
|
|
|
@ -138,8 +138,7 @@ public:
|
|||
* Get all uniformInfos.
|
||||
* @return The uniformInfos.
|
||||
*/
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(
|
||||
ShaderStage stage) const = 0;
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(ShaderStage stage) const = 0;
|
||||
|
||||
/**
|
||||
* Set engin built-in program type.
|
||||
|
|
|
@ -278,9 +278,7 @@ public:
|
|||
* @return True if the auto binding is handled and the associated parameter is
|
||||
* bound, false otherwise.
|
||||
*/
|
||||
virtual bool resolveAutoBinding(ProgramState*,
|
||||
std::string_view uniformName,
|
||||
std::string_view autoBinding) = 0;
|
||||
virtual bool resolveAutoBinding(ProgramState*, std::string_view uniformName, std::string_view autoBinding) = 0;
|
||||
};
|
||||
/**
|
||||
* Sets a uniform auto-binding.
|
||||
|
|
|
@ -41,7 +41,7 @@ void VertexLayout::setAttribute(std::string_view name,
|
|||
hlookup::set_item(
|
||||
_attributes, name,
|
||||
Attribute{name, index, format, offset,
|
||||
needToBeNormallized}); // _attributes[name] = {name, index, format, offset, needToBeNormallized};
|
||||
needToBeNormallized}); // _attributes[name] = {name, index, format, offset, needToBeNormallized};
|
||||
}
|
||||
|
||||
void VertexLayout::setLayout(std::size_t stride)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "BufferMTL.h"
|
||||
#include "../Macros.h"
|
||||
#include "BufferManager.h"
|
||||
|
@ -29,15 +29,15 @@
|
|||
CC_BACKEND_BEGIN
|
||||
|
||||
BufferMTL::BufferMTL(id<MTLDevice> mtlDevice, std::size_t size, BufferType type, BufferUsage usage)
|
||||
: Buffer(size, type, usage)
|
||||
: Buffer(size, type, usage)
|
||||
{
|
||||
if (BufferUsage::DYNAMIC == usage)
|
||||
{
|
||||
NSMutableArray *mutableDynamicDataBuffers = [NSMutableArray arrayWithCapacity:MAX_INFLIGHT_BUFFER];
|
||||
NSMutableArray* mutableDynamicDataBuffers = [NSMutableArray arrayWithCapacity:MAX_INFLIGHT_BUFFER];
|
||||
for (int i = 0; i < MAX_INFLIGHT_BUFFER; ++i)
|
||||
{
|
||||
// Create a new buffer with enough capacity to store one instance of the dynamic buffer data
|
||||
id <MTLBuffer> dynamicDataBuffer = [mtlDevice newBufferWithLength:size options:MTLResourceStorageModeShared];
|
||||
id<MTLBuffer> dynamicDataBuffer = [mtlDevice newBufferWithLength:size options:MTLResourceStorageModeShared];
|
||||
[mutableDynamicDataBuffers addObject:dynamicDataBuffer];
|
||||
}
|
||||
_dynamicDataBuffers = [mutableDynamicDataBuffers copy];
|
||||
|
@ -97,8 +97,8 @@ void BufferMTL::updateIndex()
|
|||
if (BufferUsage::DYNAMIC == _usage && !_indexUpdated)
|
||||
{
|
||||
_currentFrameIndex = (_currentFrameIndex + 1) % MAX_INFLIGHT_BUFFER;
|
||||
_mtlBuffer = _dynamicDataBuffers[_currentFrameIndex];
|
||||
_indexUpdated = true;
|
||||
_mtlBuffer = _dynamicDataBuffers[_currentFrameIndex];
|
||||
_indexUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "BufferManager.h"
|
||||
#include "BufferMTL.h"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "CommandBufferMTL.h"
|
||||
#include "BufferMTL.h"
|
||||
#include "DeviceMTL.h"
|
||||
|
@ -39,130 +39,131 @@ CC_BACKEND_BEGIN
|
|||
namespace
|
||||
{
|
||||
|
||||
#define byte(n) ((n) * 8)
|
||||
#define byte(n) ((n)*8)
|
||||
#define bit(n) (n)
|
||||
static uint8_t getBitsPerElementMTL(MTLPixelFormat pixleFormat)
|
||||
static uint8_t getBitsPerElementMTL(MTLPixelFormat pixleFormat)
|
||||
{
|
||||
switch (pixleFormat)
|
||||
{
|
||||
switch (pixleFormat)
|
||||
{
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
return byte(8);
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
case MTLPixelFormatDepth32Float:
|
||||
return byte(4);
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
return byte(4);
|
||||
#else
|
||||
case MTLPixelFormatABGR4Unorm:
|
||||
case MTLPixelFormatBGR5A1Unorm:
|
||||
case MTLPixelFormatB5G6R5Unorm:
|
||||
case MTLPixelFormatA1BGR5Unorm:
|
||||
return byte(2);
|
||||
#endif
|
||||
case MTLPixelFormatA8Unorm:
|
||||
case MTLPixelFormatR8Unorm:
|
||||
return byte(1);
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
return byte(8);
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
case MTLPixelFormatDepth32Float:
|
||||
return byte(4);
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
return byte(4);
|
||||
#else
|
||||
case MTLPixelFormatABGR4Unorm:
|
||||
case MTLPixelFormatBGR5A1Unorm:
|
||||
case MTLPixelFormatB5G6R5Unorm:
|
||||
case MTLPixelFormatA1BGR5Unorm:
|
||||
return byte(2);
|
||||
#endif
|
||||
case MTLPixelFormatA8Unorm:
|
||||
case MTLPixelFormatR8Unorm:
|
||||
return byte(1);
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MTLWinding toMTLWinding(Winding winding)
|
||||
{
|
||||
if (Winding::CLOCK_WISE == winding)
|
||||
return MTLWindingClockwise;
|
||||
else
|
||||
return MTLWindingCounterClockwise;
|
||||
}
|
||||
static MTLWinding toMTLWinding(Winding winding)
|
||||
{
|
||||
if (Winding::CLOCK_WISE == winding)
|
||||
return MTLWindingClockwise;
|
||||
else
|
||||
return MTLWindingCounterClockwise;
|
||||
}
|
||||
|
||||
static MTLPrimitiveType toMTLPrimitive(PrimitiveType primitiveType)
|
||||
static MTLPrimitiveType toMTLPrimitive(PrimitiveType primitiveType)
|
||||
{
|
||||
MTLPrimitiveType ret = MTLPrimitiveTypeTriangle;
|
||||
switch (primitiveType)
|
||||
{
|
||||
MTLPrimitiveType ret = MTLPrimitiveTypeTriangle;
|
||||
switch (primitiveType)
|
||||
{
|
||||
case PrimitiveType::POINT:
|
||||
ret = MTLPrimitiveTypePoint;
|
||||
break;
|
||||
case PrimitiveType::LINE:
|
||||
ret = MTLPrimitiveTypeLine;
|
||||
break;
|
||||
case PrimitiveType::LINE_STRIP:
|
||||
ret = MTLPrimitiveTypeLineStrip;
|
||||
break;
|
||||
case PrimitiveType::TRIANGLE:
|
||||
ret = MTLPrimitiveTypeTriangle;
|
||||
break;
|
||||
case PrimitiveType::TRIANGLE_STRIP:
|
||||
ret = MTLPrimitiveTypeTriangleStrip;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MTLIndexType toMTLIndexType(IndexFormat indexFormat)
|
||||
{
|
||||
if (IndexFormat::U_SHORT == indexFormat)
|
||||
return MTLIndexTypeUInt16;
|
||||
else
|
||||
return MTLIndexTypeUInt32;
|
||||
}
|
||||
|
||||
static MTLCullMode toMTLCullMode(CullMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case CullMode::NONE:
|
||||
return MTLCullModeNone;
|
||||
case CullMode::FRONT:
|
||||
return MTLCullModeFront;
|
||||
case CullMode::BACK:
|
||||
return MTLCullModeBack;
|
||||
}
|
||||
}
|
||||
|
||||
static MTLRenderPassDescriptor* toMTLRenderPassDescriptor(const RenderTarget* rt, const RenderPassDescriptor& desc)
|
||||
{
|
||||
MTLRenderPassDescriptor* mtlDescritpor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
|
||||
auto rtMTL = static_cast<const RenderTargetMTL*>(rt);
|
||||
rtMTL->applyRenderPassAttachments(desc, mtlDescritpor);
|
||||
return mtlDescritpor;
|
||||
}
|
||||
|
||||
static id<MTLTexture> getMTLTexture(TextureBackend* texture, int index)
|
||||
{
|
||||
return reinterpret_cast<id<MTLTexture>>(texture->getHandler(index));
|
||||
}
|
||||
|
||||
static id<MTLSamplerState> getMTLSamplerState(TextureBackend* texture)
|
||||
{
|
||||
switch (texture->getTextureType())
|
||||
{
|
||||
case TextureType::TEXTURE_2D:
|
||||
return static_cast<TextureMTL*>(texture)->getMTLSamplerState();
|
||||
case TextureType::TEXTURE_CUBE:
|
||||
return static_cast<TextureCubeMTL*>(texture)->getMTLSamplerState();
|
||||
default:
|
||||
assert(false);
|
||||
return nil;
|
||||
}
|
||||
case PrimitiveType::POINT:
|
||||
ret = MTLPrimitiveTypePoint;
|
||||
break;
|
||||
case PrimitiveType::LINE:
|
||||
ret = MTLPrimitiveTypeLine;
|
||||
break;
|
||||
case PrimitiveType::LINE_STRIP:
|
||||
ret = MTLPrimitiveTypeLineStrip;
|
||||
break;
|
||||
case PrimitiveType::TRIANGLE:
|
||||
ret = MTLPrimitiveTypeTriangle;
|
||||
break;
|
||||
case PrimitiveType::TRIANGLE_STRIP:
|
||||
ret = MTLPrimitiveTypeTriangleStrip;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int clamp(int value, int min, int max) {
|
||||
return std::min(max, std::max(min, value));
|
||||
static MTLIndexType toMTLIndexType(IndexFormat indexFormat)
|
||||
{
|
||||
if (IndexFormat::U_SHORT == indexFormat)
|
||||
return MTLIndexTypeUInt16;
|
||||
else
|
||||
return MTLIndexTypeUInt32;
|
||||
}
|
||||
|
||||
static MTLCullMode toMTLCullMode(CullMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case CullMode::NONE:
|
||||
return MTLCullModeNone;
|
||||
case CullMode::FRONT:
|
||||
return MTLCullModeFront;
|
||||
case CullMode::BACK:
|
||||
return MTLCullModeBack;
|
||||
}
|
||||
}
|
||||
|
||||
static MTLRenderPassDescriptor* toMTLRenderPassDescriptor(const RenderTarget* rt, const RenderPassDescriptor& desc)
|
||||
{
|
||||
MTLRenderPassDescriptor* mtlDescritpor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
|
||||
auto rtMTL = static_cast<const RenderTargetMTL*>(rt);
|
||||
rtMTL->applyRenderPassAttachments(desc, mtlDescritpor);
|
||||
return mtlDescritpor;
|
||||
}
|
||||
|
||||
static id<MTLTexture> getMTLTexture(TextureBackend* texture, int index)
|
||||
{
|
||||
return reinterpret_cast<id<MTLTexture>>(texture->getHandler(index));
|
||||
}
|
||||
|
||||
static id<MTLSamplerState> getMTLSamplerState(TextureBackend* texture)
|
||||
{
|
||||
switch (texture->getTextureType())
|
||||
{
|
||||
case TextureType::TEXTURE_2D:
|
||||
return static_cast<TextureMTL*>(texture)->getMTLSamplerState();
|
||||
case TextureType::TEXTURE_CUBE:
|
||||
return static_cast<TextureCubeMTL*>(texture)->getMTLSamplerState();
|
||||
default:
|
||||
assert(false);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
inline int clamp(int value, int min, int max)
|
||||
{
|
||||
return std::min(max, std::max(min, value));
|
||||
}
|
||||
}
|
||||
|
||||
CommandBufferMTL::CommandBufferMTL(DeviceMTL* deviceMTL)
|
||||
: _mtlCommandQueue(deviceMTL->getMTLCommandQueue())
|
||||
, _frameBoundarySemaphore(dispatch_semaphore_create(MAX_INFLIGHT_BUFFER))
|
||||
{
|
||||
}
|
||||
: _mtlCommandQueue(deviceMTL->getMTLCommandQueue())
|
||||
, _frameBoundarySemaphore(dispatch_semaphore_create(MAX_INFLIGHT_BUFFER))
|
||||
{}
|
||||
|
||||
CommandBufferMTL::~CommandBufferMTL()
|
||||
{
|
||||
|
@ -171,7 +172,7 @@ CommandBufferMTL::~CommandBufferMTL()
|
|||
id<MTLCommandBuffer> oneOffBuffer = [_mtlCommandQueue commandBuffer];
|
||||
[oneOffBuffer commit];
|
||||
[oneOffBuffer waitUntilCompleted];
|
||||
|
||||
|
||||
dispatch_semaphore_signal(_frameBoundarySemaphore);
|
||||
}
|
||||
|
||||
|
@ -199,38 +200,37 @@ bool CommandBufferMTL::beginFrame()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CommandBufferMTL::updateRenderCommandEncoder(const RenderTarget* renderTarget, const RenderPassDescriptor& renderPassDesc)
|
||||
void CommandBufferMTL::updateRenderCommandEncoder(const RenderTarget* renderTarget,
|
||||
const RenderPassDescriptor& renderPassDesc)
|
||||
{
|
||||
if(_mtlRenderEncoder != nil &&
|
||||
_currentRenderPassDesc == renderPassDesc &&
|
||||
_currentRenderTarget == renderTarget &&
|
||||
_currentRenderTargetFlags == renderTarget->getTargetFlags())
|
||||
if (_mtlRenderEncoder != nil && _currentRenderPassDesc == renderPassDesc && _currentRenderTarget == renderTarget &&
|
||||
_currentRenderTargetFlags == renderTarget->getTargetFlags())
|
||||
{
|
||||
return _mtlRenderEncoder;
|
||||
}
|
||||
|
||||
_currentRenderTarget = renderTarget;
|
||||
_currentRenderPassDesc = renderPassDesc;
|
||||
|
||||
_currentRenderTarget = renderTarget;
|
||||
_currentRenderPassDesc = renderPassDesc;
|
||||
_currentRenderTargetFlags = renderTarget->getTargetFlags();
|
||||
|
||||
if(_mtlRenderEncoder != nil)
|
||||
|
||||
if (_mtlRenderEncoder != nil)
|
||||
{
|
||||
[_mtlRenderEncoder endEncoding];
|
||||
[_mtlRenderEncoder release];
|
||||
_mtlRenderEncoder = nil;
|
||||
}
|
||||
|
||||
auto mtlDescriptor = toMTLRenderPassDescriptor(renderTarget, renderPassDesc);
|
||||
_renderTargetWidth = (unsigned int)mtlDescriptor.colorAttachments[0].texture.width;
|
||||
auto mtlDescriptor = toMTLRenderPassDescriptor(renderTarget, renderPassDesc);
|
||||
_renderTargetWidth = (unsigned int)mtlDescriptor.colorAttachments[0].texture.width;
|
||||
_renderTargetHeight = (unsigned int)mtlDescriptor.colorAttachments[0].texture.height;
|
||||
_mtlRenderEncoder = [_mtlCommandBuffer renderCommandEncoderWithDescriptor:mtlDescriptor];
|
||||
_mtlRenderEncoder = [_mtlCommandBuffer renderCommandEncoderWithDescriptor:mtlDescriptor];
|
||||
[_mtlRenderEncoder retain];
|
||||
}
|
||||
|
||||
void CommandBufferMTL::beginRenderPass(const RenderTarget* renderTarget, const RenderPassDescriptor& renderPassDesc)
|
||||
{
|
||||
updateRenderCommandEncoder(renderTarget, renderPassDesc);
|
||||
// [_mtlRenderEncoder setFrontFacingWinding:MTLWindingCounterClockwise];
|
||||
// [_mtlRenderEncoder setFrontFacingWinding:MTLWindingCounterClockwise];
|
||||
}
|
||||
|
||||
void CommandBufferMTL::updateDepthStencilState(const DepthStencilDescriptor& descriptor)
|
||||
|
@ -249,10 +249,10 @@ void CommandBufferMTL::setViewport(int x, int y, unsigned int w, unsigned int h)
|
|||
MTLViewport viewport;
|
||||
viewport.originX = x;
|
||||
viewport.originY = (int)(_renderTargetHeight - y - h);
|
||||
viewport.width = w;
|
||||
viewport.height = h;
|
||||
viewport.znear = 0;
|
||||
viewport.zfar = 1;
|
||||
viewport.width = w;
|
||||
viewport.height = h;
|
||||
viewport.znear = 0;
|
||||
viewport.zfar = 1;
|
||||
[_mtlRenderEncoder setViewport:viewport];
|
||||
}
|
||||
|
||||
|
@ -269,9 +269,7 @@ void CommandBufferMTL::setWinding(Winding winding)
|
|||
void CommandBufferMTL::setVertexBuffer(Buffer* buffer)
|
||||
{
|
||||
// Vertex buffer is bound in index 0.
|
||||
[_mtlRenderEncoder setVertexBuffer:static_cast<BufferMTL*>(buffer)->getMTLBuffer()
|
||||
offset:0
|
||||
atIndex:0];
|
||||
[_mtlRenderEncoder setVertexBuffer:static_cast<BufferMTL*>(buffer)->getMTLBuffer() offset:0 atIndex:0];
|
||||
}
|
||||
|
||||
void CommandBufferMTL::setProgramState(ProgramState* programState)
|
||||
|
@ -286,20 +284,21 @@ void CommandBufferMTL::setIndexBuffer(Buffer* buffer)
|
|||
assert(buffer != nullptr);
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
|
||||
_mtlIndexBuffer = static_cast<BufferMTL*>(buffer)->getMTLBuffer();
|
||||
[_mtlIndexBuffer retain];
|
||||
}
|
||||
|
||||
void CommandBufferMTL::drawArrays(PrimitiveType primitiveType, std::size_t start, std::size_t count)
|
||||
void CommandBufferMTL::drawArrays(PrimitiveType primitiveType, std::size_t start, std::size_t count)
|
||||
{
|
||||
prepareDrawing();
|
||||
[_mtlRenderEncoder drawPrimitives:toMTLPrimitive(primitiveType)
|
||||
vertexStart:start
|
||||
vertexCount:count];
|
||||
[_mtlRenderEncoder drawPrimitives:toMTLPrimitive(primitiveType) vertexStart:start vertexCount:count];
|
||||
}
|
||||
|
||||
void CommandBufferMTL::drawElements(PrimitiveType primitiveType, IndexFormat indexType, std::size_t count, std::size_t offset)
|
||||
void CommandBufferMTL::drawElements(PrimitiveType primitiveType,
|
||||
IndexFormat indexType,
|
||||
std::size_t count,
|
||||
std::size_t offset)
|
||||
{
|
||||
prepareDrawing();
|
||||
[_mtlRenderEncoder drawIndexedPrimitives:toMTLPrimitive(primitiveType)
|
||||
|
@ -307,7 +306,6 @@ void CommandBufferMTL::drawElements(PrimitiveType primitiveType, IndexFormat ind
|
|||
indexType:toMTLIndexType(indexType)
|
||||
indexBuffer:_mtlIndexBuffer
|
||||
indexBufferOffset:offset];
|
||||
|
||||
}
|
||||
|
||||
void CommandBufferMTL::endRenderPass()
|
||||
|
@ -318,7 +316,7 @@ void CommandBufferMTL::endRenderPass()
|
|||
void CommandBufferMTL::readPixels(RenderTarget* rt, std::function<void(const PixelBufferDescriptor&)> callback)
|
||||
{
|
||||
auto rtMTL = static_cast<RenderTargetMTL*>(rt);
|
||||
|
||||
|
||||
// we only read form color attachment 0
|
||||
// if it's nullptr, will regard as screen to perform capture
|
||||
auto texture = rtMTL->_color[0].texture;
|
||||
|
@ -331,14 +329,14 @@ void CommandBufferMTL::endFrame()
|
|||
[_mtlRenderEncoder endEncoding];
|
||||
[_mtlRenderEncoder release];
|
||||
_mtlRenderEncoder = nil;
|
||||
|
||||
|
||||
auto currentDrawable = DeviceMTL::getCurrentDrawable();
|
||||
[_mtlCommandBuffer presentDrawable:currentDrawable];
|
||||
_drawableTexture = currentDrawable.texture;
|
||||
[_mtlCommandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer) {
|
||||
// GPU work is complete
|
||||
// Signal the semaphore to start the CPU work
|
||||
dispatch_semaphore_signal(_frameBoundarySemaphore);
|
||||
// GPU work is complete
|
||||
// Signal the semaphore to start the CPU work
|
||||
dispatch_semaphore_signal(_frameBoundarySemaphore);
|
||||
}];
|
||||
|
||||
flush();
|
||||
|
@ -349,12 +347,13 @@ void CommandBufferMTL::endFrame()
|
|||
|
||||
void CommandBufferMTL::flush()
|
||||
{
|
||||
if(_mtlCommandBuffer) {
|
||||
if (_mtlCommandBuffer)
|
||||
{
|
||||
assert(_mtlCommandBuffer.status != MTLCommandBufferStatusCommitted);
|
||||
[_mtlCommandBuffer commit];
|
||||
|
||||
|
||||
flushCaptureCommands();
|
||||
|
||||
|
||||
[_mtlCommandBuffer release];
|
||||
_mtlCommandBuffer = nil;
|
||||
}
|
||||
|
@ -362,24 +361,30 @@ void CommandBufferMTL::flush()
|
|||
|
||||
void CommandBufferMTL::flushCaptureCommands()
|
||||
{
|
||||
if(!_captureCallbacks.empty()) {
|
||||
if (!_captureCallbacks.empty())
|
||||
{
|
||||
// !!!important, if have capture request, must wait pending commandBuffer finish at this frame,
|
||||
// because readPixels require sync operation to get screen pixels properly without data race issue,
|
||||
// otherwise, will lead dead-lock
|
||||
// !!!Notes, MTL is mutli-threading, all GPU handler is dispatch at GPU threads
|
||||
[_mtlCommandBuffer waitUntilCompleted];
|
||||
|
||||
|
||||
PixelBufferDescriptor screenPixelData;
|
||||
for(auto& cb : _captureCallbacks) {
|
||||
if(cb.first == nil) { // screen capture
|
||||
if(!screenPixelData) {
|
||||
CommandBufferMTL::readPixels(_drawableTexture, 0, 0, [_drawableTexture width], [_drawableTexture height], screenPixelData);
|
||||
for (auto& cb : _captureCallbacks)
|
||||
{
|
||||
if (cb.first == nil)
|
||||
{ // screen capture
|
||||
if (!screenPixelData)
|
||||
{
|
||||
CommandBufferMTL::readPixels(_drawableTexture, 0, 0, [_drawableTexture width],
|
||||
[_drawableTexture height], screenPixelData);
|
||||
// screen framebuffer copied, restore screen framebuffer only to true
|
||||
backend::Device::getInstance()->setFrameBufferOnly(true);
|
||||
}
|
||||
cb.second(screenPixelData);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
PixelBufferDescriptor pixelData;
|
||||
auto texture = cb.first;
|
||||
assert(texture != nullptr);
|
||||
|
@ -399,7 +404,7 @@ void CommandBufferMTL::afterDraw()
|
|||
[_mtlIndexBuffer release];
|
||||
_mtlIndexBuffer = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CC_SAFE_RELEASE_NULL(_programState);
|
||||
}
|
||||
|
||||
|
@ -407,7 +412,7 @@ void CommandBufferMTL::prepareDrawing() const
|
|||
{
|
||||
setUniformBuffer();
|
||||
setTextures();
|
||||
|
||||
|
||||
auto mtlDepthStencilState = _depthStencilStateMTL->getMTLDepthStencilState();
|
||||
if (mtlDepthStencilState)
|
||||
{
|
||||
|
@ -428,36 +433,33 @@ void CommandBufferMTL::setTextures() const
|
|||
|
||||
void CommandBufferMTL::doSetTextures(bool isVertex) const
|
||||
{
|
||||
const auto& bindTextureInfos = (isVertex) ? _programState->getVertexTextureInfos() : _programState->getFragmentTextureInfos();
|
||||
const auto& bindTextureInfos =
|
||||
(isVertex) ? _programState->getVertexTextureInfos() : _programState->getFragmentTextureInfos();
|
||||
|
||||
for(const auto& iter : bindTextureInfos)
|
||||
for (const auto& iter : bindTextureInfos)
|
||||
{
|
||||
/* About mutli textures support
|
||||
* a. TODO: sampler2DArray, not implemented in Metal Renderer currently
|
||||
* b. texture slot, one BackendTexture, multi GPU texture handlers, used by etc1, restrict: textures must have same size
|
||||
* c. Bind multi BackendTexture to 1 Shader Program, see the ShaderTest
|
||||
* d. iter.second.slots not used for Metal Renderer
|
||||
*/
|
||||
auto location = iter.first;
|
||||
* a. TODO: sampler2DArray, not implemented in Metal Renderer currently
|
||||
* b. texture slot, one BackendTexture, multi GPU texture handlers, used by etc1, restrict: textures must have
|
||||
* same size c. Bind multi BackendTexture to 1 Shader Program, see the ShaderTest d. iter.second.slots not used
|
||||
* for Metal Renderer
|
||||
*/
|
||||
auto location = iter.first;
|
||||
auto& textures = iter.second.textures;
|
||||
auto& indexs = iter.second.indexs;
|
||||
|
||||
auto& indexs = iter.second.indexs;
|
||||
|
||||
auto texture = textures[0];
|
||||
auto index = indexs[0];
|
||||
auto index = indexs[0];
|
||||
|
||||
if (isVertex)
|
||||
{
|
||||
[_mtlRenderEncoder setVertexTexture:getMTLTexture(texture, index)
|
||||
atIndex:location];
|
||||
[_mtlRenderEncoder setVertexSamplerState:getMTLSamplerState(texture)
|
||||
atIndex:location];
|
||||
[_mtlRenderEncoder setVertexTexture:getMTLTexture(texture, index) atIndex:location];
|
||||
[_mtlRenderEncoder setVertexSamplerState:getMTLSamplerState(texture) atIndex:location];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_mtlRenderEncoder setFragmentTexture:getMTLTexture(texture, index)
|
||||
atIndex:location];
|
||||
[_mtlRenderEncoder setFragmentSamplerState:getMTLSamplerState(texture)
|
||||
atIndex:location];
|
||||
[_mtlRenderEncoder setFragmentTexture:getMTLTexture(texture, index) atIndex:location];
|
||||
[_mtlRenderEncoder setFragmentSamplerState:getMTLSamplerState(texture) atIndex:location];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,108 +468,122 @@ void CommandBufferMTL::setUniformBuffer() const
|
|||
{
|
||||
if (_programState)
|
||||
{
|
||||
auto& callbackUniforms = _programState->getCallbackUniforms();
|
||||
for(auto& cb : callbackUniforms)
|
||||
cb.second(_programState, cb.first);
|
||||
auto& callbackUniforms = _programState->getCallbackUniforms();
|
||||
for (auto& cb : callbackUniforms)
|
||||
cb.second(_programState, cb.first);
|
||||
|
||||
// Uniform buffer is bound to index 1.
|
||||
std::size_t bufferSize = 0;
|
||||
char* vertexBuffer = nullptr;
|
||||
char* vertexBuffer = nullptr;
|
||||
_programState->getVertexUniformBuffer(&vertexBuffer, bufferSize);
|
||||
if(vertexBuffer)
|
||||
if (vertexBuffer)
|
||||
{
|
||||
[_mtlRenderEncoder setVertexBytes:vertexBuffer
|
||||
length:bufferSize
|
||||
atIndex:1];
|
||||
[_mtlRenderEncoder setVertexBytes:vertexBuffer length:bufferSize atIndex:1];
|
||||
}
|
||||
|
||||
|
||||
char* fragmentBuffer = nullptr;
|
||||
_programState->getFragmentUniformBuffer(&fragmentBuffer, bufferSize);
|
||||
if(fragmentBuffer)
|
||||
if (fragmentBuffer)
|
||||
{
|
||||
[_mtlRenderEncoder setFragmentBytes:fragmentBuffer
|
||||
length:bufferSize
|
||||
atIndex:1];
|
||||
[_mtlRenderEncoder setFragmentBytes:fragmentBuffer length:bufferSize atIndex:1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBufferMTL::setLineWidth(float lineWidth)
|
||||
{
|
||||
}
|
||||
void CommandBufferMTL::setLineWidth(float lineWidth) {}
|
||||
|
||||
void CommandBufferMTL::setScissorRect(bool isEnabled, float x, float y, float width, float height)
|
||||
{
|
||||
MTLScissorRect scissorRect;
|
||||
if(isEnabled)
|
||||
if (isEnabled)
|
||||
{
|
||||
y = _renderTargetHeight - height - y;
|
||||
int minX = clamp((int)x, 0, (int)_renderTargetWidth);
|
||||
int minY = clamp((int)y, 0, (int)_renderTargetHeight);
|
||||
int maxX = clamp((int)(x + width), 0, (int)_renderTargetWidth);
|
||||
int maxY = clamp((int)(y + height), 0, (int)_renderTargetHeight);
|
||||
scissorRect.x = minX;
|
||||
scissorRect.y = minY;
|
||||
scissorRect.width = maxX - minX;
|
||||
y = _renderTargetHeight - height - y;
|
||||
int minX = clamp((int)x, 0, (int)_renderTargetWidth);
|
||||
int minY = clamp((int)y, 0, (int)_renderTargetHeight);
|
||||
int maxX = clamp((int)(x + width), 0, (int)_renderTargetWidth);
|
||||
int maxY = clamp((int)(y + height), 0, (int)_renderTargetHeight);
|
||||
scissorRect.x = minX;
|
||||
scissorRect.y = minY;
|
||||
scissorRect.width = maxX - minX;
|
||||
scissorRect.height = maxY - minY;
|
||||
if (scissorRect.width == 0 || scissorRect.height == 0) {
|
||||
scissorRect.width = 0;
|
||||
if (scissorRect.width == 0 || scissorRect.height == 0)
|
||||
{
|
||||
scissorRect.width = 0;
|
||||
scissorRect.height = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scissorRect.x = 0;
|
||||
scissorRect.y = 0;
|
||||
scissorRect.width = _renderTargetWidth;
|
||||
scissorRect.x = 0;
|
||||
scissorRect.y = 0;
|
||||
scissorRect.width = _renderTargetWidth;
|
||||
scissorRect.height = _renderTargetHeight;
|
||||
}
|
||||
[_mtlRenderEncoder setScissorRect:scissorRect];
|
||||
}
|
||||
|
||||
void CommandBufferMTL::readPixels(TextureBackend* texture, std::size_t origX, std::size_t origY, std::size_t rectWidth, std::size_t rectHeight, PixelBufferDescriptor& pbd)
|
||||
void CommandBufferMTL::readPixels(TextureBackend* texture,
|
||||
std::size_t origX,
|
||||
std::size_t origY,
|
||||
std::size_t rectWidth,
|
||||
std::size_t rectHeight,
|
||||
PixelBufferDescriptor& pbd)
|
||||
{
|
||||
CommandBufferMTL::readPixels(reinterpret_cast<id<MTLTexture>>(texture->getHandler()), origX, origY, rectWidth, rectHeight, pbd);
|
||||
CommandBufferMTL::readPixels(reinterpret_cast<id<MTLTexture>>(texture->getHandler()), origX, origY, rectWidth,
|
||||
rectHeight, pbd);
|
||||
}
|
||||
|
||||
void CommandBufferMTL::readPixels(id<MTLTexture> texture, std::size_t origX, std::size_t origY, std::size_t rectWidth, std::size_t rectHeight, PixelBufferDescriptor& pbd)
|
||||
void CommandBufferMTL::readPixels(id<MTLTexture> texture,
|
||||
std::size_t origX,
|
||||
std::size_t origY,
|
||||
std::size_t rectWidth,
|
||||
std::size_t rectHeight,
|
||||
PixelBufferDescriptor& pbd)
|
||||
{
|
||||
NSUInteger texWidth = texture.width;
|
||||
NSUInteger texHeight = texture.height;
|
||||
MTLRegion region = MTLRegionMake2D(0, 0, texWidth, texHeight);
|
||||
NSUInteger texWidth = texture.width;
|
||||
NSUInteger texHeight = texture.height;
|
||||
MTLRegion region = MTLRegionMake2D(0, 0, texWidth, texHeight);
|
||||
MTLRegion imageRegion = MTLRegionMake2D(origX, origY, rectWidth, rectHeight);
|
||||
|
||||
|
||||
MTLTextureDescriptor* textureDescriptor =
|
||||
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:[texture pixelFormat]
|
||||
width:texWidth
|
||||
height:texHeight
|
||||
mipmapped:NO];
|
||||
id<MTLDevice> device = static_cast<DeviceMTL*>(DeviceMTL::getInstance())->getMTLDevice();
|
||||
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:[texture pixelFormat]
|
||||
width:texWidth
|
||||
height:texHeight
|
||||
mipmapped:NO];
|
||||
id<MTLDevice> device = static_cast<DeviceMTL*>(DeviceMTL::getInstance())->getMTLDevice();
|
||||
id<MTLTexture> readPixelsTexture = [device newTextureWithDescriptor:textureDescriptor];
|
||||
|
||||
|
||||
id<MTLCommandQueue> commandQueue = static_cast<DeviceMTL*>(DeviceMTL::getInstance())->getMTLCommandQueue();
|
||||
auto commandBuffer = [commandQueue commandBuffer];
|
||||
auto commandBuffer = [commandQueue commandBuffer];
|
||||
// [commandBuffer enqueue];
|
||||
|
||||
|
||||
id<MTLBlitCommandEncoder> blitCommandEncoder = [commandBuffer blitCommandEncoder];
|
||||
[blitCommandEncoder copyFromTexture:texture sourceSlice:0 sourceLevel:0 sourceOrigin:region.origin sourceSize:region.size toTexture:readPixelsTexture destinationSlice:0 destinationLevel:0 destinationOrigin:region.origin];
|
||||
|
||||
[blitCommandEncoder copyFromTexture:texture
|
||||
sourceSlice:0
|
||||
sourceLevel:0
|
||||
sourceOrigin:region.origin
|
||||
sourceSize:region.size
|
||||
toTexture:readPixelsTexture
|
||||
destinationSlice:0
|
||||
destinationLevel:0
|
||||
destinationOrigin:region.origin];
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
[blitCommandEncoder synchronizeResource:readPixelsTexture];
|
||||
#endif
|
||||
[blitCommandEncoder endEncoding];
|
||||
|
||||
|
||||
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBufferMTL) {
|
||||
auto bytePerRow = rectWidth * getBitsPerElementMTL(texture.pixelFormat) / 8;
|
||||
auto texelData = pbd._data.resize(bytePerRow * rectHeight);
|
||||
if(texelData != nullptr)
|
||||
{
|
||||
auto bytePerRow = rectWidth * getBitsPerElementMTL(texture.pixelFormat) / 8;
|
||||
auto texelData = pbd._data.resize(bytePerRow * rectHeight);
|
||||
if (texelData != nullptr)
|
||||
{
|
||||
[readPixelsTexture getBytes:texelData bytesPerRow:bytePerRow fromRegion:imageRegion mipmapLevel:0];
|
||||
UtilsMTL::swizzleImage(texelData, rectWidth, rectHeight, readPixelsTexture.pixelFormat);
|
||||
pbd._width = rectWidth;
|
||||
pbd._width = rectWidth;
|
||||
pbd._height = rectHeight;
|
||||
}
|
||||
[readPixelsTexture release];
|
||||
}
|
||||
[readPixelsTexture release];
|
||||
}];
|
||||
[commandBuffer commit];
|
||||
[commandBuffer waitUntilCompleted];
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "DepthStencilStateMTL.h"
|
||||
#include "../RenderTarget.h"
|
||||
#include "xxhash.h"
|
||||
|
@ -30,108 +30,110 @@ CC_BACKEND_BEGIN
|
|||
|
||||
namespace
|
||||
{
|
||||
MTLCompareFunction toMTLCompareFunction(CompareFunction compareFunction)
|
||||
MTLCompareFunction toMTLCompareFunction(CompareFunction compareFunction)
|
||||
{
|
||||
MTLCompareFunction ret = MTLCompareFunctionNever;
|
||||
switch (compareFunction)
|
||||
{
|
||||
MTLCompareFunction ret = MTLCompareFunctionNever;
|
||||
switch (compareFunction) {
|
||||
case CompareFunction::NEVER:
|
||||
ret = MTLCompareFunctionNever;
|
||||
break;
|
||||
case CompareFunction::LESS:
|
||||
ret = MTLCompareFunctionLess;
|
||||
break;
|
||||
case CompareFunction::LESS_EQUAL:
|
||||
ret = MTLCompareFunctionLessEqual;
|
||||
break;
|
||||
case CompareFunction::GREATER:
|
||||
ret = MTLCompareFunctionGreater;
|
||||
break;
|
||||
case CompareFunction::GREATER_EQUAL:
|
||||
ret = MTLCompareFunctionGreaterEqual;
|
||||
break;
|
||||
case CompareFunction::EQUAL:
|
||||
ret = MTLCompareFunctionEqual;
|
||||
break;
|
||||
case CompareFunction::NOT_EQUAL:
|
||||
ret = MTLCompareFunctionNotEqual;
|
||||
break;
|
||||
case CompareFunction::ALWAYS:
|
||||
ret = MTLCompareFunctionAlways;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
MTLStencilOperation toMTLStencilOperation(StencilOperation operation)
|
||||
{
|
||||
MTLStencilOperation ret = MTLStencilOperationKeep;
|
||||
switch (operation) {
|
||||
case StencilOperation::KEEP:
|
||||
ret = MTLStencilOperationKeep;
|
||||
break;
|
||||
case StencilOperation::ZERO:
|
||||
ret = MTLStencilOperationZero;
|
||||
break;
|
||||
case StencilOperation::REPLACE:
|
||||
ret = MTLStencilOperationReplace;
|
||||
break;
|
||||
case StencilOperation::INVERT:
|
||||
ret = MTLStencilOperationInvert;
|
||||
break;
|
||||
case StencilOperation::INCREMENT_WRAP:
|
||||
ret = MTLStencilOperationIncrementWrap;
|
||||
break;
|
||||
case StencilOperation::DECREMENT_WRAP:
|
||||
ret = MTLStencilOperationDecrementWrap;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setMTLStencilDescriptor(MTLStencilDescriptor* stencilDescriptor, const StencilDescriptor& descriptor)
|
||||
{
|
||||
stencilDescriptor.stencilFailureOperation = toMTLStencilOperation(descriptor.stencilFailureOperation);
|
||||
stencilDescriptor.depthFailureOperation = toMTLStencilOperation(descriptor.depthFailureOperation);
|
||||
stencilDescriptor.depthStencilPassOperation = toMTLStencilOperation(descriptor.depthStencilPassOperation);
|
||||
stencilDescriptor.stencilCompareFunction = toMTLCompareFunction(descriptor.stencilCompareFunction);
|
||||
stencilDescriptor.readMask = descriptor.readMask;
|
||||
stencilDescriptor.writeMask = descriptor.writeMask;
|
||||
case CompareFunction::NEVER:
|
||||
ret = MTLCompareFunctionNever;
|
||||
break;
|
||||
case CompareFunction::LESS:
|
||||
ret = MTLCompareFunctionLess;
|
||||
break;
|
||||
case CompareFunction::LESS_EQUAL:
|
||||
ret = MTLCompareFunctionLessEqual;
|
||||
break;
|
||||
case CompareFunction::GREATER:
|
||||
ret = MTLCompareFunctionGreater;
|
||||
break;
|
||||
case CompareFunction::GREATER_EQUAL:
|
||||
ret = MTLCompareFunctionGreaterEqual;
|
||||
break;
|
||||
case CompareFunction::EQUAL:
|
||||
ret = MTLCompareFunctionEqual;
|
||||
break;
|
||||
case CompareFunction::NOT_EQUAL:
|
||||
ret = MTLCompareFunctionNotEqual;
|
||||
break;
|
||||
case CompareFunction::ALWAYS:
|
||||
ret = MTLCompareFunctionAlways;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DepthStencilStateMTL::DepthStencilStateMTL(id<MTLDevice> mtlDevice) : _mtlDevice(mtlDevice)
|
||||
MTLStencilOperation toMTLStencilOperation(StencilOperation operation)
|
||||
{
|
||||
MTLStencilOperation ret = MTLStencilOperationKeep;
|
||||
switch (operation)
|
||||
{
|
||||
case StencilOperation::KEEP:
|
||||
ret = MTLStencilOperationKeep;
|
||||
break;
|
||||
case StencilOperation::ZERO:
|
||||
ret = MTLStencilOperationZero;
|
||||
break;
|
||||
case StencilOperation::REPLACE:
|
||||
ret = MTLStencilOperationReplace;
|
||||
break;
|
||||
case StencilOperation::INVERT:
|
||||
ret = MTLStencilOperationInvert;
|
||||
break;
|
||||
case StencilOperation::INCREMENT_WRAP:
|
||||
ret = MTLStencilOperationIncrementWrap;
|
||||
break;
|
||||
case StencilOperation::DECREMENT_WRAP:
|
||||
ret = MTLStencilOperationDecrementWrap;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setMTLStencilDescriptor(MTLStencilDescriptor* stencilDescriptor, const StencilDescriptor& descriptor)
|
||||
{
|
||||
stencilDescriptor.stencilFailureOperation = toMTLStencilOperation(descriptor.stencilFailureOperation);
|
||||
stencilDescriptor.depthFailureOperation = toMTLStencilOperation(descriptor.depthFailureOperation);
|
||||
stencilDescriptor.depthStencilPassOperation = toMTLStencilOperation(descriptor.depthStencilPassOperation);
|
||||
stencilDescriptor.stencilCompareFunction = toMTLCompareFunction(descriptor.stencilCompareFunction);
|
||||
stencilDescriptor.readMask = descriptor.readMask;
|
||||
stencilDescriptor.writeMask = descriptor.writeMask;
|
||||
}
|
||||
}
|
||||
|
||||
DepthStencilStateMTL::DepthStencilStateMTL(id<MTLDevice> mtlDevice) : _mtlDevice(mtlDevice) {}
|
||||
|
||||
void DepthStencilStateMTL::update(const DepthStencilDescriptor& dsDesc)
|
||||
{
|
||||
DepthStencilState::update(dsDesc);
|
||||
|
||||
if(!isEnabled()) {
|
||||
|
||||
if (!isEnabled())
|
||||
{
|
||||
_mtlDepthStencilState = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DepthStencilDescriptor hashMe;
|
||||
memset(&hashMe, 0, sizeof(hashMe));
|
||||
hashMe.depthCompareFunction = dsDesc.depthCompareFunction;
|
||||
hashMe.backFaceStencil = dsDesc.backFaceStencil;
|
||||
hashMe.frontFaceStencil = dsDesc.frontFaceStencil;
|
||||
hashMe.flags = dsDesc.flags;
|
||||
|
||||
hashMe.backFaceStencil = dsDesc.backFaceStencil;
|
||||
hashMe.frontFaceStencil = dsDesc.frontFaceStencil;
|
||||
hashMe.flags = dsDesc.flags;
|
||||
|
||||
auto key = XXH32((const void*)&hashMe, sizeof(hashMe), 0);
|
||||
auto it = _mtlStateCache.find(key);
|
||||
if(it != _mtlStateCache.end()) {
|
||||
auto it = _mtlStateCache.find(key);
|
||||
if (it != _mtlStateCache.end())
|
||||
{
|
||||
_mtlDepthStencilState = it->second;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MTLDepthStencilDescriptor* mtlDescriptor = [[MTLDepthStencilDescriptor alloc] init];
|
||||
|
||||
if (bitmask::any(dsDesc.flags, DepthStencilFlags::DEPTH_TEST))
|
||||
|
@ -149,7 +151,7 @@ void DepthStencilStateMTL::update(const DepthStencilDescriptor& dsDesc)
|
|||
|
||||
_mtlDepthStencilState = [_mtlDevice newDepthStencilStateWithDescriptor:mtlDescriptor];
|
||||
[mtlDescriptor release];
|
||||
|
||||
|
||||
// emplace to state cache
|
||||
_mtlStateCache.emplace(key, _mtlDepthStencilState);
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ void DepthStencilStateMTL::update(const DepthStencilDescriptor& dsDesc)
|
|||
DepthStencilStateMTL::~DepthStencilStateMTL()
|
||||
{
|
||||
_mtlDepthStencilState = nullptr;
|
||||
for(auto& stateItem : _mtlStateCache)
|
||||
for (auto& stateItem : _mtlStateCache)
|
||||
[stateItem.second release];
|
||||
_mtlStateCache.clear();
|
||||
}
|
||||
|
|
|
@ -22,367 +22,367 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "DeviceInfoMTL.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "UtilsMTL.h"
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
namespace {
|
||||
int getMaxVertexAttributes(FeatureSet featureSet)
|
||||
namespace
|
||||
{
|
||||
int getMaxVertexAttributes(FeatureSet featureSet)
|
||||
{
|
||||
int maxAttributes = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
int maxAttributes = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxAttributes = 31;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return maxAttributes;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxAttributes = 31;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int getMaxTextureEntries(FeatureSet featureSet)
|
||||
return maxAttributes;
|
||||
}
|
||||
|
||||
int getMaxTextureEntries(FeatureSet featureSet)
|
||||
{
|
||||
int maxTextureEntries = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
int maxTextureEntries = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
maxTextureEntries = 31;
|
||||
break;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxTextureEntries = 128;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return maxTextureEntries;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
maxTextureEntries = 31;
|
||||
break;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxTextureEntries = 128;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int getMaxSamplerEntries(FeatureSet featureSet)
|
||||
return maxTextureEntries;
|
||||
}
|
||||
|
||||
int getMaxSamplerEntries(FeatureSet featureSet)
|
||||
{
|
||||
int maxSamplerEntries = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
int maxSamplerEntries = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxSamplerEntries = 16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return maxSamplerEntries;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxSamplerEntries = 16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int getMaxTextureWidthHeight(FeatureSet featureSet)
|
||||
return maxSamplerEntries;
|
||||
}
|
||||
|
||||
int getMaxTextureWidthHeight(FeatureSet featureSet)
|
||||
{
|
||||
int maxTextureSize = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
int maxTextureSize = 0;
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
maxTextureSize = 4096;
|
||||
break;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
maxTextureSize = 8192;
|
||||
break;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxTextureSize = 16384;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return maxTextureSize;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
maxTextureSize = 4096;
|
||||
break;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
maxTextureSize = 8192;
|
||||
break;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
maxTextureSize = 16384;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const char* featureSetToString(FeatureSet featureSet)
|
||||
return maxTextureSize;
|
||||
}
|
||||
|
||||
const char* featureSetToString(FeatureSet featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
return "iOS_GPUFamily1_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
return "iOS_GPUFamily2_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
return "iOS_GPUFamily1_v2";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
return "iOS_GPUFamily2_v2";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
return "iOS_GPUFamily1_v3";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
return "iOS_GPUFamily2_v3";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
return "iOS_GPUFamily1_v4";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
return "iOS_GPUFamily2_v4";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
return "iOS_GPUFamily1_v5";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
return "iOS_GPUFamily2_v5";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
return "iOS_GPUFamily3_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
return "iOS_GPUFamily3_v2";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
return "iOS_GPUFamily3_v3";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
return "iOS_GPUFamily4_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
return "iOS_GPUFamily3_v4";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return "iOS_GPUFamily4_v2";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
return "macOS_GPUFamily1_v1";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
return "macOS_GPUFamily1_v2";
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
return "macOS_ReadWriteTextureTier2";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
return "macOS_GPUFamily1_v3";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
return "macOS_GPUFamily1_v4";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return "macOS_GPUFamily2_v1";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
return "iOS_GPUFamily1_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
return "iOS_GPUFamily2_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
return "iOS_GPUFamily1_v2";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
return "iOS_GPUFamily2_v2";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
return "iOS_GPUFamily1_v3";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
return "iOS_GPUFamily2_v3";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
return "iOS_GPUFamily1_v4";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
return "iOS_GPUFamily2_v4";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
return "iOS_GPUFamily1_v5";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
return "iOS_GPUFamily2_v5";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
return "iOS_GPUFamily3_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
return "iOS_GPUFamily3_v2";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
return "iOS_GPUFamily3_v3";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
return "iOS_GPUFamily4_v1";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
return "iOS_GPUFamily3_v4";
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return "iOS_GPUFamily4_v2";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
return "macOS_GPUFamily1_v1";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
return "macOS_GPUFamily1_v2";
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
return "macOS_ReadWriteTextureTier2";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
return "macOS_GPUFamily1_v3";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
return "macOS_GPUFamily1_v4";
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return "macOS_GPUFamily2_v1";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool supportPVRTC(FeatureSet featureSet)
|
||||
return "";
|
||||
}
|
||||
|
||||
bool supportPVRTC(FeatureSet featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return true;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return true;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool supportEACETC(FeatureSet featureSet)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool supportEACETC(FeatureSet featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return true;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return true;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool supportASTC(FeatureSet featureSet)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool supportASTC(FeatureSet featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
return false;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return true;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
return false;
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return true;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool supportS3TC(FeatureSet featureSet)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool supportS3TC(FeatureSet featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
switch (featureSet)
|
||||
{
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return false;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily1_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily2_v5:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v2:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v3:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v1:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily3_v4:
|
||||
case FeatureSet::FeatureSet_iOS_GPUFamily4_v2:
|
||||
return false;
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v1:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v2:
|
||||
case FeatureSet::FeatureSet_macOS_ReadWriteTextureTier2:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v3:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily1_v4:
|
||||
case FeatureSet::FeatureSet_macOS_GPUFamily2_v1:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceInfoMTL::_isDepth24Stencil8PixelFormatSupported = false;
|
||||
|
||||
DeviceInfoMTL::DeviceInfoMTL(id<MTLDevice> device)
|
||||
{
|
||||
_deviceName = [device.name UTF8String];
|
||||
|
||||
_deviceName = [device.name UTF8String];
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
const FeatureSet minRequiredFeatureSet = FeatureSet::FeatureSet_iOS_GPUFamily1_v1;
|
||||
const FeatureSet maxKnownFeatureSet = FeatureSet::FeatureSet_iOS_GPUFamily4_v2;
|
||||
const FeatureSet maxKnownFeatureSet = FeatureSet::FeatureSet_iOS_GPUFamily4_v2;
|
||||
#else
|
||||
const FeatureSet minRequiredFeatureSet = FeatureSet::FeatureSet_macOS_GPUFamily1_v1;
|
||||
const FeatureSet maxKnownFeatureSet = FeatureSet::FeatureSet_macOS_GPUFamily2_v1;
|
||||
const FeatureSet maxKnownFeatureSet = FeatureSet::FeatureSet_macOS_GPUFamily2_v1;
|
||||
_isDepth24Stencil8PixelFormatSupported = [device isDepth24Stencil8PixelFormatSupported];
|
||||
#endif
|
||||
|
||||
|
||||
for (auto featureSet = maxKnownFeatureSet; featureSet >= minRequiredFeatureSet; --featureSet)
|
||||
{
|
||||
if ([device supportsFeatureSet:MTLFeatureSet(featureSet)])
|
||||
|
@ -391,17 +391,17 @@ DeviceInfoMTL::DeviceInfoMTL(id<MTLDevice> device)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UtilsMTL::initGPUTextureFormats();
|
||||
}
|
||||
|
||||
bool DeviceInfoMTL::init()
|
||||
{
|
||||
_maxAttributes = getMaxVertexAttributes(_featureSet);
|
||||
_maxAttributes = getMaxVertexAttributes(_featureSet);
|
||||
_maxSamplesAllowed = getMaxSamplerEntries(_featureSet);
|
||||
_maxTextureUnits = getMaxTextureEntries(_featureSet);
|
||||
_maxTextureSize = getMaxTextureWidthHeight(_featureSet);
|
||||
|
||||
_maxTextureUnits = getMaxTextureEntries(_featureSet);
|
||||
_maxTextureSize = getMaxTextureWidthHeight(_featureSet);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "DeviceMTL.h"
|
||||
#include "CommandBufferMTL.h"
|
||||
#include "BufferMTL.h"
|
||||
|
@ -37,12 +37,12 @@
|
|||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
CAMetalLayer* DeviceMTL::_metalLayer = nil;
|
||||
CAMetalLayer* DeviceMTL::_metalLayer = nil;
|
||||
id<CAMetalDrawable> DeviceMTL::_currentDrawable = nil;
|
||||
|
||||
Device* Device::getInstance()
|
||||
{
|
||||
if (! Device::_instance)
|
||||
if (!Device::_instance)
|
||||
Device::_instance = new DeviceMTL();
|
||||
|
||||
return Device::_instance;
|
||||
|
@ -55,9 +55,9 @@ void DeviceMTL::setCAMetalLayer(CAMetalLayer* metalLayer)
|
|||
|
||||
id<CAMetalDrawable> DeviceMTL::getCurrentDrawable()
|
||||
{
|
||||
if (! DeviceMTL::_currentDrawable)
|
||||
if (!DeviceMTL::_currentDrawable)
|
||||
DeviceMTL::_currentDrawable = [DeviceMTL::_metalLayer nextDrawable];
|
||||
|
||||
|
||||
return DeviceMTL::_currentDrawable;
|
||||
}
|
||||
|
||||
|
@ -68,10 +68,10 @@ void DeviceMTL::resetCurrentDrawable()
|
|||
|
||||
DeviceMTL::DeviceMTL()
|
||||
{
|
||||
_mtlDevice = DeviceMTL::_metalLayer.device;
|
||||
_mtlDevice = DeviceMTL::_metalLayer.device;
|
||||
_mtlCommandQueue = [_mtlDevice newCommandQueue];
|
||||
_deviceInfo = new DeviceInfoMTL(_mtlDevice);
|
||||
if(!_deviceInfo->init())
|
||||
_deviceInfo = new DeviceInfoMTL(_mtlDevice);
|
||||
if (!_deviceInfo->init())
|
||||
{
|
||||
delete _deviceInfo;
|
||||
_deviceInfo = nullptr;
|
||||
|
@ -97,15 +97,15 @@ Buffer* DeviceMTL::newBuffer(std::size_t size, BufferType type, BufferUsage usag
|
|||
|
||||
TextureBackend* DeviceMTL::newTexture(const TextureDescriptor& descriptor)
|
||||
{
|
||||
switch(descriptor.textureType)
|
||||
switch (descriptor.textureType)
|
||||
{
|
||||
case TextureType::TEXTURE_2D:
|
||||
return new TextureMTL(_mtlDevice, descriptor);
|
||||
case TextureType::TEXTURE_CUBE:
|
||||
return new TextureCubeMTL(_mtlDevice, descriptor);
|
||||
default:
|
||||
CCASSERT(false, "invalidate texture type");
|
||||
return nullptr;
|
||||
case TextureType::TEXTURE_2D:
|
||||
return new TextureMTL(_mtlDevice, descriptor);
|
||||
case TextureType::TEXTURE_CUBE:
|
||||
return new TextureCubeMTL(_mtlDevice, descriptor);
|
||||
default:
|
||||
CCASSERT(false, "invalidate texture type");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,14 +117,14 @@ RenderTarget* DeviceMTL::newDefaultRenderTarget(TargetBufferFlags rtf)
|
|||
}
|
||||
|
||||
RenderTarget* DeviceMTL::newRenderTarget(TargetBufferFlags rtf,
|
||||
TextureBackend* colorAttachment,
|
||||
TextureBackend* depthAttachment,
|
||||
TextureBackend* stencilAttachhment)
|
||||
TextureBackend* colorAttachment,
|
||||
TextureBackend* depthAttachment,
|
||||
TextureBackend* stencilAttachhment)
|
||||
{
|
||||
auto rtGL = new RenderTargetMTL(false);
|
||||
rtGL->setTargetFlags(rtf);
|
||||
rtGL->bindFrameBuffer();
|
||||
RenderTarget::ColorAttachment colors{ {colorAttachment, 0} };
|
||||
RenderTarget::ColorAttachment colors{{colorAttachment, 0}};
|
||||
rtGL->setColorAttachment(colors);
|
||||
rtGL->setDepthAttachment(depthAttachment);
|
||||
rtGL->setStencilAttachment(stencilAttachhment);
|
||||
|
|
|
@ -127,8 +127,7 @@ public:
|
|||
* Get all uniformInfos.
|
||||
* @return The uniformInfos.
|
||||
*/
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(
|
||||
ShaderStage stage) const override;
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(ShaderStage stage) const override;
|
||||
|
||||
private:
|
||||
ShaderModuleMTL* _vertexShader = nullptr;
|
||||
|
|
|
@ -21,18 +21,19 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "ProgramMTL.h"
|
||||
#include "ShaderModuleMTL.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
namespace {
|
||||
constexpr std::string_view metalSpecificDefine = "#define METAL\n"sv;
|
||||
namespace
|
||||
{
|
||||
constexpr std::string_view metalSpecificDefine = "#define METAL\n"sv;
|
||||
}
|
||||
|
||||
ProgramMTL::ProgramMTL(std::string_view vertexShader, std::string_view fragmentShader)
|
||||
: Program(vertexShader, fragmentShader)
|
||||
: Program(vertexShader, fragmentShader)
|
||||
{
|
||||
_vertexShader = static_cast<ShaderModuleMTL*>(ShaderCache::newVertexShaderModule(vertexShader));
|
||||
std::string combinedSource{metalSpecificDefine};
|
||||
|
@ -64,13 +65,13 @@ UniformLocation ProgramMTL::getUniformLocation(backend::Uniform name) const
|
|||
UniformLocation uniformLocation;
|
||||
auto vsLocation = _vertexShader->getUniformLocation(name);
|
||||
auto fsLocation = _fragmentShader->getUniformLocation(name);
|
||||
if(vsLocation != -1 && fsLocation != -1)
|
||||
if (vsLocation != -1 && fsLocation != -1)
|
||||
{
|
||||
uniformLocation.shaderStage = ShaderStage::VERTEX_AND_FRAGMENT;
|
||||
uniformLocation.location[0] = vsLocation;
|
||||
uniformLocation.location[1] = fsLocation;
|
||||
}
|
||||
else if( vsLocation != -1)
|
||||
else if (vsLocation != -1)
|
||||
{
|
||||
uniformLocation.shaderStage = ShaderStage::VERTEX;
|
||||
uniformLocation.location[0] = vsLocation;
|
||||
|
@ -88,13 +89,13 @@ UniformLocation ProgramMTL::getUniformLocation(std::string_view uniform) const
|
|||
UniformLocation uniformLocation;
|
||||
auto vsLocation = _vertexShader->getUniformLocation(uniform);
|
||||
auto fsLocation = _fragmentShader->getUniformLocation(uniform);
|
||||
if(vsLocation != -1 && fsLocation != -1)
|
||||
if (vsLocation != -1 && fsLocation != -1)
|
||||
{
|
||||
uniformLocation.shaderStage = ShaderStage::VERTEX_AND_FRAGMENT;
|
||||
uniformLocation.location[0] = vsLocation;
|
||||
uniformLocation.location[1] = fsLocation;
|
||||
}
|
||||
else if( vsLocation != -1)
|
||||
else if (vsLocation != -1)
|
||||
{
|
||||
uniformLocation.shaderStage = ShaderStage::VERTEX;
|
||||
uniformLocation.location[0] = vsLocation;
|
||||
|
@ -122,58 +123,60 @@ const std::unordered_map<std::string, AttributeBindInfo> ProgramMTL::getActiveAt
|
|||
return _vertexShader->getAttributeInfo();
|
||||
}
|
||||
|
||||
//const std::vector<char>& ProgramMTL::cloneUniformBuffer(ShaderStage stage) const
|
||||
// const std::vector<char>& ProgramMTL::cloneUniformBuffer(ShaderStage stage) const
|
||||
//{
|
||||
// switch (stage) {
|
||||
// case ShaderStage::VERTEX:
|
||||
// return _vertexShader->cloneUniformBuffer();
|
||||
// break;
|
||||
// case ShaderStage::FRAGMENT:
|
||||
// return _fragmentShader->cloneUniformBuffer();
|
||||
// default:
|
||||
// CCASSERT(false, "Invalid shader stage.");
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
// switch (stage) {
|
||||
// case ShaderStage::VERTEX:
|
||||
// return _vertexShader->cloneUniformBuffer();
|
||||
// break;
|
||||
// case ShaderStage::FRAGMENT:
|
||||
// return _fragmentShader->cloneUniformBuffer();
|
||||
// default:
|
||||
// CCASSERT(false, "Invalid shader stage.");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
const UniformInfo& ProgramMTL::getActiveUniformInfo(ShaderStage stage, int location) const
|
||||
{
|
||||
switch (stage) {
|
||||
case ShaderStage::VERTEX:
|
||||
return _vertexShader->getActiveUniform(location);
|
||||
case ShaderStage::FRAGMENT:
|
||||
return _fragmentShader->getActiveUniform(location);
|
||||
default:
|
||||
CCASSERT(false, "Invalid shader stage.");
|
||||
switch (stage)
|
||||
{
|
||||
case ShaderStage::VERTEX:
|
||||
return _vertexShader->getActiveUniform(location);
|
||||
case ShaderStage::FRAGMENT:
|
||||
return _fragmentShader->getActiveUniform(location);
|
||||
default:
|
||||
CCASSERT(false, "Invalid shader stage.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t ProgramMTL::getUniformBufferSize(ShaderStage stage) const
|
||||
{
|
||||
switch (stage) {
|
||||
case ShaderStage::VERTEX:
|
||||
return _vertexShader->getUniformBufferSize();
|
||||
case ShaderStage::FRAGMENT:
|
||||
return _fragmentShader->getUniformBufferSize();
|
||||
default:
|
||||
CCASSERT(false, "Invalid shader stage.");
|
||||
break;
|
||||
switch (stage)
|
||||
{
|
||||
case ShaderStage::VERTEX:
|
||||
return _vertexShader->getUniformBufferSize();
|
||||
case ShaderStage::FRAGMENT:
|
||||
return _fragmentShader->getUniformBufferSize();
|
||||
default:
|
||||
CCASSERT(false, "Invalid shader stage.");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, UniformInfo>& ProgramMTL::getAllActiveUniformInfo(ShaderStage stage) const
|
||||
{
|
||||
switch (stage) {
|
||||
case ShaderStage::VERTEX:
|
||||
return _vertexShader->getAllActiveUniformInfo();
|
||||
case ShaderStage::FRAGMENT:
|
||||
return _fragmentShader->getAllActiveUniformInfo();
|
||||
default:
|
||||
CCASSERT(false, "Invalid shader stage.");
|
||||
break;
|
||||
switch (stage)
|
||||
{
|
||||
case ShaderStage::VERTEX:
|
||||
return _vertexShader->getAllActiveUniformInfo();
|
||||
case ShaderStage::FRAGMENT:
|
||||
return _fragmentShader->getAllActiveUniformInfo();
|
||||
default:
|
||||
CCASSERT(false, "Invalid shader stage.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "RenderPipelineMTL.h"
|
||||
#include "DeviceMTL.h"
|
||||
#include "RenderTargetMTL.h"
|
||||
|
@ -35,133 +35,133 @@ CC_BACKEND_BEGIN
|
|||
|
||||
namespace
|
||||
{
|
||||
MTLVertexStepFunction toMTLVertexStepFunction(VertexStepMode vertexStepMode)
|
||||
{
|
||||
if (VertexStepMode::VERTEX == vertexStepMode)
|
||||
return MTLVertexStepFunctionPerVertex;
|
||||
else
|
||||
return MTLVertexStepFunctionPerInstance;
|
||||
}
|
||||
|
||||
MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat, bool needNormalize)
|
||||
{
|
||||
MTLVertexFormat ret = MTLVertexFormatFloat4;
|
||||
switch (vertexFormat)
|
||||
{
|
||||
case VertexFormat::FLOAT4:
|
||||
ret = MTLVertexFormatFloat4;
|
||||
break;
|
||||
case VertexFormat::FLOAT3:
|
||||
ret = MTLVertexFormatFloat3;
|
||||
break;
|
||||
case VertexFormat::FLOAT2:
|
||||
ret = MTLVertexFormatFloat2;
|
||||
break;
|
||||
case VertexFormat::FLOAT:
|
||||
ret = MTLVertexFormatFloat;
|
||||
break;
|
||||
case VertexFormat::INT4:
|
||||
ret = MTLVertexFormatInt4;
|
||||
break;
|
||||
case VertexFormat::INT3:
|
||||
ret = MTLVertexFormatInt3;
|
||||
break;
|
||||
case VertexFormat::INT2:
|
||||
ret = MTLVertexFormatInt2;
|
||||
break;
|
||||
case VertexFormat::INT:
|
||||
ret = MTLVertexFormatInt;
|
||||
break;
|
||||
case VertexFormat::USHORT4:
|
||||
ret = MTLVertexFormatUShort4;
|
||||
break;
|
||||
case VertexFormat::USHORT2:
|
||||
ret = MTLVertexFormatUShort2;
|
||||
break;
|
||||
case VertexFormat::UBYTE4:
|
||||
if (needNormalize)
|
||||
ret = MTLVertexFormatUChar4Normalized;
|
||||
else
|
||||
ret = MTLVertexFormatUChar4;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
MTLColorWriteMask toMTLColorWriteMask(ColorWriteMask mask)
|
||||
{
|
||||
switch (mask) {
|
||||
case ColorWriteMask::NONE:
|
||||
return MTLColorWriteMaskNone;
|
||||
case ColorWriteMask::RED:
|
||||
return MTLColorWriteMaskRed;
|
||||
case ColorWriteMask::GREEN:
|
||||
return MTLColorWriteMaskGreen;
|
||||
case ColorWriteMask::BLUE:
|
||||
return MTLColorWriteMaskBlue;
|
||||
case ColorWriteMask::ALPHA:
|
||||
return MTLColorWriteMaskAlpha;
|
||||
case ColorWriteMask::ALL:
|
||||
return MTLColorWriteMaskAll;
|
||||
}
|
||||
}
|
||||
|
||||
MTLBlendFactor toMTLBlendFactor(BlendFactor factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case BlendFactor::ZERO:
|
||||
return MTLBlendFactorZero;
|
||||
case BlendFactor::ONE:
|
||||
return MTLBlendFactorOne;
|
||||
case BlendFactor::SRC_COLOR:
|
||||
return MTLBlendFactorSourceColor;
|
||||
case BlendFactor::ONE_MINUS_SRC_COLOR:
|
||||
return MTLBlendFactorOneMinusSourceColor;
|
||||
case BlendFactor::SRC_ALPHA:
|
||||
return MTLBlendFactorSourceAlpha;
|
||||
case BlendFactor::ONE_MINUS_SRC_ALPHA:
|
||||
return MTLBlendFactorOneMinusSourceAlpha;
|
||||
case BlendFactor::DST_COLOR:
|
||||
return MTLBlendFactorDestinationColor;
|
||||
case BlendFactor::ONE_MINUS_DST_COLOR:
|
||||
return MTLBlendFactorOneMinusDestinationColor;
|
||||
case BlendFactor::DST_ALPHA:
|
||||
return MTLBlendFactorDestinationAlpha;
|
||||
case BlendFactor::ONE_MINUS_DST_ALPHA:
|
||||
return MTLBlendFactorOneMinusDestinationAlpha;
|
||||
case BlendFactor::SRC_ALPHA_SATURATE:
|
||||
return MTLBlendFactorSourceAlphaSaturated;
|
||||
case BlendFactor::BLEND_CLOLOR:
|
||||
return MTLBlendFactorBlendColor;
|
||||
default:
|
||||
return MTLBlendFactorZero;
|
||||
}
|
||||
}
|
||||
|
||||
MTLBlendOperation toMTLBlendOperation(BlendOperation operation)
|
||||
{
|
||||
switch (operation) {
|
||||
case BlendOperation::ADD:
|
||||
return MTLBlendOperationAdd;
|
||||
case BlendOperation::SUBTRACT:
|
||||
return MTLBlendOperationSubtract;
|
||||
case BlendOperation::RESERVE_SUBTRACT:
|
||||
return MTLBlendOperationReverseSubtract;
|
||||
default:
|
||||
return MTLBlendOperationAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipelineMTL::RenderPipelineMTL(id<MTLDevice> mtlDevice)
|
||||
: _mtlDevice(mtlDevice)
|
||||
MTLVertexStepFunction toMTLVertexStepFunction(VertexStepMode vertexStepMode)
|
||||
{
|
||||
if (VertexStepMode::VERTEX == vertexStepMode)
|
||||
return MTLVertexStepFunctionPerVertex;
|
||||
else
|
||||
return MTLVertexStepFunctionPerInstance;
|
||||
}
|
||||
|
||||
void RenderPipelineMTL::update(const RenderTarget* renderTarget, const PipelineDescriptor & pipelineDescirptor)
|
||||
MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat, bool needNormalize)
|
||||
{
|
||||
MTLVertexFormat ret = MTLVertexFormatFloat4;
|
||||
switch (vertexFormat)
|
||||
{
|
||||
case VertexFormat::FLOAT4:
|
||||
ret = MTLVertexFormatFloat4;
|
||||
break;
|
||||
case VertexFormat::FLOAT3:
|
||||
ret = MTLVertexFormatFloat3;
|
||||
break;
|
||||
case VertexFormat::FLOAT2:
|
||||
ret = MTLVertexFormatFloat2;
|
||||
break;
|
||||
case VertexFormat::FLOAT:
|
||||
ret = MTLVertexFormatFloat;
|
||||
break;
|
||||
case VertexFormat::INT4:
|
||||
ret = MTLVertexFormatInt4;
|
||||
break;
|
||||
case VertexFormat::INT3:
|
||||
ret = MTLVertexFormatInt3;
|
||||
break;
|
||||
case VertexFormat::INT2:
|
||||
ret = MTLVertexFormatInt2;
|
||||
break;
|
||||
case VertexFormat::INT:
|
||||
ret = MTLVertexFormatInt;
|
||||
break;
|
||||
case VertexFormat::USHORT4:
|
||||
ret = MTLVertexFormatUShort4;
|
||||
break;
|
||||
case VertexFormat::USHORT2:
|
||||
ret = MTLVertexFormatUShort2;
|
||||
break;
|
||||
case VertexFormat::UBYTE4:
|
||||
if (needNormalize)
|
||||
ret = MTLVertexFormatUChar4Normalized;
|
||||
else
|
||||
ret = MTLVertexFormatUChar4;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
MTLColorWriteMask toMTLColorWriteMask(ColorWriteMask mask)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case ColorWriteMask::NONE:
|
||||
return MTLColorWriteMaskNone;
|
||||
case ColorWriteMask::RED:
|
||||
return MTLColorWriteMaskRed;
|
||||
case ColorWriteMask::GREEN:
|
||||
return MTLColorWriteMaskGreen;
|
||||
case ColorWriteMask::BLUE:
|
||||
return MTLColorWriteMaskBlue;
|
||||
case ColorWriteMask::ALPHA:
|
||||
return MTLColorWriteMaskAlpha;
|
||||
case ColorWriteMask::ALL:
|
||||
return MTLColorWriteMaskAll;
|
||||
}
|
||||
}
|
||||
|
||||
MTLBlendFactor toMTLBlendFactor(BlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case BlendFactor::ZERO:
|
||||
return MTLBlendFactorZero;
|
||||
case BlendFactor::ONE:
|
||||
return MTLBlendFactorOne;
|
||||
case BlendFactor::SRC_COLOR:
|
||||
return MTLBlendFactorSourceColor;
|
||||
case BlendFactor::ONE_MINUS_SRC_COLOR:
|
||||
return MTLBlendFactorOneMinusSourceColor;
|
||||
case BlendFactor::SRC_ALPHA:
|
||||
return MTLBlendFactorSourceAlpha;
|
||||
case BlendFactor::ONE_MINUS_SRC_ALPHA:
|
||||
return MTLBlendFactorOneMinusSourceAlpha;
|
||||
case BlendFactor::DST_COLOR:
|
||||
return MTLBlendFactorDestinationColor;
|
||||
case BlendFactor::ONE_MINUS_DST_COLOR:
|
||||
return MTLBlendFactorOneMinusDestinationColor;
|
||||
case BlendFactor::DST_ALPHA:
|
||||
return MTLBlendFactorDestinationAlpha;
|
||||
case BlendFactor::ONE_MINUS_DST_ALPHA:
|
||||
return MTLBlendFactorOneMinusDestinationAlpha;
|
||||
case BlendFactor::SRC_ALPHA_SATURATE:
|
||||
return MTLBlendFactorSourceAlphaSaturated;
|
||||
case BlendFactor::BLEND_CLOLOR:
|
||||
return MTLBlendFactorBlendColor;
|
||||
default:
|
||||
return MTLBlendFactorZero;
|
||||
}
|
||||
}
|
||||
|
||||
MTLBlendOperation toMTLBlendOperation(BlendOperation operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case BlendOperation::ADD:
|
||||
return MTLBlendOperationAdd;
|
||||
case BlendOperation::SUBTRACT:
|
||||
return MTLBlendOperationSubtract;
|
||||
case BlendOperation::RESERVE_SUBTRACT:
|
||||
return MTLBlendOperationReverseSubtract;
|
||||
default:
|
||||
return MTLBlendOperationAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipelineMTL::RenderPipelineMTL(id<MTLDevice> mtlDevice) : _mtlDevice(mtlDevice) {}
|
||||
|
||||
void RenderPipelineMTL::update(const RenderTarget* renderTarget, const PipelineDescriptor& pipelineDescirptor)
|
||||
{
|
||||
struct
|
||||
{
|
||||
|
@ -179,135 +179,140 @@ void RenderPipelineMTL::update(const RenderTarget* renderTarget, const PipelineD
|
|||
unsigned int destinationRGBBlendFactor;
|
||||
unsigned int sourceAlphaBlendFactor;
|
||||
unsigned int destinationAlphaBlendFactor;
|
||||
}hashMe;
|
||||
|
||||
} hashMe;
|
||||
|
||||
memset(&hashMe, 0, sizeof(hashMe));
|
||||
const auto& blendDescriptor = pipelineDescirptor.blendDescriptor;
|
||||
chooseAttachmentFormat(renderTarget, _colorAttachmentsFormat, _depthAttachmentFormat, _stencilAttachmentFormat);
|
||||
auto program = static_cast<ProgramMTL*>(pipelineDescirptor.programState->getProgram());
|
||||
hashMe.vertexShaderHash = program->getVertexShader()->getHashValue();
|
||||
auto program = static_cast<ProgramMTL*>(pipelineDescirptor.programState->getProgram());
|
||||
hashMe.vertexShaderHash = program->getVertexShader()->getHashValue();
|
||||
hashMe.fragmentShaderHash = program->getFragmentShader()->getHashValue();
|
||||
memcpy(&hashMe.colorAttachment, &_colorAttachmentsFormat, sizeof(_colorAttachmentsFormat));
|
||||
hashMe.depthAttachment = _depthAttachmentFormat;
|
||||
hashMe.stencilAttachment =_stencilAttachmentFormat;
|
||||
hashMe.blendEnabled = blendDescriptor.blendEnabled;
|
||||
hashMe.writeMask = (unsigned int)blendDescriptor.writeMask;
|
||||
hashMe.rgbBlendOperation = (unsigned int)blendDescriptor.rgbBlendOperation;
|
||||
hashMe.alphaBlendOperation = (unsigned int)blendDescriptor.alphaBlendOperation;
|
||||
hashMe.sourceRGBBlendFactor = (unsigned int)blendDescriptor.sourceRGBBlendFactor;
|
||||
hashMe.destinationRGBBlendFactor = (unsigned int)blendDescriptor.destinationRGBBlendFactor;
|
||||
hashMe.sourceAlphaBlendFactor = (unsigned int)blendDescriptor.sourceAlphaBlendFactor;
|
||||
hashMe.depthAttachment = _depthAttachmentFormat;
|
||||
hashMe.stencilAttachment = _stencilAttachmentFormat;
|
||||
hashMe.blendEnabled = blendDescriptor.blendEnabled;
|
||||
hashMe.writeMask = (unsigned int)blendDescriptor.writeMask;
|
||||
hashMe.rgbBlendOperation = (unsigned int)blendDescriptor.rgbBlendOperation;
|
||||
hashMe.alphaBlendOperation = (unsigned int)blendDescriptor.alphaBlendOperation;
|
||||
hashMe.sourceRGBBlendFactor = (unsigned int)blendDescriptor.sourceRGBBlendFactor;
|
||||
hashMe.destinationRGBBlendFactor = (unsigned int)blendDescriptor.destinationRGBBlendFactor;
|
||||
hashMe.sourceAlphaBlendFactor = (unsigned int)blendDescriptor.sourceAlphaBlendFactor;
|
||||
hashMe.destinationAlphaBlendFactor = (unsigned int)blendDescriptor.destinationAlphaBlendFactor;
|
||||
int index = 0;
|
||||
auto vertexLayout = pipelineDescirptor.programState->getVertexLayout();
|
||||
const auto& attributes = vertexLayout->getAttributes();
|
||||
int index = 0;
|
||||
auto vertexLayout = pipelineDescirptor.programState->getVertexLayout();
|
||||
const auto& attributes = vertexLayout->getAttributes();
|
||||
for (const auto& it : attributes)
|
||||
{
|
||||
auto &attribute = it.second;
|
||||
auto& attribute = it.second;
|
||||
/*
|
||||
stepFunction:1 stride:15 offest:10 format:5 needNormalized:1
|
||||
bit31 bit30 ~ bit16 bit15 ~ bit6 bit5 ~ bit1 bit0
|
||||
*/
|
||||
hashMe.vertexLayoutInfo[index++] =
|
||||
((unsigned int)vertexLayout->getVertexStepMode() & 0x1) << 31 |
|
||||
((unsigned int)(vertexLayout->getStride() & 0x7FFF)) << 16 |
|
||||
((unsigned int)attribute.offset & 0x3FF) << 6 |
|
||||
((unsigned int)attribute.format & 0x1F) << 1 |
|
||||
((unsigned int)attribute.needToBeNormallized & 0x1);
|
||||
((unsigned int)vertexLayout->getVertexStepMode() & 0x1) << 31 |
|
||||
((unsigned int)(vertexLayout->getStride() & 0x7FFF)) << 16 | ((unsigned int)attribute.offset & 0x3FF) << 6 |
|
||||
((unsigned int)attribute.format & 0x1F) << 1 | ((unsigned int)attribute.needToBeNormallized & 0x1);
|
||||
}
|
||||
|
||||
|
||||
unsigned int hash = XXH32((const void*)&hashMe, sizeof(hashMe), 0);
|
||||
auto it = _mtlStateCache.find(hash);
|
||||
if(it != _mtlStateCache.end()) {
|
||||
auto it = _mtlStateCache.find(hash);
|
||||
if (it != _mtlStateCache.end())
|
||||
{
|
||||
_mtlRenderPipelineState = it->second;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
_mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||
|
||||
|
||||
setShaderModules(pipelineDescirptor);
|
||||
setVertexLayout(_mtlRenderPipelineDescriptor, pipelineDescirptor);
|
||||
|
||||
|
||||
setBlendStateAndFormat(pipelineDescirptor.blendDescriptor);
|
||||
|
||||
NSError *error = nil;
|
||||
_mtlRenderPipelineState = [_mtlDevice newRenderPipelineStateWithDescriptor:_mtlRenderPipelineDescriptor error:&error];
|
||||
|
||||
NSError* error = nil;
|
||||
_mtlRenderPipelineState = [_mtlDevice newRenderPipelineStateWithDescriptor:_mtlRenderPipelineDescriptor
|
||||
error:&error];
|
||||
if (error)
|
||||
NSLog(@"Can not create renderpipeline state: %@", error);
|
||||
|
||||
|
||||
[_mtlRenderPipelineDescriptor release];
|
||||
|
||||
|
||||
_mtlStateCache.emplace(hash, _mtlRenderPipelineState);
|
||||
}
|
||||
|
||||
RenderPipelineMTL::~RenderPipelineMTL()
|
||||
{
|
||||
for(auto& item : _mtlStateCache)
|
||||
for (auto& item : _mtlStateCache)
|
||||
[item.second release];
|
||||
}
|
||||
|
||||
void RenderPipelineMTL::setVertexLayout(MTLRenderPipelineDescriptor* mtlDescriptor, const PipelineDescriptor& descriptor)
|
||||
void RenderPipelineMTL::setVertexLayout(MTLRenderPipelineDescriptor* mtlDescriptor,
|
||||
const PipelineDescriptor& descriptor)
|
||||
{
|
||||
int vertexIndex = 0;
|
||||
int vertexIndex = 0;
|
||||
auto vertexLayout = descriptor.programState->getVertexLayout();
|
||||
if (!vertexLayout->isValid())
|
||||
return;
|
||||
|
||||
|
||||
mtlDescriptor.vertexDescriptor.layouts[vertexIndex].stride = vertexLayout->getStride();
|
||||
mtlDescriptor.vertexDescriptor.layouts[vertexIndex].stepFunction = toMTLVertexStepFunction(vertexLayout->getVertexStepMode());
|
||||
|
||||
mtlDescriptor.vertexDescriptor.layouts[vertexIndex].stepFunction =
|
||||
toMTLVertexStepFunction(vertexLayout->getVertexStepMode());
|
||||
|
||||
const auto& attributes = vertexLayout->getAttributes();
|
||||
for (const auto& it : attributes)
|
||||
{
|
||||
auto attribute = it.second;
|
||||
mtlDescriptor.vertexDescriptor.attributes[attribute.index].format = toMTLVertexFormat(attribute.format, attribute.needToBeNormallized);
|
||||
mtlDescriptor.vertexDescriptor.attributes[attribute.index].format =
|
||||
toMTLVertexFormat(attribute.format, attribute.needToBeNormallized);
|
||||
mtlDescriptor.vertexDescriptor.attributes[attribute.index].offset = attribute.offset;
|
||||
// Buffer index will always be 0;
|
||||
mtlDescriptor.vertexDescriptor.attributes[attribute.index].bufferIndex = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RenderPipelineMTL::setBlendState(MTLRenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor,
|
||||
const BlendDescriptor& blendDescriptor)
|
||||
{
|
||||
colorAttachmentDescriptor.blendingEnabled = blendDescriptor.blendEnabled;
|
||||
colorAttachmentDescriptor.writeMask = toMTLColorWriteMask(blendDescriptor.writeMask);
|
||||
|
||||
colorAttachmentDescriptor.rgbBlendOperation = toMTLBlendOperation(blendDescriptor.rgbBlendOperation);
|
||||
colorAttachmentDescriptor.writeMask = toMTLColorWriteMask(blendDescriptor.writeMask);
|
||||
|
||||
colorAttachmentDescriptor.rgbBlendOperation = toMTLBlendOperation(blendDescriptor.rgbBlendOperation);
|
||||
colorAttachmentDescriptor.alphaBlendOperation = toMTLBlendOperation(blendDescriptor.alphaBlendOperation);
|
||||
|
||||
colorAttachmentDescriptor.sourceRGBBlendFactor = toMTLBlendFactor(blendDescriptor.sourceRGBBlendFactor);
|
||||
|
||||
colorAttachmentDescriptor.sourceRGBBlendFactor = toMTLBlendFactor(blendDescriptor.sourceRGBBlendFactor);
|
||||
colorAttachmentDescriptor.destinationRGBBlendFactor = toMTLBlendFactor(blendDescriptor.destinationRGBBlendFactor);
|
||||
colorAttachmentDescriptor.sourceAlphaBlendFactor = toMTLBlendFactor(blendDescriptor.sourceAlphaBlendFactor);
|
||||
colorAttachmentDescriptor.destinationAlphaBlendFactor = toMTLBlendFactor(blendDescriptor.destinationAlphaBlendFactor);
|
||||
colorAttachmentDescriptor.sourceAlphaBlendFactor = toMTLBlendFactor(blendDescriptor.sourceAlphaBlendFactor);
|
||||
colorAttachmentDescriptor.destinationAlphaBlendFactor =
|
||||
toMTLBlendFactor(blendDescriptor.destinationAlphaBlendFactor);
|
||||
}
|
||||
|
||||
void RenderPipelineMTL::setShaderModules(const PipelineDescriptor& descriptor)
|
||||
{
|
||||
auto vertexShaderModule = static_cast<ProgramMTL*>(descriptor.programState->getProgram())->getVertexShader();
|
||||
_mtlRenderPipelineDescriptor.vertexFunction = vertexShaderModule->getMTLFunction();
|
||||
|
||||
|
||||
auto fragShaderModule = static_cast<ProgramMTL*>(descriptor.programState->getProgram())->getFragmentShader();
|
||||
_mtlRenderPipelineDescriptor.fragmentFunction = fragShaderModule->getMTLFunction();
|
||||
}
|
||||
|
||||
void RenderPipelineMTL::chooseAttachmentFormat(const RenderTarget* renderTarget,
|
||||
PixelFormat colorAttachmentsFormat[MAX_COLOR_ATTCHMENT],
|
||||
PixelFormat& depthFormat,
|
||||
PixelFormat& stencilFormat)
|
||||
PixelFormat colorAttachmentsFormat[MAX_COLOR_ATTCHMENT],
|
||||
PixelFormat& depthFormat,
|
||||
PixelFormat& stencilFormat)
|
||||
{
|
||||
// Choose color attachment format
|
||||
auto rtMTL = static_cast<const RenderTargetMTL*>(renderTarget);
|
||||
auto rtMTL = static_cast<const RenderTargetMTL*>(renderTarget);
|
||||
auto rtflags = rtMTL->getTargetFlags();
|
||||
for(auto i = 0; i < MAX_COLOR_ATTCHMENT; ++i) {
|
||||
colorAttachmentsFormat[i] = bitmask::any(rtflags, getMRTColorFlag(i)) ? rtMTL->getColorAttachmentPixelFormat(i) : PixelFormat::NONE;
|
||||
for (auto i = 0; i < MAX_COLOR_ATTCHMENT; ++i)
|
||||
{
|
||||
colorAttachmentsFormat[i] =
|
||||
bitmask::any(rtflags, getMRTColorFlag(i)) ? rtMTL->getColorAttachmentPixelFormat(i) : PixelFormat::NONE;
|
||||
}
|
||||
|
||||
|
||||
if (bitmask::any(rtflags, RenderTargetFlag::DEPTH_AND_STENCIL))
|
||||
{
|
||||
depthFormat = rtMTL->getDepthAttachmentPixelFormat();
|
||||
stencilFormat =rtMTL->getStencilAttachmentPixelFormat();
|
||||
depthFormat = rtMTL->getDepthAttachmentPixelFormat();
|
||||
stencilFormat = rtMTL->getStencilAttachmentPixelFormat();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -319,15 +324,17 @@ void RenderPipelineMTL::setBlendStateAndFormat(const BlendDescriptor& blendDescr
|
|||
{
|
||||
for (int i = 0; i < MAX_COLOR_ATTCHMENT; ++i)
|
||||
{
|
||||
if (PixelFormat::NONE == _colorAttachmentsFormat[i]) {
|
||||
if (PixelFormat::NONE == _colorAttachmentsFormat[i])
|
||||
{
|
||||
_mtlRenderPipelineDescriptor.colorAttachments[i].pixelFormat = MTLPixelFormat::MTLPixelFormatInvalid;
|
||||
continue;
|
||||
}
|
||||
|
||||
_mtlRenderPipelineDescriptor.colorAttachments[i].pixelFormat = UtilsMTL::toMTLPixelFormat(_colorAttachmentsFormat[i]);
|
||||
|
||||
_mtlRenderPipelineDescriptor.colorAttachments[i].pixelFormat =
|
||||
UtilsMTL::toMTLPixelFormat(_colorAttachmentsFormat[i]);
|
||||
setBlendState(_mtlRenderPipelineDescriptor.colorAttachments[i], blendDescriptor);
|
||||
}
|
||||
_mtlRenderPipelineDescriptor.depthAttachmentPixelFormat = UtilsMTL::toMTLPixelFormat(_depthAttachmentFormat);
|
||||
_mtlRenderPipelineDescriptor.depthAttachmentPixelFormat = UtilsMTL::toMTLPixelFormat(_depthAttachmentFormat);
|
||||
_mtlRenderPipelineDescriptor.stencilAttachmentPixelFormat = UtilsMTL::toMTLPixelFormat(_stencilAttachmentFormat);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,83 +3,77 @@
|
|||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
static MTLLoadAction getLoadAction(const RenderPassDescriptor& params,
|
||||
TargetBufferFlags buffer) {
|
||||
const auto clearFlags = (TargetBufferFlags) params.flags.clear;
|
||||
static MTLLoadAction getLoadAction(const RenderPassDescriptor& params, TargetBufferFlags buffer)
|
||||
{
|
||||
const auto clearFlags = (TargetBufferFlags)params.flags.clear;
|
||||
const auto discardStartFlags = params.flags.discardStart;
|
||||
if (bitmask::any(clearFlags, buffer)) {
|
||||
if (bitmask::any(clearFlags, buffer))
|
||||
{
|
||||
return MTLLoadActionClear;
|
||||
} else if (bitmask::any(discardStartFlags, buffer)) {
|
||||
}
|
||||
else if (bitmask::any(discardStartFlags, buffer))
|
||||
{
|
||||
return MTLLoadActionDontCare;
|
||||
}
|
||||
return MTLLoadActionLoad;
|
||||
}
|
||||
|
||||
static MTLStoreAction getStoreAction(const RenderPassDescriptor& params,
|
||||
TargetBufferFlags buffer) {
|
||||
static MTLStoreAction getStoreAction(const RenderPassDescriptor& params, TargetBufferFlags buffer)
|
||||
{
|
||||
const auto discardEndFlags = params.flags.discardEnd;
|
||||
if (bitmask::any(discardEndFlags, buffer)) {
|
||||
if (bitmask::any(discardEndFlags, buffer))
|
||||
{
|
||||
return MTLStoreActionDontCare;
|
||||
}
|
||||
return MTLStoreActionStore;
|
||||
}
|
||||
|
||||
RenderTargetMTL::RenderTargetMTL(bool defaultRenderTarget) : RenderTarget(defaultRenderTarget)
|
||||
{
|
||||
|
||||
}
|
||||
RenderTargetMTL::~RenderTargetMTL()
|
||||
{
|
||||
}
|
||||
RenderTargetMTL::RenderTargetMTL(bool defaultRenderTarget) : RenderTarget(defaultRenderTarget) {}
|
||||
RenderTargetMTL::~RenderTargetMTL() {}
|
||||
|
||||
void RenderTargetMTL::bindFrameBuffer() const
|
||||
{
|
||||
}
|
||||
void RenderTargetMTL::bindFrameBuffer() const {}
|
||||
|
||||
void RenderTargetMTL::unbindFrameBuffer() const
|
||||
{
|
||||
}
|
||||
void RenderTargetMTL::unbindFrameBuffer() const {}
|
||||
void RenderTargetMTL::setColorAttachment(ColorAttachment attachment)
|
||||
{
|
||||
RenderTarget::setColorAttachment(attachment);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RenderTargetMTL::setDepthAttachment(TextureBackend* attachment, int level)
|
||||
{
|
||||
RenderTarget::setDepthAttachment(attachment, level);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RenderTargetMTL::setStencilAttachment(TextureBackend* attachment, int level)
|
||||
{
|
||||
RenderTarget::setStencilAttachment(attachment, level);
|
||||
|
||||
}
|
||||
|
||||
void RenderTargetMTL::applyRenderPassAttachments(const RenderPassDescriptor& params, MTLRenderPassDescriptor* descriptor) const
|
||||
void RenderTargetMTL::applyRenderPassAttachments(const RenderPassDescriptor& params,
|
||||
MTLRenderPassDescriptor* descriptor) const
|
||||
{
|
||||
// const auto discardFlags = params.flags.discardEnd;
|
||||
auto clearFlags = params.flags.clear;
|
||||
|
||||
for (size_t i = 0; i < MAX_COLOR_ATTCHMENT; i++) {
|
||||
|
||||
for (size_t i = 0; i < MAX_COLOR_ATTCHMENT; i++)
|
||||
{
|
||||
auto attachment = getColorAttachment(i);
|
||||
if (!attachment) {
|
||||
if (!attachment)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const auto MRTColorFlag = getMRTColorFlag(i);
|
||||
|
||||
|
||||
descriptor.colorAttachments[i].texture = attachment.texture;
|
||||
descriptor.colorAttachments[i].level = attachment.level;
|
||||
descriptor.colorAttachments[i].level = attachment.level;
|
||||
// descriptor.colorAttachments[i].slice = attachment.layer;
|
||||
descriptor.colorAttachments[i].loadAction = getLoadAction(params, MRTColorFlag);
|
||||
descriptor.colorAttachments[i].storeAction = getStoreAction(params,MRTColorFlag);
|
||||
if(bitmask::any(clearFlags, MRTColorFlag))
|
||||
descriptor.colorAttachments[i].clearColor = MTLClearColorMake(
|
||||
params.clearColorValue[0], params.clearColorValue[1], params.clearColorValue[2], params.clearColorValue[3]);
|
||||
descriptor.colorAttachments[i].loadAction = getLoadAction(params, MRTColorFlag);
|
||||
descriptor.colorAttachments[i].storeAction = getStoreAction(params, MRTColorFlag);
|
||||
if (bitmask::any(clearFlags, MRTColorFlag))
|
||||
descriptor.colorAttachments[i].clearColor =
|
||||
MTLClearColorMake(params.clearColorValue[0], params.clearColorValue[1], params.clearColorValue[2],
|
||||
params.clearColorValue[3]);
|
||||
#if 0
|
||||
if (multisampledColor[i]) {
|
||||
// We're rendering into our temporary MSAA texture and doing an automatic resolve.
|
||||
|
@ -99,32 +93,35 @@ void RenderTargetMTL::applyRenderPassAttachments(const RenderPassDescriptor& par
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Sets descriptor depth and stencil params, should match RenderTargetMTL::chooseAttachmentFormat
|
||||
if(bitmask::any(this->_flags, RenderTargetFlag::DEPTH_AND_STENCIL)) {
|
||||
if (bitmask::any(this->_flags, RenderTargetFlag::DEPTH_AND_STENCIL))
|
||||
{
|
||||
auto depthAttachment = getDepthAttachment();
|
||||
if(depthAttachment){
|
||||
if (depthAttachment)
|
||||
{
|
||||
descriptor.depthAttachment.texture = depthAttachment.texture;
|
||||
descriptor.depthAttachment.level = depthAttachment.level;
|
||||
descriptor.depthAttachment.level = depthAttachment.level;
|
||||
// descriptor.depthAttachment.slice = depthAttachment.layer;
|
||||
descriptor.depthAttachment.loadAction = getLoadAction(params, TargetBufferFlags::DEPTH);
|
||||
descriptor.depthAttachment.loadAction = getLoadAction(params, TargetBufferFlags::DEPTH);
|
||||
descriptor.depthAttachment.storeAction = getStoreAction(params, TargetBufferFlags::DEPTH);
|
||||
if(bitmask::any(clearFlags, TargetBufferFlags::DEPTH))
|
||||
if (bitmask::any(clearFlags, TargetBufferFlags::DEPTH))
|
||||
descriptor.depthAttachment.clearDepth = params.clearDepthValue;
|
||||
}
|
||||
|
||||
|
||||
auto stencilAttachment = getStencilAttachment();
|
||||
if(stencilAttachment) {
|
||||
if (stencilAttachment)
|
||||
{
|
||||
descriptor.stencilAttachment.texture = stencilAttachment.texture;
|
||||
descriptor.stencilAttachment.level = stencilAttachment.level;
|
||||
descriptor.stencilAttachment.level = stencilAttachment.level;
|
||||
// descriptor.stencilAttachment.slice = depthAttachment.layer;
|
||||
descriptor.stencilAttachment.loadAction = getLoadAction(params, TargetBufferFlags::STENCIL);
|
||||
descriptor.stencilAttachment.loadAction = getLoadAction(params, TargetBufferFlags::STENCIL);
|
||||
descriptor.stencilAttachment.storeAction = getStoreAction(params, TargetBufferFlags::STENCIL);
|
||||
if(bitmask::any(clearFlags, TargetBufferFlags::STENCIL))
|
||||
if (bitmask::any(clearFlags, TargetBufferFlags::STENCIL))
|
||||
descriptor.stencilAttachment.clearStencil = params.clearStencilValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (multisampledDepth) {
|
||||
// We're rendering into our temporary MSAA texture and doing an automatic resolve.
|
||||
|
@ -147,15 +144,16 @@ void RenderTargetMTL::applyRenderPassAttachments(const RenderPassDescriptor& par
|
|||
|
||||
RenderTargetMTL::Attachment RenderTargetMTL::getColorAttachment(int index) const
|
||||
{
|
||||
if(isDefaultRenderTarget() && index == 0)
|
||||
if (isDefaultRenderTarget() && index == 0)
|
||||
return {DeviceMTL::getCurrentDrawable().texture, 0};
|
||||
auto& rb = this->_color[index];
|
||||
return RenderTargetMTL::Attachment{static_cast<bool>(rb) ? (id<MTLTexture>)(rb.texture->getHandler()) : nil, rb.level};
|
||||
return RenderTargetMTL::Attachment{static_cast<bool>(rb) ? (id<MTLTexture>)(rb.texture->getHandler()) : nil,
|
||||
rb.level};
|
||||
}
|
||||
|
||||
RenderTargetMTL::Attachment RenderTargetMTL::getDepthAttachment() const
|
||||
{
|
||||
if(isDefaultRenderTarget())
|
||||
if (isDefaultRenderTarget())
|
||||
return {UtilsMTL::getDefaultDepthStencilTexture(), 0};
|
||||
auto& rb = this->_depth;
|
||||
return RenderTargetMTL::Attachment{!!rb ? (id<MTLTexture>)(rb.texture->getHandler()) : nil, rb.level};
|
||||
|
@ -163,7 +161,7 @@ RenderTargetMTL::Attachment RenderTargetMTL::getDepthAttachment() const
|
|||
|
||||
RenderTargetMTL::Attachment RenderTargetMTL::getStencilAttachment() const
|
||||
{
|
||||
if(isDefaultRenderTarget())
|
||||
if (isDefaultRenderTarget())
|
||||
return RenderTargetMTL::Attachment{UtilsMTL::getDefaultDepthStencilTexture(), 0};
|
||||
auto& rb = this->_stencil;
|
||||
return RenderTargetMTL::Attachment{!!rb ? (id<MTLTexture>)(rb.texture->getHandler()) : nil, rb.level};
|
||||
|
@ -173,16 +171,17 @@ PixelFormat RenderTargetMTL::getColorAttachmentPixelFormat(int index) const
|
|||
{
|
||||
// !!!important
|
||||
// the default framebuffer pixel format is: MTLPixelFormatBGRA8Unorm
|
||||
if(isDefaultRenderTarget() && index == 0)
|
||||
if (isDefaultRenderTarget() && index == 0)
|
||||
return PixelFormat::BGRA8;
|
||||
auto& rb = this->_color[index];
|
||||
return rb ? rb.texture->getTextureFormat() : PixelFormat::NONE;
|
||||
}
|
||||
|
||||
PixelFormat RenderTargetMTL::getDepthAttachmentPixelFormat() const
|
||||
{ // FIXME: adxe only support D24S8
|
||||
if(bitmask::any(_flags, TargetBufferFlags::DEPTH_AND_STENCIL)) {
|
||||
if(isDefaultRenderTarget() || !_depth)
|
||||
{ // FIXME: adxe only support D24S8
|
||||
if (bitmask::any(_flags, TargetBufferFlags::DEPTH_AND_STENCIL))
|
||||
{
|
||||
if (isDefaultRenderTarget() || !_depth)
|
||||
return PixelFormat::D24S8;
|
||||
return _depth.texture->getTextureFormat();
|
||||
}
|
||||
|
@ -190,9 +189,10 @@ PixelFormat RenderTargetMTL::getDepthAttachmentPixelFormat() const
|
|||
}
|
||||
|
||||
PixelFormat RenderTargetMTL::getStencilAttachmentPixelFormat() const
|
||||
{ // FIXME: adxe only support D24S8
|
||||
if(bitmask::any(_flags, TargetBufferFlags::DEPTH_AND_STENCIL)) {
|
||||
if(isDefaultRenderTarget() || !_stencil)
|
||||
{ // FIXME: adxe only support D24S8
|
||||
if (bitmask::any(_flags, TargetBufferFlags::DEPTH_AND_STENCIL))
|
||||
{
|
||||
if (isDefaultRenderTarget() || !_stencil)
|
||||
return PixelFormat::D24S8;
|
||||
return _stencil.texture->getTextureFormat();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "ShaderModuleMTL.h"
|
||||
#include "DeviceMTL.h"
|
||||
|
||||
|
@ -30,20 +30,20 @@
|
|||
CC_BACKEND_BEGIN
|
||||
|
||||
ShaderModuleMTL::ShaderModuleMTL(id<MTLDevice> mtlDevice, ShaderStage stage, std::string_view source)
|
||||
: ShaderModule(stage)
|
||||
: ShaderModule(stage)
|
||||
{
|
||||
// Convert GLSL shader to metal shader
|
||||
//TODO: don't crreate/destroy ctx every time.
|
||||
glslopt_ctx* ctx = glslopt_initialize(kGlslTargetMetal);
|
||||
// TODO: don't crreate/destroy ctx every time.
|
||||
glslopt_ctx* ctx = glslopt_initialize(kGlslTargetMetal);
|
||||
glslopt_shader_type shaderType = stage == ShaderStage::VERTEX ? kGlslOptShaderVertex : kGlslOptShaderFragment;
|
||||
glslopt_shader* glslShader = glslopt_optimize(ctx, shaderType, source.data(), 0);
|
||||
glslopt_shader* glslShader = glslopt_optimize(ctx, shaderType, source.data(), 0);
|
||||
if (!glslShader)
|
||||
{
|
||||
NSLog(@"Can not translate GLSL shader to metal shader:");
|
||||
NSLog(@"%s", source.data());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const char* metalShader = glslopt_get_output(glslShader);
|
||||
if (!metalShader)
|
||||
{
|
||||
|
@ -52,20 +52,18 @@ ShaderModuleMTL::ShaderModuleMTL(id<MTLDevice> mtlDevice, ShaderStage stage, std
|
|||
glslopt_cleanup(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// NSLog(@"%s", metalShader);
|
||||
|
||||
|
||||
// NSLog(@"%s", metalShader);
|
||||
|
||||
parseAttibute(mtlDevice, glslShader);
|
||||
parseUniform(mtlDevice, glslShader);
|
||||
parseTexture(mtlDevice, glslShader);
|
||||
setBuiltinUniformLocation();
|
||||
setBuiltinAttributeLocation();
|
||||
|
||||
|
||||
NSString* shader = [NSString stringWithUTF8String:metalShader];
|
||||
NSError* error;
|
||||
id<MTLLibrary> library = [mtlDevice newLibraryWithSource:shader
|
||||
options:nil
|
||||
error:&error];
|
||||
id<MTLLibrary> library = [mtlDevice newLibraryWithSource:shader options:nil error:&error];
|
||||
if (!library)
|
||||
{
|
||||
NSLog(@"Can not compile metal shader: %@", error);
|
||||
|
@ -74,7 +72,7 @@ ShaderModuleMTL::ShaderModuleMTL(id<MTLDevice> mtlDevice, ShaderStage stage, std
|
|||
glslopt_cleanup(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ShaderStage::VERTEX == stage)
|
||||
_mtlFunction = [library newFunctionWithName:@"xlatMtlMain1"];
|
||||
else
|
||||
|
@ -85,7 +83,7 @@ ShaderModuleMTL::ShaderModuleMTL(id<MTLDevice> mtlDevice, ShaderStage stage, std
|
|||
NSLog(@"%s", metalShader);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
glslopt_shader_delete(glslShader);
|
||||
glslopt_cleanup(ctx);
|
||||
[library release];
|
||||
|
@ -99,26 +97,27 @@ ShaderModuleMTL::~ShaderModuleMTL()
|
|||
void ShaderModuleMTL::parseAttibute(id<MTLDevice> mtlDevice, glslopt_shader* shader)
|
||||
{
|
||||
const int attributeCount = glslopt_shader_get_input_count(shader);
|
||||
for(int i = 0; i < attributeCount; i++)
|
||||
for (int i = 0; i < attributeCount; i++)
|
||||
{
|
||||
const char* parName;
|
||||
glslopt_basic_type parType;
|
||||
glslopt_precision parPrec;
|
||||
int parVecSize, parMatSize, parArrSize, location;
|
||||
glslopt_shader_get_input_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location);
|
||||
|
||||
glslopt_shader_get_input_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize,
|
||||
&location);
|
||||
|
||||
AttributeBindInfo attributeInfo;
|
||||
attributeInfo.attributeName = parName;
|
||||
attributeInfo.location = location;
|
||||
_attributeInfo[parName] = attributeInfo;
|
||||
attributeInfo.location = location;
|
||||
_attributeInfo[parName] = attributeInfo;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderModuleMTL::parseUniform(id<MTLDevice> mtlDevice, glslopt_shader* shader)
|
||||
{
|
||||
const int uniformCount = glslopt_shader_get_uniform_count(shader);
|
||||
_uniformBufferSize = glslopt_shader_get_uniform_total_size(shader);
|
||||
|
||||
_uniformBufferSize = glslopt_shader_get_uniform_total_size(shader);
|
||||
|
||||
for (int i = 0; i < uniformCount; ++i)
|
||||
{
|
||||
int nextLocation = -1;
|
||||
|
@ -126,31 +125,33 @@ void ShaderModuleMTL::parseUniform(id<MTLDevice> mtlDevice, glslopt_shader* shad
|
|||
glslopt_basic_type parType;
|
||||
glslopt_precision parPrec;
|
||||
int parVecSize, parMatSize, parArrSize, location;
|
||||
if( i+1 < uniformCount)
|
||||
if (i + 1 < uniformCount)
|
||||
{
|
||||
glslopt_shader_get_uniform_desc(shader, i+1, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location);
|
||||
glslopt_shader_get_uniform_desc(shader, i + 1, &parName, &parType, &parPrec, &parVecSize, &parMatSize,
|
||||
&parArrSize, &location);
|
||||
nextLocation = location;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLocation = static_cast<int>(_uniformBufferSize);
|
||||
}
|
||||
|
||||
glslopt_shader_get_uniform_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location);
|
||||
|
||||
|
||||
glslopt_shader_get_uniform_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize,
|
||||
&location);
|
||||
|
||||
parArrSize = (parArrSize > 0) ? parArrSize : 1;
|
||||
UniformInfo uniform;
|
||||
uniform.count = parArrSize;
|
||||
uniform.location = location;
|
||||
uniform.isArray = parArrSize;
|
||||
uniform.size = nextLocation - location;
|
||||
uniform.bufferOffset = location;
|
||||
uniform.needConvert = (parVecSize == 3) ? true : false;
|
||||
uniform.type = static_cast<unsigned int>(parType);
|
||||
uniform.isMatrix = (parMatSize > 1) ? true : false;
|
||||
_uniformInfos[parName] = uniform;
|
||||
uniform.count = parArrSize;
|
||||
uniform.location = location;
|
||||
uniform.isArray = parArrSize;
|
||||
uniform.size = nextLocation - location;
|
||||
uniform.bufferOffset = location;
|
||||
uniform.needConvert = (parVecSize == 3) ? true : false;
|
||||
uniform.type = static_cast<unsigned int>(parType);
|
||||
uniform.isMatrix = (parMatSize > 1) ? true : false;
|
||||
_uniformInfos[parName] = uniform;
|
||||
_activeUniformInfos[location] = uniform;
|
||||
_maxLocation = _maxLocation < location ? (location + 1) : _maxLocation;
|
||||
_maxLocation = _maxLocation < location ? (location + 1) : _maxLocation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,7 +163,7 @@ int ShaderModuleMTL::getUniformLocation(Uniform name) const
|
|||
int ShaderModuleMTL::getUniformLocation(std::string_view name) const
|
||||
{
|
||||
auto iter = _uniformInfos.find(name);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
return iter->second.location;
|
||||
}
|
||||
|
@ -173,44 +174,44 @@ int ShaderModuleMTL::getUniformLocation(std::string_view name) const
|
|||
void ShaderModuleMTL::setBuiltinUniformLocation()
|
||||
{
|
||||
std::fill(_uniformLocation, _uniformLocation + UNIFORM_MAX, -1);
|
||||
///u_mvpMatrix
|
||||
/// u_mvpMatrix
|
||||
auto iter = _uniformInfos.find(UNIFORM_NAME_MVP_MATRIX);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
_uniformLocation[Uniform::MVP_MATRIX] = iter->second.location;
|
||||
}
|
||||
|
||||
///u_textColor
|
||||
|
||||
/// u_textColor
|
||||
iter = _uniformInfos.find(UNIFORM_NAME_TEXT_COLOR);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
_uniformLocation[Uniform::TEXT_COLOR] = iter->second.location;
|
||||
}
|
||||
|
||||
///u_effectColor
|
||||
|
||||
/// u_effectColor
|
||||
iter = _uniformInfos.find(UNIFORM_NAME_EFFECT_COLOR);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
_uniformLocation[Uniform::EFFECT_COLOR] = iter->second.location;
|
||||
}
|
||||
|
||||
///u_effectType
|
||||
|
||||
/// u_effectType
|
||||
iter = _uniformInfos.find(UNIFORM_NAME_EFFECT_TYPE);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
_uniformLocation[Uniform::EFFECT_TYPE] = iter->second.location;
|
||||
}
|
||||
|
||||
///u_texture
|
||||
|
||||
/// u_texture
|
||||
iter = _uniformInfos.find(UNIFORM_NAME_TEXTURE);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
_uniformLocation[Uniform::TEXTURE] = iter->second.location;
|
||||
}
|
||||
|
||||
///u_texture1
|
||||
|
||||
/// u_texture1
|
||||
iter = _uniformInfos.find(UNIFORM_NAME_TEXTURE1);
|
||||
if(iter != _uniformInfos.end())
|
||||
if (iter != _uniformInfos.end())
|
||||
{
|
||||
_uniformLocation[Uniform::TEXTURE1] = iter->second.location;
|
||||
}
|
||||
|
@ -224,7 +225,7 @@ int ShaderModuleMTL::getAttributeLocation(Attribute name) const
|
|||
int ShaderModuleMTL::getAttributeLocation(std::string name)
|
||||
{
|
||||
auto iter = _attributeInfo.find(name);
|
||||
if(iter != _attributeInfo.end())
|
||||
if (iter != _attributeInfo.end())
|
||||
return _attributeInfo[name].location;
|
||||
else
|
||||
return -1;
|
||||
|
@ -233,23 +234,23 @@ int ShaderModuleMTL::getAttributeLocation(std::string name)
|
|||
void ShaderModuleMTL::setBuiltinAttributeLocation()
|
||||
{
|
||||
std::fill(_attributeLocation, _attributeLocation + ATTRIBUTE_MAX, -1);
|
||||
///a_position
|
||||
/// a_position
|
||||
auto iter = _attributeInfo.find(ATTRIBUTE_NAME_POSITION);
|
||||
if(iter != _attributeInfo.end())
|
||||
if (iter != _attributeInfo.end())
|
||||
{
|
||||
_attributeLocation[Attribute::POSITION] = iter->second.location;
|
||||
}
|
||||
|
||||
///a_color
|
||||
|
||||
/// a_color
|
||||
iter = _attributeInfo.find(ATTRIBUTE_NAME_COLOR);
|
||||
if(iter != _attributeInfo.end())
|
||||
if (iter != _attributeInfo.end())
|
||||
{
|
||||
_attributeLocation[Attribute::COLOR] = iter->second.location;
|
||||
}
|
||||
|
||||
///a_texCoord
|
||||
|
||||
/// a_texCoord
|
||||
iter = _attributeInfo.find(ATTRIBUTE_NAME_TEXCOORD);
|
||||
if(iter != _attributeInfo.end())
|
||||
if (iter != _attributeInfo.end())
|
||||
{
|
||||
_attributeLocation[Attribute::TEXCOORD] = iter->second.location;
|
||||
}
|
||||
|
@ -264,12 +265,13 @@ void ShaderModuleMTL::parseTexture(id<MTLDevice> mtlDevice, glslopt_shader* shad
|
|||
glslopt_basic_type parType;
|
||||
glslopt_precision parPrec;
|
||||
int parVecSize, parMatSize, parArrSize, location;
|
||||
glslopt_shader_get_texture_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location);
|
||||
|
||||
glslopt_shader_get_texture_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize,
|
||||
&location);
|
||||
|
||||
UniformInfo uniform;
|
||||
uniform.count = parArrSize;
|
||||
uniform.location = location;
|
||||
uniform.isArray = parArrSize > 0;
|
||||
uniform.count = parArrSize;
|
||||
uniform.location = location;
|
||||
uniform.isArray = parArrSize > 0;
|
||||
_uniformInfos[parName] = uniform;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "TextureMTL.h"
|
||||
#include "UtilsMTL.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
@ -31,78 +31,86 @@ CC_BACKEND_BEGIN
|
|||
|
||||
namespace
|
||||
{
|
||||
MTLSamplerAddressMode toMTLSamplerAddressMode(SamplerAddressMode mode)
|
||||
MTLSamplerAddressMode toMTLSamplerAddressMode(SamplerAddressMode mode)
|
||||
{
|
||||
MTLSamplerAddressMode ret = MTLSamplerAddressModeRepeat;
|
||||
switch (mode)
|
||||
{
|
||||
MTLSamplerAddressMode ret = MTLSamplerAddressModeRepeat;
|
||||
switch (mode) {
|
||||
case SamplerAddressMode::REPEAT:
|
||||
ret = MTLSamplerAddressModeRepeat;
|
||||
break;
|
||||
case SamplerAddressMode::MIRROR_REPEAT:
|
||||
ret = MTLSamplerAddressModeMirrorRepeat;
|
||||
break;
|
||||
case SamplerAddressMode::CLAMP_TO_EDGE:
|
||||
ret = MTLSamplerAddressModeClampToEdge;
|
||||
break;
|
||||
default:
|
||||
CCASSERT(false, "Not supported sampler address mode!");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
case SamplerAddressMode::REPEAT:
|
||||
ret = MTLSamplerAddressModeRepeat;
|
||||
break;
|
||||
case SamplerAddressMode::MIRROR_REPEAT:
|
||||
ret = MTLSamplerAddressModeMirrorRepeat;
|
||||
break;
|
||||
case SamplerAddressMode::CLAMP_TO_EDGE:
|
||||
ret = MTLSamplerAddressModeClampToEdge;
|
||||
break;
|
||||
default:
|
||||
CCASSERT(false, "Not supported sampler address mode!");
|
||||
break;
|
||||
}
|
||||
|
||||
MTLSamplerMinMagFilter toMTLSamplerMinMagFilter(SamplerFilter mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
MTLSamplerMinMagFilter toMTLSamplerMinMagFilter(SamplerFilter mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case SamplerFilter::NEAREST:
|
||||
case SamplerFilter::NEAREST_MIPMAP_LINEAR:
|
||||
case SamplerFilter::NEAREST_MIPMAP_NEAREST:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
case SamplerFilter::LINEAR:
|
||||
case SamplerFilter::LINEAR_MIPMAP_LINEAR:
|
||||
case SamplerFilter::LINEAR_MIPMAP_NEAREST:
|
||||
return MTLSamplerMinMagFilterLinear;
|
||||
case SamplerFilter::DONT_CARE:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
}
|
||||
case SamplerFilter::NEAREST:
|
||||
case SamplerFilter::NEAREST_MIPMAP_LINEAR:
|
||||
case SamplerFilter::NEAREST_MIPMAP_NEAREST:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
case SamplerFilter::LINEAR:
|
||||
case SamplerFilter::LINEAR_MIPMAP_LINEAR:
|
||||
case SamplerFilter::LINEAR_MIPMAP_NEAREST:
|
||||
return MTLSamplerMinMagFilterLinear;
|
||||
case SamplerFilter::DONT_CARE:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
}
|
||||
|
||||
bool isColorRenderable(PixelFormat textureFormat)
|
||||
}
|
||||
|
||||
bool isColorRenderable(PixelFormat textureFormat)
|
||||
{
|
||||
switch (textureFormat)
|
||||
{
|
||||
switch (textureFormat)
|
||||
{
|
||||
case PixelFormat::RGBA8:
|
||||
case PixelFormat::RGBA4:
|
||||
case PixelFormat::RGB565:
|
||||
case PixelFormat::RGB5A1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case PixelFormat::RGBA8:
|
||||
case PixelFormat::RGBA4:
|
||||
case PixelFormat::RGB565:
|
||||
case PixelFormat::RGB5A1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// CLASS TextureInfoMTL
|
||||
id<MTLTexture> TextureInfoMTL::ensure(int index, int target)
|
||||
{
|
||||
if(index < CC_META_TEXTURES) {
|
||||
if (index < CC_META_TEXTURES)
|
||||
{
|
||||
id<MTLTexture>& mtlTexture = _mtlTextures[index];
|
||||
if(mtlTexture) return mtlTexture;
|
||||
if (mtlTexture)
|
||||
return mtlTexture;
|
||||
mtlTexture = createTexture(_mtlDevice, _descriptor, target);
|
||||
if(_maxIdx < index) _maxIdx = index;
|
||||
if (_maxIdx < index)
|
||||
_maxIdx = index;
|
||||
return mtlTexture;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
void TextureInfoMTL::destroy() {
|
||||
if(_maxIdx == -1) return;
|
||||
void TextureInfoMTL::destroy()
|
||||
{
|
||||
if (_maxIdx == -1)
|
||||
return;
|
||||
id<MTLTexture> texture;
|
||||
int i = 0;
|
||||
while((texture = _mtlTextures[i++]))
|
||||
while ((texture = _mtlTextures[i++]))
|
||||
[texture release];
|
||||
|
||||
if(_mtlSamplerState) {
|
||||
if (_mtlSamplerState)
|
||||
{
|
||||
[_mtlSamplerState release];
|
||||
_mtlSamplerState = nil;
|
||||
}
|
||||
|
@ -112,120 +120,143 @@ void TextureInfoMTL::destroy() {
|
|||
id<MTLTexture> TextureInfoMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor, int target)
|
||||
{
|
||||
MTLPixelFormat pixelFormat = UtilsMTL::toMTLPixelFormat(descriptor.textureFormat);
|
||||
if(pixelFormat == MTLPixelFormatInvalid)
|
||||
if (pixelFormat == MTLPixelFormatInvalid)
|
||||
return nil;
|
||||
|
||||
|
||||
MTLTextureDescriptor* textureDescriptor = nil;
|
||||
switch(target) {
|
||||
switch (target)
|
||||
{
|
||||
case MTL_TEXTURE_2D:
|
||||
textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat
|
||||
width:descriptor.width
|
||||
height:descriptor.height
|
||||
mipmapped:YES];
|
||||
width:descriptor.width
|
||||
height:descriptor.height
|
||||
mipmapped:YES];
|
||||
break;
|
||||
case MTL_TEXTURE_CUBE:
|
||||
textureDescriptor = [MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:pixelFormat size:descriptor.width mipmapped:YES];
|
||||
textureDescriptor = [MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:pixelFormat
|
||||
size:descriptor.width
|
||||
mipmapped:YES];
|
||||
break;
|
||||
default: return nil;
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
if (TextureUsage::RENDER_TARGET == descriptor.textureUsage)
|
||||
{
|
||||
//DepthStencil, and Multisample textures must be allocated with the MTLResourceStorageModePrivate resource option
|
||||
if(PixelFormat::D24S8 == descriptor.textureFormat && target == MTL_TEXTURE_2D)
|
||||
// DepthStencil, and Multisample textures must be allocated with the MTLResourceStorageModePrivate resource
|
||||
// option
|
||||
if (PixelFormat::D24S8 == descriptor.textureFormat && target == MTL_TEXTURE_2D)
|
||||
textureDescriptor.resourceOptions = MTLResourceStorageModePrivate;
|
||||
textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
|
||||
}
|
||||
|
||||
|
||||
return [mtlDevice newTextureWithDescriptor:textureDescriptor];
|
||||
}
|
||||
|
||||
void TextureInfoMTL::recreateSampler(const SamplerDescriptor &descriptor)
|
||||
void TextureInfoMTL::recreateSampler(const SamplerDescriptor& descriptor)
|
||||
{
|
||||
MTLSamplerDescriptor *mtlDescriptor = [MTLSamplerDescriptor new];
|
||||
mtlDescriptor.sAddressMode = descriptor.sAddressMode == SamplerAddressMode::DONT_CARE ? _sAddressMode : toMTLSamplerAddressMode(descriptor.sAddressMode);
|
||||
mtlDescriptor.tAddressMode = descriptor.tAddressMode == SamplerAddressMode::DONT_CARE ? _tAddressMode : toMTLSamplerAddressMode(descriptor.tAddressMode);
|
||||
|
||||
mtlDescriptor.minFilter = descriptor.minFilter == SamplerFilter::DONT_CARE ? _minFilter : toMTLSamplerMinMagFilter(descriptor.minFilter);
|
||||
mtlDescriptor.magFilter = descriptor.magFilter == SamplerFilter::DONT_CARE ? _magFilter : toMTLSamplerMinMagFilter(descriptor.magFilter);
|
||||
|
||||
if(_mtlSamplerState)
|
||||
MTLSamplerDescriptor* mtlDescriptor = [MTLSamplerDescriptor new];
|
||||
mtlDescriptor.sAddressMode = descriptor.sAddressMode == SamplerAddressMode::DONT_CARE
|
||||
? _sAddressMode
|
||||
: toMTLSamplerAddressMode(descriptor.sAddressMode);
|
||||
mtlDescriptor.tAddressMode = descriptor.tAddressMode == SamplerAddressMode::DONT_CARE
|
||||
? _tAddressMode
|
||||
: toMTLSamplerAddressMode(descriptor.tAddressMode);
|
||||
|
||||
mtlDescriptor.minFilter =
|
||||
descriptor.minFilter == SamplerFilter::DONT_CARE ? _minFilter : toMTLSamplerMinMagFilter(descriptor.minFilter);
|
||||
mtlDescriptor.magFilter =
|
||||
descriptor.magFilter == SamplerFilter::DONT_CARE ? _magFilter : toMTLSamplerMinMagFilter(descriptor.magFilter);
|
||||
|
||||
if (_mtlSamplerState)
|
||||
{
|
||||
[_mtlSamplerState release];
|
||||
_mtlSamplerState = nil;
|
||||
}
|
||||
|
||||
|
||||
_sAddressMode = mtlDescriptor.sAddressMode;
|
||||
_tAddressMode = mtlDescriptor.tAddressMode;
|
||||
_minFilter = mtlDescriptor.minFilter;
|
||||
_magFilter = mtlDescriptor.magFilter;
|
||||
_mipFilter = mtlDescriptor.mipFilter;
|
||||
|
||||
_minFilter = mtlDescriptor.minFilter;
|
||||
_magFilter = mtlDescriptor.magFilter;
|
||||
_mipFilter = mtlDescriptor.mipFilter;
|
||||
|
||||
_mtlSamplerState = [_mtlDevice newSamplerStateWithDescriptor:mtlDescriptor];
|
||||
|
||||
|
||||
[mtlDescriptor release];
|
||||
}
|
||||
|
||||
/// CLASS TextureMTL
|
||||
TextureMTL::TextureMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor)
|
||||
: _textureInfo(mtlDevice)
|
||||
TextureMTL::TextureMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor) : _textureInfo(mtlDevice)
|
||||
{
|
||||
updateTextureDescriptor(descriptor);
|
||||
}
|
||||
|
||||
TextureMTL::~TextureMTL()
|
||||
{
|
||||
}
|
||||
TextureMTL::~TextureMTL() {}
|
||||
|
||||
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
|
||||
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor& sampler)
|
||||
{
|
||||
_textureInfo.recreateSampler(sampler);
|
||||
}
|
||||
|
||||
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
|
||||
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor& descriptor, int index)
|
||||
{
|
||||
TextureBackend::updateTextureDescriptor(descriptor, index);
|
||||
|
||||
_textureInfo._descriptor = descriptor;
|
||||
_textureInfo.ensure(index, MTL_TEXTURE_2D);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||
|
||||
|
||||
_textureInfo._bytesPerRow = PixelFormatUtils::computeRowPitch(descriptor.textureFormat, descriptor.width);
|
||||
}
|
||||
|
||||
void TextureMTL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index)
|
||||
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, 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, int 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,
|
||||
int index)
|
||||
{
|
||||
auto mtlTexture = _textureInfo.ensure(index, MTL_TEXTURE_2D);
|
||||
if(!mtlTexture) return;
|
||||
|
||||
MTLRegion region =
|
||||
{
|
||||
if (!mtlTexture)
|
||||
return;
|
||||
|
||||
MTLRegion region = {
|
||||
{xoffset, yoffset, 0}, // MTLOrigin
|
||||
{width, height, 1} // MTLSize
|
||||
};
|
||||
|
||||
|
||||
auto bytesPerRow = PixelFormatUtils::computeRowPitch(_textureFormat, width);
|
||||
|
||||
[mtlTexture replaceRegion:region
|
||||
mipmapLevel:level
|
||||
withBytes:data
|
||||
bytesPerRow:bytesPerRow];
|
||||
|
||||
if(!_hasMipmaps && level > 0)
|
||||
|
||||
[mtlTexture replaceRegion:region mipmapLevel:level withBytes:data bytesPerRow:bytesPerRow];
|
||||
|
||||
if (!_hasMipmaps && level > 0)
|
||||
_hasMipmaps = true;
|
||||
}
|
||||
|
||||
void TextureMTL::updateCompressedData(uint8_t *data, std::size_t width, std::size_t height, std::size_t dataLen, std::size_t level, int index)
|
||||
void TextureMTL::updateCompressedData(uint8_t* data,
|
||||
std::size_t width,
|
||||
std::size_t height,
|
||||
std::size_t dataLen,
|
||||
std::size_t level,
|
||||
int index)
|
||||
{
|
||||
updateCompressedSubData(0, 0, width, height, dataLen, level, data, index);
|
||||
}
|
||||
|
||||
void TextureMTL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t dataLen, std::size_t level, uint8_t *data, int index)
|
||||
void TextureMTL::updateCompressedSubData(std::size_t xoffset,
|
||||
std::size_t yoffset,
|
||||
std::size_t width,
|
||||
std::size_t height,
|
||||
std::size_t dataLen,
|
||||
std::size_t level,
|
||||
uint8_t* data,
|
||||
int index)
|
||||
{
|
||||
updateSubData(xoffset, yoffset, width, height, level, data, index);
|
||||
}
|
||||
|
@ -234,8 +265,8 @@ void TextureMTL::generateMipmaps()
|
|||
{
|
||||
if (TextureUsage::RENDER_TARGET == _textureUsage || isColorRenderable(_textureFormat) == false)
|
||||
return;
|
||||
|
||||
if(!_hasMipmaps)
|
||||
|
||||
if (!_hasMipmaps)
|
||||
{
|
||||
_hasMipmaps = true;
|
||||
UtilsMTL::generateMipmaps(reinterpret_cast<id<MTLTexture>>(this->getHandler()));
|
||||
|
@ -243,54 +274,52 @@ void TextureMTL::generateMipmaps()
|
|||
}
|
||||
|
||||
/// CLASS TextureCubeMTL
|
||||
TextureCubeMTL::TextureCubeMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor)
|
||||
: _textureInfo(mtlDevice)
|
||||
TextureCubeMTL::TextureCubeMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor) : _textureInfo(mtlDevice)
|
||||
{
|
||||
updateTextureDescriptor(descriptor);
|
||||
}
|
||||
|
||||
TextureCubeMTL::~TextureCubeMTL()
|
||||
{
|
||||
}
|
||||
TextureCubeMTL::~TextureCubeMTL() {}
|
||||
|
||||
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
|
||||
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor& descriptor, int index)
|
||||
{
|
||||
TextureBackend::updateTextureDescriptor(descriptor, index);
|
||||
|
||||
_textureInfo._descriptor = descriptor;
|
||||
_textureInfo.ensure(index, MTL_TEXTURE_CUBE);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||
|
||||
|
||||
_textureInfo._bytesPerRow = PixelFormatUtils::computeRowPitch(descriptor.textureFormat, descriptor.width);
|
||||
_bytesPerImage = _textureInfo._bytesPerRow * descriptor.width;
|
||||
_region = MTLRegionMake2D(0, 0, descriptor.width, descriptor.height);
|
||||
_bytesPerImage = _textureInfo._bytesPerRow * descriptor.width;
|
||||
_region = MTLRegionMake2D(0, 0, descriptor.width, descriptor.height);
|
||||
}
|
||||
|
||||
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
|
||||
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor& sampler)
|
||||
{
|
||||
_textureInfo.recreateSampler(sampler);
|
||||
}
|
||||
|
||||
void TextureCubeMTL::updateFaceData(TextureCubeFace side, void *data, int index)
|
||||
void TextureCubeMTL::updateFaceData(TextureCubeFace side, void* data, int index)
|
||||
{
|
||||
NSUInteger slice = static_cast<int>(side);
|
||||
auto mtlTexture = _textureInfo.ensure(index, MTL_TEXTURE_CUBE);
|
||||
if(!mtlTexture) return;
|
||||
auto mtlTexture = _textureInfo.ensure(index, MTL_TEXTURE_CUBE);
|
||||
if (!mtlTexture)
|
||||
return;
|
||||
|
||||
[mtlTexture replaceRegion:_region
|
||||
mipmapLevel:0
|
||||
slice:slice
|
||||
withBytes:data
|
||||
bytesPerRow:_textureInfo._bytesPerRow
|
||||
bytesPerImage:_bytesPerImage];
|
||||
mipmapLevel:0
|
||||
slice:slice
|
||||
withBytes:data
|
||||
bytesPerRow:_textureInfo._bytesPerRow
|
||||
bytesPerImage:_bytesPerImage];
|
||||
}
|
||||
|
||||
void TextureCubeMTL::generateMipmaps()
|
||||
{
|
||||
if (TextureUsage::RENDER_TARGET == _textureUsage || isColorRenderable(_textureFormat) == false)
|
||||
return;
|
||||
|
||||
if(!_hasMipmaps)
|
||||
|
||||
if (!_hasMipmaps)
|
||||
{
|
||||
_hasMipmaps = true;
|
||||
UtilsMTL::generateMipmaps(reinterpret_cast<id<MTLTexture>>(this->getHandler()));
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "UtilsMTL.h"
|
||||
#include "DeviceMTL.h"
|
||||
#include "DeviceInfoMTL.h"
|
||||
|
@ -32,20 +32,21 @@
|
|||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
id<MTLTexture> UtilsMTL::_defaultColorAttachmentTexture = nil;
|
||||
id<MTLTexture> UtilsMTL::_defaultColorAttachmentTexture = nil;
|
||||
id<MTLTexture> UtilsMTL::_defaultDepthStencilAttachmentTexture = nil;
|
||||
|
||||
namespace {
|
||||
MTLPixelFormat getSupportedDepthStencilFormat()
|
||||
{
|
||||
MTLPixelFormat pixelFormat = MTLPixelFormatDepth32Float_Stencil8;
|
||||
namespace
|
||||
{
|
||||
MTLPixelFormat getSupportedDepthStencilFormat()
|
||||
{
|
||||
MTLPixelFormat pixelFormat = MTLPixelFormatDepth32Float_Stencil8;
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
bool isDepth24Stencil8PixelFormatSupported = DeviceInfoMTL::supportD24S8();
|
||||
if(isDepth24Stencil8PixelFormatSupported)
|
||||
pixelFormat = MTLPixelFormatDepth24Unorm_Stencil8;
|
||||
bool isDepth24Stencil8PixelFormatSupported = DeviceInfoMTL::supportD24S8();
|
||||
if (isDepth24Stencil8PixelFormatSupported)
|
||||
pixelFormat = MTLPixelFormatDepth24Unorm_Stencil8;
|
||||
#endif
|
||||
return pixelFormat;
|
||||
}
|
||||
return pixelFormat;
|
||||
}
|
||||
}
|
||||
|
||||
struct GPUTextureFormatInfo
|
||||
|
@ -54,76 +55,77 @@ struct GPUTextureFormatInfo
|
|||
MTLPixelFormat fmtSrgb;
|
||||
};
|
||||
|
||||
static GPUTextureFormatInfo s_textureFormats[] =
|
||||
{
|
||||
static GPUTextureFormatInfo s_textureFormats[] = {
|
||||
/* pvrtc v1 */
|
||||
{ MTLPixelFormat(162/*PVRTC_RGB_4BPP*/), MTLPixelFormat(163/*PVRTC_RGB_4BPP_sRGB*/) }, // PTC14
|
||||
{ MTLPixelFormat(166/*PVRTC_RGBA_4BPP*/), MTLPixelFormat(167/*PVRTC_RGBA_4BPP_sRGB*/) }, // PTC14A
|
||||
{ MTLPixelFormat(160/*PVRTC_RGB_2BPP*/), MTLPixelFormat(161/*PVRTC_RGB_2BPP_sRGB*/) }, // PTC12
|
||||
{ MTLPixelFormat(164/*PVRTC_RGBA_2BPP*/), MTLPixelFormat(165/*PVRTC_RGBA_2BPP_sRGB*/) }, // PTC12A
|
||||
|
||||
{MTLPixelFormat(162 /*PVRTC_RGB_4BPP*/), MTLPixelFormat(163 /*PVRTC_RGB_4BPP_sRGB*/)}, // PTC14
|
||||
{MTLPixelFormat(166 /*PVRTC_RGBA_4BPP*/), MTLPixelFormat(167 /*PVRTC_RGBA_4BPP_sRGB*/)}, // PTC14A
|
||||
{MTLPixelFormat(160 /*PVRTC_RGB_2BPP*/), MTLPixelFormat(161 /*PVRTC_RGB_2BPP_sRGB*/)}, // PTC12
|
||||
{MTLPixelFormat(164 /*PVRTC_RGBA_2BPP*/), MTLPixelFormat(165 /*PVRTC_RGBA_2BPP_sRGB*/)}, // PTC12A
|
||||
|
||||
/* etc */
|
||||
{ MTLPixelFormat(180/*ETC2_RGB8*/), MTLPixelFormat(181/*ETC2_RGB8_sRGB*/) }, // ETC1
|
||||
{ MTLPixelFormat(180/*ETC2_RGB8*/), MTLPixelFormat(181/*ETC2_RGB8_sRGB*/) }, // ETC2
|
||||
{ MTLPixelFormat(178/*EAC_RGBA8*/), MTLPixelFormat(179/*EAC_RGBA8_sRGB*/) }, // ETC2A
|
||||
|
||||
{MTLPixelFormat(180 /*ETC2_RGB8*/), MTLPixelFormat(181 /*ETC2_RGB8_sRGB*/)}, // ETC1
|
||||
{MTLPixelFormat(180 /*ETC2_RGB8*/), MTLPixelFormat(181 /*ETC2_RGB8_sRGB*/)}, // ETC2
|
||||
{MTLPixelFormat(178 /*EAC_RGBA8*/), MTLPixelFormat(179 /*EAC_RGBA8_sRGB*/)}, // ETC2A
|
||||
|
||||
/* s3tc */
|
||||
{ MTLPixelFormat(130/*BC1_RGBA*/), MTLPixelFormat(131/*BC1_RGBA_sRGB*/) }, // S3TC_DXT1/BC1
|
||||
{ MTLPixelFormat(132/*BC2_RGBA*/), MTLPixelFormat(133/*BC2_RGBA_sRGB*/) }, // S3TC_DXT3/BC2
|
||||
{ MTLPixelFormat(134/*BC3_RGBA*/), MTLPixelFormat(135/*BC3_RGBA_sRGB*/) }, // S3TC_DXT5/BC3
|
||||
|
||||
{MTLPixelFormat(130 /*BC1_RGBA*/), MTLPixelFormat(131 /*BC1_RGBA_sRGB*/)}, // S3TC_DXT1/BC1
|
||||
{MTLPixelFormat(132 /*BC2_RGBA*/), MTLPixelFormat(133 /*BC2_RGBA_sRGB*/)}, // S3TC_DXT3/BC2
|
||||
{MTLPixelFormat(134 /*BC3_RGBA*/), MTLPixelFormat(135 /*BC3_RGBA_sRGB*/)}, // S3TC_DXT5/BC3
|
||||
|
||||
/* atc */
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ATC_RGB
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ATC_EXPLICIT_ALPHA
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ATC_INTERPOLATED_ALPHA
|
||||
|
||||
/* astc */
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ATC_RGB
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ATC_EXPLICIT_ALPHA
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ATC_INTERPOLATED_ALPHA
|
||||
|
||||
/* astc */
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
{ MTLPixelFormatASTC_4x4_LDR, MTLPixelFormatASTC_4x4_sRGB }, // ASTC4x4
|
||||
{ MTLPixelFormatASTC_5x5_LDR, MTLPixelFormatASTC_5x5_sRGB }, // ASTC5x5
|
||||
{ MTLPixelFormatASTC_6x6_LDR, MTLPixelFormatASTC_6x6_sRGB }, // ASTC6x6
|
||||
{ MTLPixelFormatASTC_8x5_LDR, MTLPixelFormatASTC_8x5_sRGB }, // ASTC8x5
|
||||
{ MTLPixelFormatASTC_8x6_LDR, MTLPixelFormatASTC_8x6_sRGB }, // ASTC8x6
|
||||
{ MTLPixelFormatASTC_8x8_LDR, MTLPixelFormatASTC_8x8_sRGB }, // ASTC8x8
|
||||
{ MTLPixelFormatASTC_10x5_LDR, MTLPixelFormatASTC_10x5_sRGB }, // ASTC10x5
|
||||
{MTLPixelFormatASTC_4x4_LDR, MTLPixelFormatASTC_4x4_sRGB}, // ASTC4x4
|
||||
{MTLPixelFormatASTC_5x5_LDR, MTLPixelFormatASTC_5x5_sRGB}, // ASTC5x5
|
||||
{MTLPixelFormatASTC_6x6_LDR, MTLPixelFormatASTC_6x6_sRGB}, // ASTC6x6
|
||||
{MTLPixelFormatASTC_8x5_LDR, MTLPixelFormatASTC_8x5_sRGB}, // ASTC8x5
|
||||
{MTLPixelFormatASTC_8x6_LDR, MTLPixelFormatASTC_8x6_sRGB}, // ASTC8x6
|
||||
{MTLPixelFormatASTC_8x8_LDR, MTLPixelFormatASTC_8x8_sRGB}, // ASTC8x8
|
||||
{MTLPixelFormatASTC_10x5_LDR, MTLPixelFormatASTC_10x5_sRGB}, // ASTC10x5
|
||||
#else
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC4x4
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC5x5
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC6x6
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC8x5
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC8x6
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC8x8
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // ASTC10x5
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC4x4
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC5x5
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC6x6
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC8x5
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC8x6
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC8x8
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // ASTC10x5
|
||||
#endif
|
||||
|
||||
|
||||
/* normal */
|
||||
{ MTLPixelFormatRGBA8Unorm, MTLPixelFormatRGBA8Unorm_sRGB }, // RGBA8
|
||||
{ MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB }, // BGRA8
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // RGB8
|
||||
{ MTLPixelFormat(40/*B5G6R5Unorm*/), MTLPixelFormatInvalid }, // R5G6B5
|
||||
{ MTLPixelFormat(42/*ABGR4Unorm*/), MTLPixelFormatInvalid }, // RGBA4
|
||||
{ MTLPixelFormat(41/*A1BGR5Unorm*/), MTLPixelFormatInvalid }, // RGB5A1
|
||||
{ MTLPixelFormatA8Unorm, MTLPixelFormatInvalid }, // A8
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // L8
|
||||
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid }, // LA8
|
||||
|
||||
{MTLPixelFormatRGBA8Unorm, MTLPixelFormatRGBA8Unorm_sRGB}, // RGBA8
|
||||
{MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB}, // BGRA8
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // RGB8
|
||||
{MTLPixelFormat(40 /*B5G6R5Unorm*/), MTLPixelFormatInvalid}, // R5G6B5
|
||||
{MTLPixelFormat(42 /*ABGR4Unorm*/), MTLPixelFormatInvalid}, // RGBA4
|
||||
{MTLPixelFormat(41 /*A1BGR5Unorm*/), MTLPixelFormatInvalid}, // RGB5A1
|
||||
{MTLPixelFormatA8Unorm, MTLPixelFormatInvalid}, // A8
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // L8
|
||||
{MTLPixelFormatInvalid, MTLPixelFormatInvalid}, // LA8
|
||||
|
||||
/* depth stencil */
|
||||
{ MTLPixelFormat(255/*Depth24Unorm_Stencil8*/), MTLPixelFormatInvalid }, // D24S8
|
||||
{MTLPixelFormat(255 /*Depth24Unorm_Stencil8*/), MTLPixelFormatInvalid}, // D24S8
|
||||
};
|
||||
static_assert(CC_ARRAYSIZE(s_textureFormats) == (int)PixelFormat::COUNT, "The OpenGL GPU texture format info table incomplete!");
|
||||
static_assert(CC_ARRAYSIZE(s_textureFormats) == (int)PixelFormat::COUNT,
|
||||
"The OpenGL GPU texture format info table incomplete!");
|
||||
|
||||
void UtilsMTL::initGPUTextureFormats()
|
||||
{
|
||||
//on mac, D24S8 means MTLPixelFormatDepth24Unorm_Stencil8, while on ios it means MTLPixelFormatDepth32Float_Stencil8
|
||||
// on mac, D24S8 means MTLPixelFormatDepth24Unorm_Stencil8, while on ios it means
|
||||
// MTLPixelFormatDepth32Float_Stencil8
|
||||
auto& info = s_textureFormats[(int)PixelFormat::D24S8];
|
||||
info.fmt = getSupportedDepthStencilFormat();
|
||||
info.fmt = getSupportedDepthStencilFormat();
|
||||
}
|
||||
|
||||
id<MTLTexture> UtilsMTL::getDefaultDepthStencilTexture()
|
||||
{
|
||||
if (! _defaultDepthStencilAttachmentTexture)
|
||||
if (!_defaultDepthStencilAttachmentTexture)
|
||||
_defaultDepthStencilAttachmentTexture = UtilsMTL::createDepthStencilAttachmentTexture();
|
||||
|
||||
|
||||
return _defaultDepthStencilAttachmentTexture;
|
||||
}
|
||||
|
||||
|
@ -134,7 +136,8 @@ void UtilsMTL::updateDefaultColorAttachmentTexture(id<MTLTexture> texture)
|
|||
|
||||
MTLPixelFormat UtilsMTL::toMTLPixelFormat(PixelFormat textureFormat)
|
||||
{
|
||||
if (UTILS_LIKELY(textureFormat < PixelFormat::COUNT)) {
|
||||
if (UTILS_LIKELY(textureFormat < PixelFormat::COUNT))
|
||||
{
|
||||
return s_textureFormats[(int)textureFormat].fmt;
|
||||
}
|
||||
return MTLPixelFormatInvalid;
|
||||
|
@ -149,48 +152,49 @@ void UtilsMTL::resizeDefaultAttachmentTexture(std::size_t width, std::size_t hei
|
|||
|
||||
id<MTLTexture> UtilsMTL::createDepthStencilAttachmentTexture()
|
||||
{
|
||||
auto CAMetalLayer = DeviceMTL::getCAMetalLayer();
|
||||
auto CAMetalLayer = DeviceMTL::getCAMetalLayer();
|
||||
MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
|
||||
textureDescriptor.width = CAMetalLayer.drawableSize.width;
|
||||
textureDescriptor.height = CAMetalLayer.drawableSize.height;
|
||||
textureDescriptor.pixelFormat = s_textureFormats[(int)PixelFormat::D24S8].fmt;
|
||||
textureDescriptor.resourceOptions = MTLResourceStorageModePrivate;
|
||||
textureDescriptor.usage = MTLTextureUsageRenderTarget;
|
||||
auto ret = [CAMetalLayer.device newTextureWithDescriptor:textureDescriptor];
|
||||
textureDescriptor.width = CAMetalLayer.drawableSize.width;
|
||||
textureDescriptor.height = CAMetalLayer.drawableSize.height;
|
||||
textureDescriptor.pixelFormat = s_textureFormats[(int)PixelFormat::D24S8].fmt;
|
||||
textureDescriptor.resourceOptions = MTLResourceStorageModePrivate;
|
||||
textureDescriptor.usage = MTLTextureUsageRenderTarget;
|
||||
auto ret = [CAMetalLayer.device newTextureWithDescriptor:textureDescriptor];
|
||||
[textureDescriptor release];
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UtilsMTL::generateMipmaps(id<MTLTexture> texture)
|
||||
{
|
||||
auto commandQueue = static_cast<DeviceMTL*>(DeviceMTL::getInstance())->getMTLCommandQueue();
|
||||
auto commandBuffer = [commandQueue commandBuffer];
|
||||
auto commandQueue = static_cast<DeviceMTL*>(DeviceMTL::getInstance())->getMTLCommandQueue();
|
||||
auto commandBuffer = [commandQueue commandBuffer];
|
||||
id<MTLBlitCommandEncoder> commandEncoder = [commandBuffer blitCommandEncoder];
|
||||
[commandEncoder generateMipmapsForTexture:texture];
|
||||
[commandEncoder endEncoding];
|
||||
[commandBuffer commit];
|
||||
}
|
||||
|
||||
void UtilsMTL::swizzleImage(unsigned char *image, std::size_t width, std::size_t height, MTLPixelFormat format)
|
||||
void UtilsMTL::swizzleImage(unsigned char* image, std::size_t width, std::size_t height, MTLPixelFormat format)
|
||||
{
|
||||
if(!image)
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
|
||||
auto len = width * height;
|
||||
switch (format) {
|
||||
//convert to RGBA
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
unsigned char temp = image[i*4];
|
||||
image[i*4] = image[i*4+2];
|
||||
image[i*4+2] = temp;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
switch (format)
|
||||
{
|
||||
// convert to RGBA
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
unsigned char temp = image[i * 4];
|
||||
image[i * 4] = image[i * 4 + 2];
|
||||
image[i * 4 + 2] = temp;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -149,8 +149,7 @@ public:
|
|||
* Get all uniformInfos.
|
||||
* @return The uniformInfos.
|
||||
*/
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(
|
||||
ShaderStage stage) const override;
|
||||
virtual const hlookup::string_map<UniformInfo>& getAllActiveUniformInfo(ShaderStage stage) const override;
|
||||
|
||||
private:
|
||||
void compileProgram();
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
static Button* create(std::string_view normalImage,
|
||||
std::string_view selectedImage = "",
|
||||
std::string_view disableImage = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
* Load textures for button.
|
||||
|
@ -96,7 +96,7 @@ public:
|
|||
void loadTextures(std::string_view normal,
|
||||
std::string_view selected,
|
||||
std::string_view disabled = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
* Load normal state texture for button.
|
||||
|
@ -317,7 +317,7 @@ public:
|
|||
virtual bool init(std::string_view normalImage,
|
||||
std::string_view selectedImage = "",
|
||||
std::string_view disableImage = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
virtual Vec2 getNormalTextureSize() const;
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 zilongshanren
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -30,92 +30,94 @@
|
|||
#include "ui/UIEditBox/Mac/CCUIPasswordTextField.h"
|
||||
#include "ui/UIEditBox/Mac/CCUIMultilineTextField.h"
|
||||
|
||||
#define getEditBoxImplMac() ((cocos2d::ui::EditBoxImplMac *)_editBox)
|
||||
|
||||
#define getEditBoxImplMac() ((cocos2d::ui::EditBoxImplMac*)_editBox)
|
||||
|
||||
@implementation UIEditBoxImplMac
|
||||
|
||||
- (instancetype)initWithFrame:(NSRect)frameRect editBox:(void *)editBox
|
||||
- (instancetype)initWithFrame:(NSRect)frameRect editBox:(void*)editBox
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
|
||||
_editState = NO;
|
||||
|
||||
if (self)
|
||||
{
|
||||
|
||||
_editState = NO;
|
||||
self.frameRect = frameRect;
|
||||
|
||||
self.editBox = editBox;
|
||||
self.dataInputMode = cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS;
|
||||
|
||||
self.editBox = editBox;
|
||||
self.dataInputMode = cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS;
|
||||
self.keyboardReturnType = cocos2d::ui::EditBox::KeyboardReturnType::DEFAULT;
|
||||
|
||||
|
||||
[self createMultiLineTextField];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createSingleLineTextField
|
||||
{
|
||||
CCUISingleLineTextField *textField = [[[CCUISingleLineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
|
||||
CCUISingleLineTextField* textField = [[[CCUISingleLineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
|
||||
self.textInput = textField;
|
||||
}
|
||||
|
||||
- (void)createMultiLineTextField
|
||||
{
|
||||
CCUIMultilineTextField *textView = [[[CCUIMultilineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
CCUIMultilineTextField* textView = [[[CCUIMultilineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
[textView setVerticallyResizable:NO];
|
||||
self.textInput = textView;
|
||||
}
|
||||
|
||||
- (void)createPasswordTextField
|
||||
{
|
||||
CCUIPasswordTextField *textField = [[[CCUIPasswordTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
|
||||
CCUIPasswordTextField* textField = [[[CCUIPasswordTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
|
||||
self.textInput = textField;
|
||||
}
|
||||
|
||||
- (void)setTextInput:(NSView<CCUITextInput> *)textInput
|
||||
- (void)setTextInput:(NSView<CCUITextInput>*)textInput
|
||||
{
|
||||
if (_textInput == textInput) {
|
||||
if (_textInput == textInput)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Migrate properties
|
||||
textInput.ccui_textColor = _textInput.ccui_textColor ?: [NSColor whiteColor];
|
||||
textInput.ccui_text = _textInput.ccui_text ?: @"";
|
||||
textInput.ccui_textColor = _textInput.ccui_textColor ?: [NSColor whiteColor];
|
||||
textInput.ccui_text = _textInput.ccui_text ?: @"";
|
||||
textInput.ccui_placeholder = _textInput.ccui_placeholder ?: @"";
|
||||
textInput.ccui_font = _textInput.ccui_font ?: [NSFont systemFontOfSize:self.frameRect.size.height*3/2];
|
||||
textInput.ccui_maxLength = getEditBoxImplMac()->getMaxLength();
|
||||
textInput.ccui_alignment = _textInput.ccui_alignment;
|
||||
|
||||
textInput.ccui_font = _textInput.ccui_font ?: [NSFont systemFontOfSize:self.frameRect.size.height * 3 / 2];
|
||||
textInput.ccui_maxLength = getEditBoxImplMac()->getMaxLength();
|
||||
textInput.ccui_alignment = _textInput.ccui_alignment;
|
||||
|
||||
[_textInput removeFromSuperview];
|
||||
[_textInput release];
|
||||
|
||||
|
||||
_textInput = [textInput retain];
|
||||
|
||||
|
||||
[_textInput performSelector:@selector(setTextColor:) withObject:_textInput.ccui_textColor];
|
||||
[_textInput performSelector:@selector(setBackgroundColor:) withObject:[NSColor clearColor]];
|
||||
|
||||
if (![_textInput isKindOfClass:[NSTextView class]]) {
|
||||
|
||||
if (![_textInput isKindOfClass:[NSTextView class]])
|
||||
{
|
||||
[_textInput performSelector:@selector(setBordered:) withObject:nil];
|
||||
}
|
||||
_textInput.hidden = NO;
|
||||
_textInput.hidden = NO;
|
||||
_textInput.wantsLayer = YES;
|
||||
|
||||
|
||||
[_textInput ccui_setDelegate:self];
|
||||
|
||||
|
||||
[self setInputFlag:self.dataInputMode];
|
||||
[self setReturnType:self.keyboardReturnType];
|
||||
}
|
||||
|
||||
- (void)updateFrame:(CGRect)rect
|
||||
{
|
||||
NSRect frame = self.textInput.frame;
|
||||
frame.origin.x = rect.origin.x;
|
||||
frame.origin.y = rect.origin.y;
|
||||
NSRect frame = self.textInput.frame;
|
||||
frame.origin.x = rect.origin.x;
|
||||
frame.origin.y = rect.origin.y;
|
||||
frame.size.height = rect.size.height;
|
||||
frame.size.width = rect.size.width;
|
||||
frame.size.width = rect.size.width;
|
||||
|
||||
self.textInput.frame = frame;
|
||||
}
|
||||
|
@ -123,11 +125,11 @@
|
|||
- (void)dealloc
|
||||
{
|
||||
self.textInput = nil;
|
||||
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSWindow *)window
|
||||
- (NSWindow*)window
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
return glview->getCocoaWindow();
|
||||
|
@ -137,41 +139,44 @@
|
|||
{
|
||||
[self.window.contentView addSubview:self.textInput];
|
||||
|
||||
if (![self.textInput isKindOfClass:[NSTextView class]]) {
|
||||
if (![self.textInput isKindOfClass:[NSTextView class]])
|
||||
{
|
||||
[self.textInput becomeFirstResponder];
|
||||
}else {
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.window makeFirstResponder:self.textInput];
|
||||
}
|
||||
|
||||
|
||||
auto editbox = getEditBoxImplMac()->getEditBox();
|
||||
auto oldPos = editbox->getPosition();
|
||||
editbox->setPosition(oldPos + cocos2d::Vec2(10,20));
|
||||
auto oldPos = editbox->getPosition();
|
||||
editbox->setPosition(oldPos + cocos2d::Vec2(10, 20));
|
||||
editbox->setPosition(oldPos);
|
||||
}
|
||||
|
||||
- (void)closeKeyboard
|
||||
{
|
||||
if (![self.textInput isKindOfClass:[NSTextView class]]) {
|
||||
if (![self.textInput isKindOfClass:[NSTextView class]])
|
||||
{
|
||||
[self.textInput resignFirstResponder];
|
||||
}
|
||||
|
||||
[self.textInput removeFromSuperview];
|
||||
}
|
||||
|
||||
|
||||
- (const char*) getText
|
||||
- (const char*)getText
|
||||
{
|
||||
return [self.textInput.ccui_text UTF8String];
|
||||
}
|
||||
|
||||
- (void)controlTextDidBeginEditing:(NSNotification *)notification
|
||||
- (void)controlTextDidBeginEditing:(NSNotification*)notification
|
||||
{
|
||||
_editState = YES;
|
||||
|
||||
|
||||
getEditBoxImplMac()->editBoxEditingDidBegin();
|
||||
}
|
||||
|
||||
- (void)controlTextDidEndEditing:(NSNotification *)notification
|
||||
- (void)controlTextDidEndEditing:(NSNotification*)notification
|
||||
{
|
||||
_editState = NO;
|
||||
|
||||
|
@ -186,27 +191,32 @@
|
|||
/**
|
||||
* Called each time when the text field's text has changed.
|
||||
*/
|
||||
- (void)controlTextDidChange:(NSNotification *)notification
|
||||
- (void)controlTextDidChange:(NSNotification*)notification
|
||||
{
|
||||
getEditBoxImplMac()->editBoxEditingChanged([self getText]);
|
||||
}
|
||||
|
||||
- (NSString *)getDefaultFontName
|
||||
- (NSString*)getDefaultFontName
|
||||
{
|
||||
return self.textInput.ccui_font.fontName ?: @"";
|
||||
}
|
||||
|
||||
- (void)setInputMode:(cocos2d::ui::EditBox::InputMode)inputMode
|
||||
{
|
||||
//multiline input
|
||||
if (inputMode == cocos2d::ui::EditBox::InputMode::ANY) {
|
||||
if (![self.textInput isKindOfClass:[NSTextView class]]) {
|
||||
// multiline input
|
||||
if (inputMode == cocos2d::ui::EditBox::InputMode::ANY)
|
||||
{
|
||||
if (![self.textInput isKindOfClass:[NSTextView class]])
|
||||
{
|
||||
[self createMultiLineTextField];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (self.dataInputMode != cocos2d::ui::EditBox::InputFlag::PASSWORD) {
|
||||
if (![self.textInput isKindOfClass:[NSTextField class]]) {
|
||||
else
|
||||
{
|
||||
if (self.dataInputMode != cocos2d::ui::EditBox::InputFlag::PASSWORD)
|
||||
{
|
||||
if (![self.textInput isKindOfClass:[NSTextField class]])
|
||||
{
|
||||
[self createSingleLineTextField];
|
||||
}
|
||||
}
|
||||
|
@ -215,42 +225,45 @@
|
|||
|
||||
- (void)setInputFlag:(cocos2d::ui::EditBox::InputFlag)inputFlag
|
||||
{
|
||||
if (self.dataInputMode == inputFlag) {
|
||||
if (self.dataInputMode == inputFlag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.dataInputMode == cocos2d::ui::EditBox::InputFlag::PASSWORD
|
||||
&& inputFlag != cocos2d::ui::EditBox::InputFlag::PASSWORD) {
|
||||
|
||||
if (self.dataInputMode == cocos2d::ui::EditBox::InputFlag::PASSWORD &&
|
||||
inputFlag != cocos2d::ui::EditBox::InputFlag::PASSWORD)
|
||||
{
|
||||
[self createSingleLineTextField];
|
||||
}
|
||||
|
||||
if (self.dataInputMode != cocos2d::ui::EditBox::InputFlag::PASSWORD
|
||||
&& inputFlag == cocos2d::ui::EditBox::InputFlag::PASSWORD) {
|
||||
|
||||
if (self.dataInputMode != cocos2d::ui::EditBox::InputFlag::PASSWORD &&
|
||||
inputFlag == cocos2d::ui::EditBox::InputFlag::PASSWORD)
|
||||
{
|
||||
[self createPasswordTextField];
|
||||
}
|
||||
|
||||
switch (inputFlag)
|
||||
{
|
||||
case cocos2d::ui::EditBox::InputFlag::PASSWORD:
|
||||
self.dataInputMode = inputFlag;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_WORD:
|
||||
CCLOG("INITIAL_CAPS_WORD not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_SENTENCE:
|
||||
CCLOG("INITIAL_CAPS_SENTENCE not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_ALL_CHARACTERS:
|
||||
CCLOG("INITIAL_CAPS_ALL_CHARACTERS not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::SENSITIVE:
|
||||
CCLOG("SENSITIVE not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS:
|
||||
CCLOG("LOWERCASE_ALL_CHARACTERS not implemented");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::PASSWORD:
|
||||
self.dataInputMode = inputFlag;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_WORD:
|
||||
CCLOG("INITIAL_CAPS_WORD not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_SENTENCE:
|
||||
CCLOG("INITIAL_CAPS_SENTENCE not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_ALL_CHARACTERS:
|
||||
CCLOG("INITIAL_CAPS_ALL_CHARACTERS not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::SENSITIVE:
|
||||
CCLOG("SENSITIVE not implemented");
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS:
|
||||
CCLOG("LOWERCASE_ALL_CHARACTERS not implemented");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,12 +275,14 @@
|
|||
- (void)setTextHorizontalAlignment:(cocos2d::TextHAlignment)alignment
|
||||
{
|
||||
// swizzle center & right, for some reason they're backwards on !TARGET_OS_IPHONE
|
||||
if (alignment == cocos2d::TextHAlignment::CENTER) alignment = cocos2d::TextHAlignment::RIGHT;
|
||||
else if (alignment == cocos2d::TextHAlignment::RIGHT) alignment = cocos2d::TextHAlignment::CENTER;
|
||||
if (alignment == cocos2d::TextHAlignment::CENTER)
|
||||
alignment = cocos2d::TextHAlignment::RIGHT;
|
||||
else if (alignment == cocos2d::TextHAlignment::RIGHT)
|
||||
alignment = cocos2d::TextHAlignment::CENTER;
|
||||
self.textInput.ccui_alignment = static_cast<NSTextAlignment>(alignment);
|
||||
}
|
||||
|
||||
- (void)setPlaceHolder:(const char *)text
|
||||
- (void)setPlaceHolder:(const char*)text
|
||||
{
|
||||
self.textInput.ccui_placeholder = [NSString stringWithUTF8String:text];
|
||||
}
|
||||
|
@ -282,14 +297,15 @@
|
|||
self.textInput.ccui_textColor = color;
|
||||
}
|
||||
|
||||
- (void)setFont:(NSFont *)font
|
||||
- (void)setFont:(NSFont*)font
|
||||
{
|
||||
if (font != nil) {
|
||||
if (font != nil)
|
||||
{
|
||||
self.textInput.ccui_font = font;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setPlaceholderFontColor:(NSColor *)color
|
||||
- (void)setPlaceholderFontColor:(NSColor*)color
|
||||
{
|
||||
self.textInput.ccui_placeholderColor = color;
|
||||
}
|
||||
|
@ -299,70 +315,76 @@
|
|||
self.textInput.ccui_placeholderFont = font;
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text
|
||||
- (void)setText:(NSString*)text
|
||||
{
|
||||
self.textInput.ccui_text = text;
|
||||
}
|
||||
|
||||
- (BOOL)textShouldBeginEditing:(NSText *)textObject // YES means do it
|
||||
- (BOOL)textShouldBeginEditing:(NSText*)textObject // YES means do it
|
||||
{
|
||||
_editState = YES;
|
||||
|
||||
|
||||
getEditBoxImplMac()->editBoxEditingDidBegin();
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)textDidEndEditing:(NSNotification *)notification
|
||||
- (void)textDidEndEditing:(NSNotification*)notification
|
||||
{
|
||||
_editState = NO;
|
||||
|
||||
getEditBoxImplMac()->editBoxEditingDidEnd([self getText], [self getEndAction:notification]);
|
||||
}
|
||||
|
||||
- (cocos2d::ui::EditBoxDelegate::EditBoxEndAction)getEndAction:(NSNotification *)notification
|
||||
- (cocos2d::ui::EditBoxDelegate::EditBoxEndAction)getEndAction:(NSNotification*)notification
|
||||
{
|
||||
auto type = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::UNKNOWN;
|
||||
auto type = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::UNKNOWN;
|
||||
NSUInteger reasonForEnding = [[[notification userInfo] objectForKey:@"NSTextMovement"] unsignedIntValue];
|
||||
if (reasonForEnding == NSTabTextMovement) {
|
||||
if (reasonForEnding == NSTabTextMovement)
|
||||
{
|
||||
type = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::TAB_TO_NEXT;
|
||||
} else if (reasonForEnding == NSBacktabTextMovement) {
|
||||
}
|
||||
else if (reasonForEnding == NSBacktabTextMovement)
|
||||
{
|
||||
type = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::TAB_TO_PREVIOUS;
|
||||
} else if (reasonForEnding == NSReturnTextMovement) {
|
||||
}
|
||||
else if (reasonForEnding == NSReturnTextMovement)
|
||||
{
|
||||
type = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::RETURN;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
- (void)textDidChange:(NSNotification *)notification
|
||||
- (void)textDidChange:(NSNotification*)notification
|
||||
{
|
||||
NSTextView* textView = notification.object;
|
||||
|
||||
|
||||
const char* inputText = [textView.string UTF8String];
|
||||
|
||||
|
||||
getEditBoxImplMac()->editBoxEditingChanged(inputText);
|
||||
}
|
||||
|
||||
- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString
|
||||
- (BOOL)textView:(NSTextView*)textView
|
||||
shouldChangeTextInRange:(NSRange)affectedCharRange
|
||||
replacementString:(NSString*)replacementString
|
||||
{
|
||||
int maxLength = getEditBoxImplMac()->getMaxLength();
|
||||
if (maxLength < 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (affectedCharRange.length + affectedCharRange.location > textView.string.length) {
|
||||
|
||||
if (affectedCharRange.length + affectedCharRange.location > textView.string.length)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSUInteger oldLength = textView.string.length;
|
||||
|
||||
NSUInteger oldLength = textView.string.length;
|
||||
NSUInteger replacementLength = replacementString.length;
|
||||
NSUInteger rangeLength = affectedCharRange.length;
|
||||
|
||||
NSUInteger rangeLength = affectedCharRange.length;
|
||||
|
||||
NSUInteger newLength = oldLength - rangeLength + replacementLength;
|
||||
|
||||
|
||||
return newLength <= maxLength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -224,7 +224,7 @@ public:
|
|||
std::string_view normalImage,
|
||||
std::string_view pressedImage = "",
|
||||
std::string_view disabledImage = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -284,7 +284,7 @@ public:
|
|||
std::string_view normalImage,
|
||||
std::string_view pressedImage = "",
|
||||
std::string_view disabledImage = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
* Load textures for edit box.
|
||||
|
@ -297,7 +297,7 @@ public:
|
|||
void loadTextures(std::string_view normal,
|
||||
std::string_view pressed,
|
||||
std::string_view disabled = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
* Load normal state texture for edit box.
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
Copyright (c) 2012 James Chen
|
||||
Copyright (c) 2013-2015 zilongshanren
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -28,43 +28,38 @@
|
|||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
|
||||
#define kLabelZOrder 9999
|
||||
# define kLabelZOrder 9999
|
||||
|
||||
#include "ui/UIEditBox/UIEditBox.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "2d/CCLabel.h"
|
||||
#import "platform/ios/CCEAGLView-ios.h"
|
||||
# include "ui/UIEditBox/UIEditBox.h"
|
||||
# include "base/CCDirector.h"
|
||||
# include "2d/CCLabel.h"
|
||||
# import "platform/ios/CCEAGLView-ios.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
# import <Foundation/Foundation.h>
|
||||
# import <UIKit/UIKit.h>
|
||||
|
||||
#import "ui/UIEditBox/iOS/CCUIEditBoxIOS.h"
|
||||
|
||||
#define getEditBoxImplIOS() ((cocos2d::ui::EditBoxImplIOS *)_editBox)
|
||||
# import "ui/UIEditBox/iOS/CCUIEditBoxIOS.h"
|
||||
|
||||
# define getEditBoxImplIOS() ((cocos2d::ui::EditBoxImplIOS*)_editBox)
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
namespace ui {
|
||||
namespace ui
|
||||
{
|
||||
|
||||
EditBoxImpl* __createSystemEditBox(EditBox* pEditBox)
|
||||
{
|
||||
return new EditBoxImplIOS(pEditBox);
|
||||
}
|
||||
|
||||
EditBoxImplIOS::EditBoxImplIOS(EditBox* pEditText)
|
||||
: EditBoxImplCommon(pEditText)
|
||||
, _systemControl(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
EditBoxImplIOS::EditBoxImplIOS(EditBox* pEditText) : EditBoxImplCommon(pEditText), _systemControl(nullptr) {}
|
||||
|
||||
EditBoxImplIOS::~EditBoxImplIOS()
|
||||
{
|
||||
[_systemControl release];
|
||||
_systemControl = nil;
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplIOS::createNativeControl(const Rect& frame)
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
|
@ -75,13 +70,10 @@ void EditBoxImplIOS::createNativeControl(const Rect& frame)
|
|||
|
||||
rect.size.width /= factor;
|
||||
rect.size.height /= factor;
|
||||
|
||||
_systemControl = [[UIEditBoxImplIOS_objc alloc] initWithFrame:CGRectMake(rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.size.width,
|
||||
rect.size.height)
|
||||
editBox:this];
|
||||
|
||||
_systemControl = [[UIEditBoxImplIOS_objc alloc]
|
||||
initWithFrame:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)
|
||||
editBox:this];
|
||||
}
|
||||
|
||||
bool EditBoxImplIOS::isEditing()
|
||||
|
@ -91,32 +83,34 @@ bool EditBoxImplIOS::isEditing()
|
|||
|
||||
void EditBoxImplIOS::doAnimationWhenKeyboardMove(float duration, float distance)
|
||||
{
|
||||
if ([_systemControl isEditState] || distance < 0.0f) {
|
||||
if ([_systemControl isEditState] || distance < 0.0f)
|
||||
{
|
||||
[_systemControl doAnimationWhenKeyboardMoveWithDuration:duration distance:distance];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplIOS::setNativeFont(const char* pFontName, int fontSize)
|
||||
{
|
||||
UIFont* textFont = constructFont(pFontName, fontSize);
|
||||
if (textFont != nil) {
|
||||
if (textFont != nil)
|
||||
{
|
||||
[_systemControl setFont:textFont];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplIOS::setNativeFontColor(const Color4B& color)
|
||||
{
|
||||
_systemControl.textColor = [UIColor colorWithRed:color.r / 255.0f
|
||||
green:color.g / 255.0f
|
||||
blue:color.b / 255.0f
|
||||
alpha:color.a / 255.f];
|
||||
|
||||
green:color.g / 255.0f
|
||||
blue:color.b / 255.0f
|
||||
alpha:color.a / 255.f];
|
||||
}
|
||||
|
||||
void EditBoxImplIOS::setNativePlaceholderFont(const char* pFontName, int fontSize)
|
||||
{
|
||||
UIFont* textFont = constructFont(pFontName, fontSize);
|
||||
if (textFont != nil) {
|
||||
if (textFont != nil)
|
||||
{
|
||||
[_systemControl setPlaceholderFont:textFont];
|
||||
}
|
||||
}
|
||||
|
@ -124,9 +118,9 @@ void EditBoxImplIOS::setNativePlaceholderFont(const char* pFontName, int fontSiz
|
|||
void EditBoxImplIOS::setNativePlaceholderFontColor(const Color4B& color)
|
||||
{
|
||||
[_systemControl setPlaceholderTextColor:[UIColor colorWithRed:color.r / 255.0f
|
||||
green:color.g / 255.0f
|
||||
blue:color.b / 255.0f
|
||||
alpha:color.a / 255.f]];
|
||||
green:color.g / 255.0f
|
||||
blue:color.b / 255.0f
|
||||
alpha:color.a / 255.f]];
|
||||
}
|
||||
|
||||
void EditBoxImplIOS::setNativeInputMode(EditBox::InputMode inputMode)
|
||||
|
@ -134,7 +128,7 @@ void EditBoxImplIOS::setNativeInputMode(EditBox::InputMode inputMode)
|
|||
[_systemControl setInputMode:inputMode];
|
||||
|
||||
auto oldPos = _editBox->getPosition();
|
||||
_editBox->setPosition(oldPos + Vec2(10,10));
|
||||
_editBox->setPosition(oldPos + Vec2(10, 10));
|
||||
_editBox->setPosition(oldPos);
|
||||
}
|
||||
|
||||
|
@ -142,7 +136,7 @@ void EditBoxImplIOS::setNativeInputFlag(EditBox::InputFlag inputFlag)
|
|||
{
|
||||
[_systemControl setInputFlag:inputFlag];
|
||||
}
|
||||
|
||||
|
||||
NSString* removeSiriString(NSString* str)
|
||||
{
|
||||
NSString* siriString = @"\xef\xbf\xbc";
|
||||
|
@ -154,7 +148,6 @@ const char* EditBoxImplIOS::getText()
|
|||
return [removeSiriString(_systemControl.text) UTF8String];
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplIOS::setNativeReturnType(EditBox::KeyboardReturnType returnType)
|
||||
{
|
||||
[_systemControl setReturnType:returnType];
|
||||
|
@ -167,8 +160,9 @@ void EditBoxImplIOS::setNativeTextHorizontalAlignment(cocos2d::TextHAlignment al
|
|||
|
||||
void EditBoxImplIOS::setNativeText(const char* pText)
|
||||
{
|
||||
NSString* nsText =[NSString stringWithUTF8String:pText];
|
||||
if ([nsText compare:_systemControl.text] != NSOrderedSame) {
|
||||
NSString* nsText = [NSString stringWithUTF8String:pText];
|
||||
if ([nsText compare:_systemControl.text] != NSOrderedSame)
|
||||
{
|
||||
_systemControl.text = nsText;
|
||||
}
|
||||
}
|
||||
|
@ -185,16 +179,13 @@ void EditBoxImplIOS::setNativeVisible(bool visible)
|
|||
|
||||
void EditBoxImplIOS::updateNativeFrame(const Rect& rect)
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView *eaglview = (CCEAGLView *) glview->getEAGLView();
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView* eaglview = (CCEAGLView*)glview->getEAGLView();
|
||||
|
||||
float factor = eaglview.contentScaleFactor;
|
||||
|
||||
[_systemControl updateFrame:CGRectMake(rect.origin.x / factor,
|
||||
rect.origin.y / factor,
|
||||
rect.size.width / factor,
|
||||
rect.size.height / factor)];
|
||||
|
||||
[_systemControl updateFrame:CGRectMake(rect.origin.x / factor, rect.origin.y / factor, rect.size.width / factor,
|
||||
rect.size.height / factor)];
|
||||
}
|
||||
|
||||
const char* EditBoxImplIOS::getNativeDefaultFontName()
|
||||
|
@ -213,33 +204,34 @@ void EditBoxImplIOS::nativeCloseKeyboard()
|
|||
{
|
||||
[_systemControl closeKeyboard];
|
||||
}
|
||||
|
||||
UIFont* EditBoxImplIOS::constructFont(const char *fontName, int fontSize)
|
||||
|
||||
UIFont* EditBoxImplIOS::constructFont(const char* fontName, int fontSize)
|
||||
{
|
||||
CCASSERT(fontName != nullptr, "fontName can't be nullptr");
|
||||
CCEAGLView *eaglview = static_cast<CCEAGLView *>(cocos2d::Director::getInstance()->getOpenGLView()->getEAGLView());
|
||||
float retinaFactor = eaglview.contentScaleFactor;
|
||||
NSString * fntName = [NSString stringWithUTF8String:fontName];
|
||||
|
||||
CCEAGLView* eaglview = static_cast<CCEAGLView*>(cocos2d::Director::getInstance()->getOpenGLView()->getEAGLView());
|
||||
float retinaFactor = eaglview.contentScaleFactor;
|
||||
NSString* fntName = [NSString stringWithUTF8String:fontName];
|
||||
|
||||
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
float scaleFactor = glview->getScaleX();
|
||||
|
||||
|
||||
if (fontSize == -1)
|
||||
{
|
||||
fontSize = _systemControl.frameRect.size.height*2/3;
|
||||
fontSize = _systemControl.frameRect.size.height * 2 / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
fontSize = fontSize * scaleFactor / retinaFactor;
|
||||
}
|
||||
|
||||
UIFont *textFont = nil;
|
||||
|
||||
UIFont* textFont = nil;
|
||||
if (strlen(fontName) > 0)
|
||||
{
|
||||
textFont = [UIFont fontWithName:fntName size:fontSize];
|
||||
if (textFont == nil) {
|
||||
if (textFont == nil)
|
||||
{
|
||||
textFont = [UIFont systemFontOfSize:fontSize];
|
||||
}
|
||||
}
|
||||
|
@ -254,5 +246,3 @@ UIFont* EditBoxImplIOS::constructFont(const char *fontName, int fontSize)
|
|||
NS_CC_END
|
||||
|
||||
#endif /* #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) */
|
||||
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2012 Jozef Pridavok
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -27,24 +27,23 @@
|
|||
#include "platform/CCPlatformConfig.h"
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
|
||||
#include "ui/UIEditBox/UIEditBoxImpl-mac.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/ccUTF8.h"
|
||||
#include "ui/UIEditBox/UIEditBox.h"
|
||||
#include "ui/UIEditBox/Mac/CCUIEditBoxMac.h"
|
||||
# include "ui/UIEditBox/UIEditBoxImpl-mac.h"
|
||||
# include "base/CCDirector.h"
|
||||
# include "base/ccUTF8.h"
|
||||
# include "ui/UIEditBox/UIEditBox.h"
|
||||
# include "ui/UIEditBox/Mac/CCUIEditBoxMac.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
namespace ui {
|
||||
namespace ui
|
||||
{
|
||||
|
||||
EditBoxImpl* __createSystemEditBox(EditBox* pEditBox)
|
||||
{
|
||||
return new EditBoxImplMac(pEditBox);
|
||||
}
|
||||
|
||||
EditBoxImplMac::EditBoxImplMac(EditBox* pEditText)
|
||||
: EditBoxImplCommon(pEditText)
|
||||
, _sysEdit(nullptr)
|
||||
EditBoxImplMac::EditBoxImplMac(EditBox* pEditText) : EditBoxImplCommon(pEditText), _sysEdit(nullptr)
|
||||
{
|
||||
//! TODO: Retina on Mac
|
||||
//! _inRetinaMode = [[CCEAGLView sharedEGLView] contentScaleFactor] == 2.0f ? true : false;
|
||||
|
@ -56,42 +55,40 @@ EditBoxImplMac::~EditBoxImplMac()
|
|||
[_sysEdit release];
|
||||
}
|
||||
|
||||
void EditBoxImplMac::createNativeControl(const cocos2d::Rect &frame)
|
||||
void EditBoxImplMac::createNativeControl(const cocos2d::Rect& frame)
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
Size size = frame.size;
|
||||
NSRect rect = NSMakeRect(0, 0,
|
||||
size.width * glview->getScaleX(),
|
||||
size.height * glview->getScaleY());
|
||||
|
||||
Size size = frame.size;
|
||||
NSRect rect = NSMakeRect(0, 0, size.width * glview->getScaleX(), size.height * glview->getScaleY());
|
||||
|
||||
float factor = cocos2d::Director::getInstance()->getContentScaleFactor();
|
||||
|
||||
|
||||
rect.size.width /= factor;
|
||||
rect.size.height /= factor;
|
||||
|
||||
|
||||
_sysEdit = [[UIEditBoxImplMac alloc] initWithFrame:rect editBox:this];
|
||||
this->setNativeVisible(false);
|
||||
}
|
||||
|
||||
NSFont* EditBoxImplMac::constructFont(const char *fontName, int fontSize)
|
||||
|
||||
NSFont* EditBoxImplMac::constructFont(const char* fontName, int fontSize)
|
||||
{
|
||||
NSString * fntName = [NSString stringWithUTF8String:fontName];
|
||||
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
|
||||
NSString* fntName = [NSString stringWithUTF8String:fontName];
|
||||
fntName = [[fntName lastPathComponent] stringByDeletingPathExtension];
|
||||
float retinaFactor = _inRetinaMode ? 2.0f : 1.0f;
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
float scaleFactor = glview->getScaleX();
|
||||
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
float scaleFactor = glview->getScaleX();
|
||||
|
||||
if (fontSize == -1)
|
||||
{
|
||||
NSRect frameRect = [_sysEdit.textInput frame];
|
||||
fontSize = frameRect.size.height*2/3;
|
||||
fontSize = frameRect.size.height * 2 / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
fontSize = fontSize * scaleFactor / retinaFactor;
|
||||
}
|
||||
|
||||
NSFont *textFont = nil;
|
||||
|
||||
NSFont* textFont = nil;
|
||||
if (strlen(fontName) == 0)
|
||||
{
|
||||
textFont = [NSFont systemFontOfSize:fontSize];
|
||||
|
@ -99,47 +96,49 @@ NSFont* EditBoxImplMac::constructFont(const char *fontName, int fontSize)
|
|||
else
|
||||
{
|
||||
textFont = [NSFont fontWithName:fntName size:fontSize];
|
||||
if (textFont == nil) {
|
||||
if (textFont == nil)
|
||||
{
|
||||
textFont = [NSFont systemFontOfSize:fontSize];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return textFont;
|
||||
}
|
||||
|
||||
void EditBoxImplMac::setNativeFont(const char *pFontName, int fontSize)
|
||||
void EditBoxImplMac::setNativeFont(const char* pFontName, int fontSize)
|
||||
{
|
||||
NSFont* textFont = constructFont(pFontName, fontSize);
|
||||
[_sysEdit setFont:textFont];
|
||||
}
|
||||
|
||||
void EditBoxImplMac::setNativePlaceholderFont(const char *pFontName, int fontSize)
|
||||
void EditBoxImplMac::setNativePlaceholderFont(const char* pFontName, int fontSize)
|
||||
{
|
||||
NSFont *textFont = constructFont(pFontName, fontSize);
|
||||
|
||||
if (!textFont) {
|
||||
NSFont* textFont = constructFont(pFontName, fontSize);
|
||||
|
||||
if (!textFont)
|
||||
{
|
||||
CCLOGWARN("Font not found: %s", pFontName);
|
||||
return;
|
||||
}
|
||||
[_sysEdit setPlaceholderFont:textFont];
|
||||
}
|
||||
|
||||
void EditBoxImplMac::setNativeFontColor(const cocos2d::Color4B &color)
|
||||
void EditBoxImplMac::setNativeFontColor(const cocos2d::Color4B& color)
|
||||
{
|
||||
NSColor *newColor = [NSColor colorWithCalibratedRed:color.r / 255.0f
|
||||
NSColor* newColor = [NSColor colorWithCalibratedRed:color.r / 255.0f
|
||||
green:color.g / 255.0f
|
||||
blue:color.b / 255.0f
|
||||
alpha:color.a / 255.f];
|
||||
|
||||
[_sysEdit setTextColor:newColor];
|
||||
}
|
||||
|
||||
void EditBoxImplMac::setNativePlaceholderFontColor(const cocos2d::Color4B &color)
|
||||
|
||||
void EditBoxImplMac::setNativePlaceholderFontColor(const cocos2d::Color4B& color)
|
||||
{
|
||||
NSColor *newColor = [NSColor colorWithCalibratedRed:color.r/255.f
|
||||
green:color.g / 255.f
|
||||
blue:color.b / 255.f
|
||||
alpha:color.a / 255.f];
|
||||
NSColor* newColor = [NSColor colorWithCalibratedRed:color.r / 255.f
|
||||
green:color.g / 255.f
|
||||
blue:color.b / 255.f
|
||||
alpha:color.a / 255.f];
|
||||
[_sysEdit setPlaceholderFontColor:newColor];
|
||||
}
|
||||
|
||||
|
@ -147,7 +146,7 @@ void EditBoxImplMac::setNativeInputMode(EditBox::InputMode inputMode)
|
|||
{
|
||||
[_sysEdit setInputMode:inputMode];
|
||||
auto oldPosition = _editBox->getPosition();
|
||||
_editBox->setPosition(_editBox->getPosition() + Vec2(10,10));
|
||||
_editBox->setPosition(_editBox->getPosition() + Vec2(10, 10));
|
||||
_editBox->setPosition(oldPosition);
|
||||
}
|
||||
|
||||
|
@ -156,7 +155,6 @@ void EditBoxImplMac::setNativeMaxLength(int maxLength)
|
|||
[_sysEdit setMaxLength:maxLength];
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplMac::setNativeInputFlag(EditBox::InputFlag inputFlag)
|
||||
{
|
||||
[_sysEdit setInputFlag:inputFlag];
|
||||
|
@ -177,12 +175,12 @@ bool EditBoxImplMac::isEditing()
|
|||
return [_sysEdit isEditState] ? true : false;
|
||||
}
|
||||
|
||||
void EditBoxImplMac::setNativeText(const char *pText)
|
||||
void EditBoxImplMac::setNativeText(const char* pText)
|
||||
{
|
||||
NSString *text = [NSString stringWithUTF8String:pText];
|
||||
NSString* text = [NSString stringWithUTF8String:pText];
|
||||
[_sysEdit setText:text];
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplMac::setNativePlaceHolder(const char* pText)
|
||||
{
|
||||
[_sysEdit setPlaceHolder:pText];
|
||||
|
@ -193,24 +191,21 @@ void EditBoxImplMac::setNativeVisible(bool visible)
|
|||
[_sysEdit setVisible:visible];
|
||||
}
|
||||
|
||||
void EditBoxImplMac::updateNativeFrame(const cocos2d::Rect &rect)
|
||||
void EditBoxImplMac::updateNativeFrame(const cocos2d::Rect& rect)
|
||||
{
|
||||
GLView* eglView = Director::getInstance()->getOpenGLView();
|
||||
auto frameSize = eglView->getFrameSize();
|
||||
auto frameSize = eglView->getFrameSize();
|
||||
// Coordinate System on OSX has its origin at the lower left corner.
|
||||
// https://developer.apple.com/library/ios/documentation/General/Conceptual/Devpedia-CocoaApp/CoordinateSystem.html
|
||||
// https://developer.apple.com/library/ios/documentation/General/Conceptual/Devpedia-CocoaApp/CoordinateSystem.html
|
||||
auto screenPosY = frameSize.height - rect.origin.y - rect.size.height;
|
||||
[_sysEdit updateFrame:CGRectMake(rect.origin.x,
|
||||
screenPosY,
|
||||
rect.size.width, rect.size.height)];
|
||||
[_sysEdit updateFrame:CGRectMake(rect.origin.x, screenPosY, rect.size.width, rect.size.height)];
|
||||
}
|
||||
|
||||
|
||||
const char* EditBoxImplMac::getNativeDefaultFontName()
|
||||
{
|
||||
return [[_sysEdit getDefaultFontName] UTF8String];
|
||||
}
|
||||
|
||||
|
||||
void EditBoxImplMac::nativeOpenKeyboard()
|
||||
{
|
||||
[_sysEdit setVisible:YES];
|
||||
|
@ -226,6 +221,4 @@ void EditBoxImplMac::nativeCloseKeyboard()
|
|||
|
||||
NS_CC_END
|
||||
|
||||
#endif // #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
|
||||
|
||||
#endif // #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
|
|
|
@ -4,19 +4,19 @@
|
|||
Copyright (c) 2013-2015 zilongshanren
|
||||
Copyright (c) 2015 Mazyad Alabduljaleel
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -33,8 +33,7 @@
|
|||
#import "platform/ios/CCEAGLView-ios.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
||||
#define getEditBoxImplIOS() ((cocos2d::ui::EditBoxImplIOS *)_editBox)
|
||||
|
||||
#define getEditBoxImplIOS() ((cocos2d::ui::EditBoxImplIOS*)_editBox)
|
||||
|
||||
@implementation UIEditBoxImplIOS_objc
|
||||
|
||||
|
@ -43,27 +42,28 @@
|
|||
+ (void)initialize
|
||||
{
|
||||
[super initialize];
|
||||
|
||||
|
||||
LoadUITextViewCCUITextInputCategory();
|
||||
LoadUITextFieldCCUITextInputCategory();
|
||||
}
|
||||
|
||||
#pragma mark - Init & Dealloc
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frameRect editBox:(void *)editBox
|
||||
- (instancetype)initWithFrame:(CGRect)frameRect editBox:(void*)editBox
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
_editState = NO;
|
||||
self.frameRect = frameRect;
|
||||
self.editBox = editBox;
|
||||
self.dataInputMode = cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS;
|
||||
if (self)
|
||||
{
|
||||
|
||||
_editState = NO;
|
||||
self.frameRect = frameRect;
|
||||
self.editBox = editBox;
|
||||
self.dataInputMode = cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS;
|
||||
self.keyboardReturnType = cocos2d::ui::EditBox::KeyboardReturnType::DEFAULT;
|
||||
|
||||
|
||||
[self createMultiLineTextField];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -71,38 +71,39 @@
|
|||
{
|
||||
// custom setter cleanup
|
||||
self.textInput = nil;
|
||||
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setTextInput:(UIView<UITextInput,CCUITextInput> *)textInput
|
||||
- (void)setTextInput:(UIView<UITextInput, CCUITextInput>*)textInput
|
||||
{
|
||||
if (_textInput == textInput) {
|
||||
if (_textInput == textInput)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// common init
|
||||
textInput.backgroundColor = [UIColor clearColor];
|
||||
textInput.hidden = true;
|
||||
textInput.returnKeyType = UIReturnKeyDefault;
|
||||
textInput.hidden = true;
|
||||
textInput.returnKeyType = UIReturnKeyDefault;
|
||||
[textInput ccui_setDelegate:self];
|
||||
|
||||
|
||||
// Migrate properties
|
||||
textInput.ccui_textColor = _textInput.ccui_textColor ?: [UIColor whiteColor];
|
||||
textInput.ccui_text = _textInput.ccui_text ?: @"";
|
||||
textInput.ccui_textColor = _textInput.ccui_textColor ?: [UIColor whiteColor];
|
||||
textInput.ccui_text = _textInput.ccui_text ?: @"";
|
||||
textInput.ccui_placeholder = _textInput.ccui_placeholder ?: @"";
|
||||
textInput.ccui_font = _textInput.ccui_font ?: [UIFont systemFontOfSize:self.frameRect.size.height*2/3];
|
||||
textInput.ccui_placeholderFont = _textInput.ccui_placeholderFont ?: textInput.ccui_font;
|
||||
textInput.ccui_font = _textInput.ccui_font ?: [UIFont systemFontOfSize:self.frameRect.size.height * 2 / 3];
|
||||
textInput.ccui_placeholderFont = _textInput.ccui_placeholderFont ?: textInput.ccui_font;
|
||||
textInput.ccui_placeholderTextColor = _textInput.ccui_placeholderTextColor ?: [UIColor lightGrayColor];
|
||||
|
||||
|
||||
[_textInput resignFirstResponder];
|
||||
[_textInput removeFromSuperview];
|
||||
[_textInput release];
|
||||
|
||||
|
||||
_textInput = [textInput retain];
|
||||
|
||||
|
||||
[self setInputFlag:self.dataInputMode];
|
||||
[self setReturnType:self.keyboardReturnType];
|
||||
}
|
||||
|
@ -111,24 +112,24 @@
|
|||
|
||||
- (void)createSingleLineTextField
|
||||
{
|
||||
CCUISingleLineTextField *textField = [[[CCUISingleLineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
CCUISingleLineTextField* textField = [[[CCUISingleLineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
|
||||
textField.borderStyle = UITextBorderStyleNone;
|
||||
|
||||
textField.borderStyle = UITextBorderStyleNone;
|
||||
|
||||
[textField addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged];
|
||||
|
||||
|
||||
self.textInput = textField;
|
||||
}
|
||||
|
||||
- (void)createMultiLineTextField
|
||||
{
|
||||
CCUIMultilineTextField *textView = [[[CCUIMultilineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
self.textInput = textView;
|
||||
CCUIMultilineTextField* textView = [[[CCUIMultilineTextField alloc] initWithFrame:self.frameRect] autorelease];
|
||||
self.textInput = textView;
|
||||
}
|
||||
|
||||
#pragma mark - Public methods
|
||||
|
||||
- (void)setFont:(UIFont *)font
|
||||
- (void)setFont:(UIFont*)font
|
||||
{
|
||||
self.textInput.ccui_font = font;
|
||||
}
|
||||
|
@ -138,53 +139,57 @@
|
|||
self.textInput.ccui_textColor = color;
|
||||
}
|
||||
|
||||
- (void)setPlaceholderFont:(UIFont *)font
|
||||
- (void)setPlaceholderFont:(UIFont*)font
|
||||
{
|
||||
self.textInput.ccui_placeholderFont = font;
|
||||
}
|
||||
|
||||
- (void)setPlaceholderTextColor:(UIColor *)color
|
||||
- (void)setPlaceholderTextColor:(UIColor*)color
|
||||
{
|
||||
self.textInput.ccui_placeholderTextColor = color;
|
||||
}
|
||||
|
||||
- (void)setInputMode:(cocos2d::ui::EditBox::InputMode)inputMode
|
||||
{
|
||||
//multiline input
|
||||
if (inputMode == cocos2d::ui::EditBox::InputMode::ANY) {
|
||||
if (![self.textInput isKindOfClass:[UITextView class]]) {
|
||||
// multiline input
|
||||
if (inputMode == cocos2d::ui::EditBox::InputMode::ANY)
|
||||
{
|
||||
if (![self.textInput isKindOfClass:[UITextView class]])
|
||||
{
|
||||
[self createMultiLineTextField];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (![self.textInput isKindOfClass:[UITextField class]]) {
|
||||
else
|
||||
{
|
||||
if (![self.textInput isKindOfClass:[UITextField class]])
|
||||
{
|
||||
[self createSingleLineTextField];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (inputMode)
|
||||
{
|
||||
case cocos2d::ui::EditBox::InputMode::EMAIL_ADDRESS:
|
||||
self.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::NUMERIC:
|
||||
self.keyboardType = UIKeyboardTypeDecimalPad;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::PHONE_NUMBER:
|
||||
self.keyboardType = UIKeyboardTypePhonePad;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::URL:
|
||||
self.keyboardType = UIKeyboardTypeURL;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::DECIMAL:
|
||||
self.keyboardType = UIKeyboardTypeDecimalPad;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::SINGLE_LINE:
|
||||
self.keyboardType = UIKeyboardTypeDefault;
|
||||
break;
|
||||
default:
|
||||
self.keyboardType = UIKeyboardTypeDefault;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::EMAIL_ADDRESS:
|
||||
self.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::NUMERIC:
|
||||
self.keyboardType = UIKeyboardTypeDecimalPad;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::PHONE_NUMBER:
|
||||
self.keyboardType = UIKeyboardTypePhonePad;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::URL:
|
||||
self.keyboardType = UIKeyboardTypeURL;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::DECIMAL:
|
||||
self.keyboardType = UIKeyboardTypeDecimalPad;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputMode::SINGLE_LINE:
|
||||
self.keyboardType = UIKeyboardTypeDefault;
|
||||
break;
|
||||
default:
|
||||
self.keyboardType = UIKeyboardTypeDefault;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,67 +203,68 @@
|
|||
self.dataInputMode = flag;
|
||||
switch (flag)
|
||||
{
|
||||
case cocos2d::ui::EditBox::InputFlag::PASSWORD:
|
||||
//textView can't be used for input password
|
||||
self.textInput.ccui_secureTextEntry = YES;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_WORD:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeWords;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_SENTENCE:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeSentences;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_ALL_CHARACTERS:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::SENSITIVE:
|
||||
self.textInput.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case cocos2d::ui::EditBox::InputFlag::PASSWORD:
|
||||
// textView can't be used for input password
|
||||
self.textInput.ccui_secureTextEntry = YES;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_WORD:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeWords;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_SENTENCE:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeSentences;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::INITIAL_CAPS_ALL_CHARACTERS:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::SENSITIVE:
|
||||
self.textInput.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::InputFlag::LOWERCASE_ALL_CHARACTERS:
|
||||
self.textInput.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setReturnType:(cocos2d::ui::EditBox::KeyboardReturnType)returnType
|
||||
{
|
||||
self.keyboardReturnType = returnType;
|
||||
switch (returnType) {
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::DEFAULT:
|
||||
self.textInput.returnKeyType = UIReturnKeyDefault;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::DONE:
|
||||
self.textInput.returnKeyType = UIReturnKeyDone;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::SEND:
|
||||
self.textInput.returnKeyType = UIReturnKeySend;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::SEARCH:
|
||||
self.textInput.returnKeyType = UIReturnKeySearch;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::GO:
|
||||
self.textInput.returnKeyType = UIReturnKeyGo;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::NEXT:
|
||||
self.textInput.returnKeyType = UIReturnKeyNext;
|
||||
break;
|
||||
switch (returnType)
|
||||
{
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::DEFAULT:
|
||||
self.textInput.returnKeyType = UIReturnKeyDefault;
|
||||
break;
|
||||
|
||||
default:
|
||||
self.textInput.returnKeyType = UIReturnKeyDefault;
|
||||
break;
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::DONE:
|
||||
self.textInput.returnKeyType = UIReturnKeyDone;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::SEND:
|
||||
self.textInput.returnKeyType = UIReturnKeySend;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::SEARCH:
|
||||
self.textInput.returnKeyType = UIReturnKeySearch;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::GO:
|
||||
self.textInput.returnKeyType = UIReturnKeyGo;
|
||||
break;
|
||||
|
||||
case cocos2d::ui::EditBox::KeyboardReturnType::NEXT:
|
||||
self.textInput.returnKeyType = UIReturnKeyNext;
|
||||
break;
|
||||
|
||||
default:
|
||||
self.textInput.returnKeyType = UIReturnKeyDefault;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,12 +273,12 @@
|
|||
self.textInput.ccui_alignment = static_cast<NSTextAlignment>(alignment);
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text
|
||||
- (void)setText:(NSString*)text
|
||||
{
|
||||
self.textInput.ccui_text = text;
|
||||
}
|
||||
|
||||
- (NSString *)text
|
||||
- (NSString*)text
|
||||
{
|
||||
return self.textInput.ccui_text ?: @"";
|
||||
}
|
||||
|
@ -282,7 +288,7 @@
|
|||
self.textInput.hidden = !visible;
|
||||
}
|
||||
|
||||
- (NSString *)getDefaultFontName
|
||||
- (NSString*)getDefaultFontName
|
||||
{
|
||||
return self.textInput.ccui_font.fontName ?: @"";
|
||||
}
|
||||
|
@ -290,28 +296,32 @@
|
|||
- (cocos2d::ui::EditBoxDelegate::EditBoxEndAction)getEndAction
|
||||
{
|
||||
cocos2d::ui::EditBoxDelegate::EditBoxEndAction action = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::UNKNOWN;
|
||||
if (self.returnPressed) {
|
||||
if (self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::NEXT) {
|
||||
if (self.returnPressed)
|
||||
{
|
||||
if (self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::NEXT)
|
||||
{
|
||||
action = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::TAB_TO_NEXT;
|
||||
} else if (self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::GO ||
|
||||
self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::SEND ||
|
||||
self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::SEARCH) {
|
||||
}
|
||||
else if (self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::GO ||
|
||||
self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::SEND ||
|
||||
self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::SEARCH)
|
||||
{
|
||||
action = cocos2d::ui::EditBoxDelegate::EditBoxEndAction::RETURN;
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
- (void)setPlaceHolder:(NSString *)text
|
||||
- (void)setPlaceHolder:(NSString*)text
|
||||
{
|
||||
self.textInput.ccui_placeholder = text;
|
||||
}
|
||||
|
||||
- (void)doAnimationWhenKeyboardMoveWithDuration:(float)duration distance:(float)distance
|
||||
{
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView *eaglview = (CCEAGLView *)view->getEAGLView();
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView* eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
|
||||
[eaglview doAnimationWhenKeyboardMoveWithDuration:duration distance:distance];
|
||||
}
|
||||
|
||||
|
@ -319,16 +329,16 @@
|
|||
{
|
||||
CGRect frame = self.textInput.frame;
|
||||
frame.origin = rect.origin;
|
||||
frame.size = rect.size;
|
||||
|
||||
frame.size = rect.size;
|
||||
|
||||
self.textInput.frame = frame;
|
||||
}
|
||||
|
||||
- (void)openKeyboard
|
||||
{
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView *eaglview = (CCEAGLView *)view->getEAGLView();
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView* eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
|
||||
[eaglview addSubview:self.textInput];
|
||||
[self.textInput becomeFirstResponder];
|
||||
}
|
||||
|
@ -339,9 +349,10 @@
|
|||
[self.textInput removeFromSuperview];
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)sender
|
||||
- (BOOL)textFieldShouldReturn:(UITextField*)sender
|
||||
{
|
||||
if (sender == self.textInput) {
|
||||
if (sender == self.textInput)
|
||||
{
|
||||
self.returnPressed = YES;
|
||||
[sender resignFirstResponder];
|
||||
}
|
||||
|
@ -350,32 +361,33 @@
|
|||
|
||||
- (void)animationSelector
|
||||
{
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView *eaglview = (CCEAGLView *)view->getEAGLView();
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView* eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
|
||||
[eaglview doAnimationWhenAnotherEditBeClicked];
|
||||
}
|
||||
|
||||
#pragma mark - UITextView delegate methods
|
||||
|
||||
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
|
||||
- (BOOL)textViewShouldBeginEditing:(UITextView*)textView
|
||||
{
|
||||
CCLOG("textFieldShouldBeginEditing...");
|
||||
_editState = YES;
|
||||
_editState = YES;
|
||||
_returnPressed = NO;
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView *eaglview = (CCEAGLView *) view->getEAGLView();
|
||||
|
||||
if ([eaglview isKeyboardShown]) {
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView* eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
|
||||
if ([eaglview isKeyboardShown])
|
||||
{
|
||||
[self performSelector:@selector(animationSelector) withObject:nil afterDelay:0.0f];
|
||||
}
|
||||
|
||||
|
||||
getEditBoxImplIOS()->editBoxEditingDidBegin();
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textViewShouldEndEditing:(UITextView *)textView
|
||||
- (BOOL)textViewShouldEndEditing:(UITextView*)textView
|
||||
{
|
||||
CCLOG("textFieldShouldEndEditing...");
|
||||
_editState = NO;
|
||||
|
@ -383,94 +395,99 @@
|
|||
|
||||
const char* inputText = [textView.text UTF8String];
|
||||
getEditBoxImplIOS()->editBoxEditingDidEnd(inputText, [self getEndAction]);
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
|
||||
- (BOOL)textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text
|
||||
{
|
||||
if ( self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::DONE &&
|
||||
[text isEqualToString: @"\n"] )
|
||||
if (self.keyboardReturnType == cocos2d::ui::EditBox::KeyboardReturnType::DONE && [text isEqualToString:@"\n"])
|
||||
{
|
||||
[self closeKeyboard];
|
||||
}
|
||||
|
||||
|
||||
int maxLength = getEditBoxImplIOS()->getMaxLength();
|
||||
if (maxLength < 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Prevent crashing undo bug http://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield
|
||||
if (range.length + range.location > textView.text.length) {
|
||||
|
||||
// Prevent crashing undo bug
|
||||
// http://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield
|
||||
if (range.length + range.location > textView.text.length)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSUInteger oldLength = textView.text.length;
|
||||
|
||||
NSUInteger oldLength = textView.text.length;
|
||||
NSUInteger replacementLength = text.length;
|
||||
NSUInteger rangeLength = range.length;
|
||||
|
||||
NSUInteger rangeLength = range.length;
|
||||
|
||||
NSUInteger newLength = oldLength - rangeLength + replacementLength;
|
||||
|
||||
|
||||
return newLength <= maxLength;
|
||||
}
|
||||
|
||||
- (void)textViewDidChange:(UITextView *)textView
|
||||
- (void)textViewDidChange:(UITextView*)textView
|
||||
{
|
||||
int maxLength = getEditBoxImplIOS()->getMaxLength();
|
||||
if (textView.markedTextRange == nil) {
|
||||
if (textView.text.length > maxLength) {
|
||||
if (textView.markedTextRange == nil)
|
||||
{
|
||||
if (textView.text.length > maxLength)
|
||||
{
|
||||
textView.text = [textView.text substringToIndex:maxLength];
|
||||
}
|
||||
|
||||
|
||||
const char* inputText = [textView.text UTF8String];
|
||||
getEditBoxImplIOS()->editBoxEditingChanged(inputText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UITextField delegate methods
|
||||
/**
|
||||
* Called each time when the text field's text has changed.
|
||||
*/
|
||||
- (void)textChanged:(UITextField *)textField
|
||||
- (void)textChanged:(UITextField*)textField
|
||||
{
|
||||
int maxLength = getEditBoxImplIOS()->getMaxLength();
|
||||
if (textField.markedTextRange == nil) {
|
||||
if (textField.text.length > maxLength) {
|
||||
if (textField.markedTextRange == nil)
|
||||
{
|
||||
if (textField.text.length > maxLength)
|
||||
{
|
||||
textField.text = [textField.text substringToIndex:maxLength];
|
||||
}
|
||||
|
||||
|
||||
const char* inputText = [textField.text UTF8String];
|
||||
getEditBoxImplIOS()->editBoxEditingChanged(inputText);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldBeginEditing:(UITextField *)sender // return NO to disallow editing.
|
||||
- (BOOL)textFieldShouldBeginEditing:(UITextField*)sender // return NO to disallow editing.
|
||||
{
|
||||
CCLOG("textFieldShouldBeginEditing...");
|
||||
_editState = YES;
|
||||
_editState = YES;
|
||||
_returnPressed = NO;
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView *eaglview = (CCEAGLView *)view->getEAGLView();
|
||||
|
||||
if ([eaglview isKeyboardShown]) {
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
CCEAGLView* eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
|
||||
if ([eaglview isKeyboardShown])
|
||||
{
|
||||
[self performSelector:@selector(animationSelector) withObject:nil afterDelay:0.0f];
|
||||
}
|
||||
|
||||
|
||||
getEditBoxImplIOS()->editBoxEditingDidBegin();
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldEndEditing:(UITextField *)sender
|
||||
- (BOOL)textFieldShouldEndEditing:(UITextField*)sender
|
||||
{
|
||||
CCLOG("textFieldShouldEndEditing...");
|
||||
_editState = NO;
|
||||
_editState = NO;
|
||||
const char* inputText = [sender.text UTF8String];
|
||||
|
||||
getEditBoxImplIOS()->editBoxEditingDidEnd(inputText, [self getEndAction]);
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -481,24 +498,29 @@
|
|||
* @param string The replacement string.
|
||||
* @return YES if the specified text range should be replaced; otherwise, NO to keep the old text.
|
||||
*/
|
||||
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
||||
- (BOOL)textField:(UITextField*)textField
|
||||
shouldChangeCharactersInRange:(NSRange)range
|
||||
replacementString:(NSString*)string
|
||||
{
|
||||
int maxLength = getEditBoxImplIOS()->getMaxLength();
|
||||
if (maxLength < 0) {
|
||||
if (maxLength < 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Prevent crashing undo bug http://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield
|
||||
if (range.length + range.location > textField.text.length) {
|
||||
|
||||
// Prevent crashing undo bug
|
||||
// http://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield
|
||||
if (range.length + range.location > textField.text.length)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSUInteger oldLength = textField.text.length;
|
||||
|
||||
NSUInteger oldLength = textField.text.length;
|
||||
NSUInteger replacementLength = string.length;
|
||||
NSUInteger rangeLength = range.length;
|
||||
|
||||
NSUInteger rangeLength = range.length;
|
||||
|
||||
NSUInteger newLength = oldLength - rangeLength + replacementLength;
|
||||
|
||||
|
||||
return newLength <= maxLength;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
Copyright (c) 2012 James Chen
|
||||
Copyright (c) 2015 Mazyad Alabduljaleel
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -34,7 +34,6 @@
|
|||
*/
|
||||
CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
|
||||
|
||||
|
||||
@implementation CCUIMultilineTextField
|
||||
|
||||
#pragma mark - Init & Dealloc
|
||||
|
@ -42,8 +41,9 @@ CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
|
|||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
|
||||
if (self)
|
||||
{
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(textChanged:)
|
||||
name:UITextViewTextDidChangeNotification
|
||||
|
@ -55,51 +55,50 @@ CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
|
|||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
|
||||
[_placeHolderLabel release];
|
||||
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (NSString *)placeholder
|
||||
- (NSString*)placeholder
|
||||
{
|
||||
return self.placeHolderLabel.text;
|
||||
}
|
||||
|
||||
- (void)setPlaceholder:(NSString *)placeholder
|
||||
- (void)setPlaceholder:(NSString*)placeholder
|
||||
{
|
||||
self.placeHolderLabel.text = placeholder;
|
||||
[self.placeHolderLabel sizeToFit];
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text
|
||||
- (void)setText:(NSString*)text
|
||||
{
|
||||
[super setText:text];
|
||||
[self textChanged:nil];
|
||||
}
|
||||
|
||||
- (UILabel *)placeHolderLabel
|
||||
- (UILabel*)placeHolderLabel
|
||||
{
|
||||
if (_placeHolderLabel == nil) {
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
if (_placeHolderLabel == nil)
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
float padding = CC_EDIT_BOX_PADDING * glview->getScaleX() / glview->getContentScaleFactor();
|
||||
|
||||
_placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(padding,
|
||||
padding,
|
||||
self.bounds.size.width - padding * 2,
|
||||
0)];
|
||||
_placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
_placeHolderLabel.numberOfLines = 0;
|
||||
_placeHolderLabel.font = self.font;
|
||||
_placeHolderLabel =
|
||||
[[UILabel alloc] initWithFrame:CGRectMake(padding, padding, self.bounds.size.width - padding * 2, 0)];
|
||||
_placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
_placeHolderLabel.numberOfLines = 0;
|
||||
_placeHolderLabel.font = self.font;
|
||||
_placeHolderLabel.backgroundColor = [UIColor clearColor];
|
||||
_placeHolderLabel.textColor = [UIColor lightGrayColor];
|
||||
_placeHolderLabel.alpha = 0;
|
||||
|
||||
_placeHolderLabel.textColor = [UIColor lightGrayColor];
|
||||
_placeHolderLabel.alpha = 0;
|
||||
|
||||
[self addSubview:_placeHolderLabel];
|
||||
}
|
||||
|
||||
|
||||
return _placeHolderLabel;
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
|
|||
- (CGRect)textRectForBounds:(CGRect)bounds
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
|
||||
|
||||
float padding = CC_EDIT_BOX_PADDING * glview->getScaleX() / glview->getContentScaleFactor();
|
||||
return CGRectInset(bounds, padding, padding);
|
||||
}
|
||||
|
@ -121,34 +120,37 @@ CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
|
|||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
if (self.placeholder.length > 0) {
|
||||
|
||||
if (self.placeholder.length > 0)
|
||||
{
|
||||
[self sendSubviewToBack:self.placeHolderLabel];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
if (self.text.length == 0 && self.placeholder.length > 0) {
|
||||
if (self.text.length == 0 && self.placeholder.length > 0)
|
||||
{
|
||||
self.placeHolderLabel.alpha = 1;
|
||||
}
|
||||
|
||||
|
||||
[super drawRect:rect];
|
||||
}
|
||||
|
||||
#pragma mark - NSNotification Observers
|
||||
|
||||
- (void)textChanged:(NSNotification *)notification
|
||||
- (void)textChanged:(NSNotification*)notification
|
||||
{
|
||||
if (self.placeholder.length == 0) {
|
||||
if (self.placeholder.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[UIView animateWithDuration:UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION animations:^{
|
||||
|
||||
CGFloat alpha = (self.text.length == 0 ? 1 : 0);
|
||||
self.placeHolderLabel.alpha = alpha;
|
||||
}];
|
||||
|
||||
[UIView animateWithDuration:UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION
|
||||
animations:^{
|
||||
CGFloat alpha = (self.text.length == 0 ? 1 : 0);
|
||||
self.placeHolderLabel.alpha = alpha;
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
Copyright (c) 2012 James Chen
|
||||
Copyright (c) 2015 Mazyad Alabduljaleel
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -34,7 +34,6 @@
|
|||
* http://stackoverflow.com/questions/18244790/changing-uitextfield-placeholder-font
|
||||
*/
|
||||
|
||||
|
||||
@implementation CCUISingleLineTextField
|
||||
|
||||
#pragma mark - Init & Dealloc
|
||||
|
@ -49,29 +48,28 @@
|
|||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (UIColor *)placeholderTextColor
|
||||
- (UIColor*)placeholderTextColor
|
||||
{
|
||||
return _placeholderTextColor;
|
||||
}
|
||||
|
||||
- (UIFont *)placeholderFont
|
||||
- (UIFont*)placeholderFont
|
||||
{
|
||||
return _placeholderFont;
|
||||
}
|
||||
|
||||
#pragma mark - Public methods
|
||||
|
||||
- (void)drawPlaceholderInRect:(CGRect)rect {
|
||||
NSDictionary *attributes = @{
|
||||
NSForegroundColorAttributeName:_placeholderTextColor,
|
||||
NSFontAttributeName:_placeholderFont
|
||||
};
|
||||
|
||||
- (void)drawPlaceholderInRect:(CGRect)rect
|
||||
{
|
||||
NSDictionary* attributes =
|
||||
@{NSForegroundColorAttributeName : _placeholderTextColor, NSFontAttributeName : _placeholderFont};
|
||||
|
||||
// center vertically
|
||||
CGSize textSize = [self.placeholder sizeWithAttributes:attributes];
|
||||
CGFloat hdif = rect.size.height - textSize.height;
|
||||
hdif = MAX(0, hdif);
|
||||
rect.origin.y += ceil(hdif/2.0);
|
||||
CGFloat hdif = rect.size.height - textSize.height;
|
||||
hdif = MAX(0, hdif);
|
||||
rect.origin.y += ceil(hdif / 2.0);
|
||||
|
||||
[[self placeholder] drawInRect:rect withAttributes:attributes];
|
||||
}
|
||||
|
@ -79,7 +77,7 @@
|
|||
- (CGRect)textRectForBounds:(CGRect)bounds
|
||||
{
|
||||
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
|
||||
|
||||
float padding = CC_EDIT_BOX_PADDING * glview->getScaleX() / glview->getContentScaleFactor();
|
||||
return CGRectInset(bounds, padding, padding);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2015 Mazyad Alabduljaleel
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -27,86 +27,90 @@
|
|||
|
||||
@implementation UITextField (CCUITextInput)
|
||||
|
||||
- (NSString *)ccui_text
|
||||
- (NSString*)ccui_text
|
||||
{
|
||||
return self.text;
|
||||
}
|
||||
|
||||
- (void)ccui_setText:(NSString *)ccui_text
|
||||
- (void)ccui_setText:(NSString*)ccui_text
|
||||
{
|
||||
self.text = ccui_text;
|
||||
}
|
||||
|
||||
- (NSString *)ccui_placeholder
|
||||
- (NSString*)ccui_placeholder
|
||||
{
|
||||
return self.placeholder;
|
||||
}
|
||||
|
||||
- (void)ccui_setPlaceholder:(NSString *)ccui_placeholder
|
||||
- (void)ccui_setPlaceholder:(NSString*)ccui_placeholder
|
||||
{
|
||||
self.placeholder = ccui_placeholder;
|
||||
}
|
||||
|
||||
- (UIColor *)ccui_textColor
|
||||
- (UIColor*)ccui_textColor
|
||||
{
|
||||
return self.textColor;
|
||||
}
|
||||
|
||||
- (void)ccui_setTextColor:(UIColor *)ccui_textColor
|
||||
- (void)ccui_setTextColor:(UIColor*)ccui_textColor
|
||||
{
|
||||
self.textColor = ccui_textColor;
|
||||
}
|
||||
|
||||
- (UIFont *)ccui_font
|
||||
- (UIFont*)ccui_font
|
||||
{
|
||||
return self.font;
|
||||
}
|
||||
|
||||
- (void)ccui_setFont:(UIFont *)ccui_font
|
||||
- (void)ccui_setFont:(UIFont*)ccui_font
|
||||
{
|
||||
self.font = ccui_font;
|
||||
}
|
||||
|
||||
- (NSTextAlignment)ccui_alignment
|
||||
{
|
||||
return self.textAlignment;
|
||||
return self.textAlignment;
|
||||
}
|
||||
|
||||
- (void)ccui_setTextHorizontalAlignment:(NSTextAlignment)ccui_alignment
|
||||
{
|
||||
self.textAlignment = ccui_alignment;
|
||||
self.textAlignment = ccui_alignment;
|
||||
}
|
||||
|
||||
- (UIColor *)ccui_placeholderTextColor
|
||||
- (UIColor*)ccui_placeholderTextColor
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"placeholderTextColor");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
return [self performSelector:selector];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)ccui_setPlaceholderTextColor:(UIColor *)ccui_placeholderTextColor
|
||||
- (void)ccui_setPlaceholderTextColor:(UIColor*)ccui_placeholderTextColor
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"setPlaceholderTextColor:");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
[self performSelector:selector withObject:ccui_placeholderTextColor];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIFont *)ccui_placeholderFont
|
||||
- (UIFont*)ccui_placeholderFont
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"placeholderFont");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
return [self performSelector:selector];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)ccui_setPlaceholderFont:(UIFont *)ccui_placeholderFont
|
||||
- (void)ccui_setPlaceholderFont:(UIFont*)ccui_placeholderFont
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"setPlaceholderFont:");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
[self performSelector:selector withObject:ccui_placeholderFont];
|
||||
}
|
||||
}
|
||||
|
@ -121,14 +125,14 @@
|
|||
self.secureTextEntry = ccui_secureTextEntry;
|
||||
}
|
||||
|
||||
- (void)ccui_setDelegate:(id<UITextFieldDelegate,UITextViewDelegate>)delegate
|
||||
- (void)ccui_setDelegate:(id<UITextFieldDelegate, UITextViewDelegate>)delegate
|
||||
{
|
||||
self.delegate = delegate;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
void LoadUITextFieldCCUITextInputCategory() {
|
||||
void LoadUITextFieldCCUITextInputCategory()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2015 Mazyad Alabduljaleel
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -25,52 +25,53 @@
|
|||
|
||||
#import "ui/UIEditBox/iOS/UITextView+CCUITextInput.h"
|
||||
|
||||
|
||||
@implementation UITextView (CCUITextInput)
|
||||
|
||||
- (NSString *)ccui_text
|
||||
- (NSString*)ccui_text
|
||||
{
|
||||
return self.text;
|
||||
}
|
||||
|
||||
- (void)ccui_setText:(NSString *)ccui_text
|
||||
- (void)ccui_setText:(NSString*)ccui_text
|
||||
{
|
||||
self.text = ccui_text;
|
||||
}
|
||||
|
||||
- (NSString *)ccui_placeholder
|
||||
- (NSString*)ccui_placeholder
|
||||
{
|
||||
SEL selector = @selector(placeholder);
|
||||
if ([self respondsToSelector:selector]) {
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
return [self performSelector:selector];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)ccui_setPlaceholder:(NSString *)ccui_placeholder
|
||||
- (void)ccui_setPlaceholder:(NSString*)ccui_placeholder
|
||||
{
|
||||
SEL selector = @selector(setPlaceholder:);
|
||||
if ([self respondsToSelector:selector]) {
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
[self performSelector:selector withObject:ccui_placeholder];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIColor *)ccui_textColor
|
||||
- (UIColor*)ccui_textColor
|
||||
{
|
||||
return self.textColor;
|
||||
}
|
||||
|
||||
- (void)ccui_setTextColor:(UIColor *)ccui_textColor
|
||||
- (void)ccui_setTextColor:(UIColor*)ccui_textColor
|
||||
{
|
||||
self.textColor = ccui_textColor;
|
||||
}
|
||||
|
||||
- (UIFont *)ccui_font
|
||||
- (UIFont*)ccui_font
|
||||
{
|
||||
return self.font;
|
||||
}
|
||||
|
||||
- (void)ccui_setFont:(UIFont *)ccui_font
|
||||
- (void)ccui_setFont:(UIFont*)ccui_font
|
||||
{
|
||||
self.font = ccui_font;
|
||||
}
|
||||
|
@ -85,37 +86,41 @@
|
|||
self.textAlignment = ccui_alignment;
|
||||
}
|
||||
|
||||
- (UIColor *)ccui_placeholderTextColor
|
||||
- (UIColor*)ccui_placeholderTextColor
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"placeHolderLabel");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
return ((UILabel *)[self performSelector:selector]).textColor;
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
return ((UILabel*)[self performSelector:selector]).textColor;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)ccui_setPlaceholderTextColor:(UIColor *)ccui_placeholderTextColor
|
||||
- (void)ccui_setPlaceholderTextColor:(UIColor*)ccui_placeholderTextColor
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"placeHolderLabel");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
((UILabel *)[self performSelector:selector]).textColor = ccui_placeholderTextColor;
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
((UILabel*)[self performSelector:selector]).textColor = ccui_placeholderTextColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIFont *)ccui_placeholderFont
|
||||
- (UIFont*)ccui_placeholderFont
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"placeHolderLabel");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
return ((UILabel *)[self performSelector:selector]).font;
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
return ((UILabel*)[self performSelector:selector]).font;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)ccui_setPlaceholderFont:(UIFont *)ccui_placeholderFont
|
||||
- (void)ccui_setPlaceholderFont:(UIFont*)ccui_placeholderFont
|
||||
{
|
||||
SEL selector = NSSelectorFromString(@"placeHolderLabel");
|
||||
if ([self respondsToSelector:selector]) {
|
||||
((UILabel *)[self performSelector:selector]).font = ccui_placeholderFont;
|
||||
if ([self respondsToSelector:selector])
|
||||
{
|
||||
((UILabel*)[self performSelector:selector]).font = ccui_placeholderFont;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,14 +134,11 @@
|
|||
self.secureTextEntry = ccui_secureTextEntry;
|
||||
}
|
||||
|
||||
- (void)ccui_setDelegate:(id<UITextFieldDelegate,UITextViewDelegate>)delegate
|
||||
- (void)ccui_setDelegate:(id<UITextFieldDelegate, UITextViewDelegate>)delegate
|
||||
{
|
||||
self.delegate = delegate;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
void LoadUITextViewCCUITextInputCategory() {
|
||||
|
||||
}
|
||||
void LoadUITextViewCCUITextInputCategory() {}
|
||||
|
|
|
@ -236,7 +236,7 @@ Widget* RelativeLayoutManager::getRelativeWidget(Widget* widget)
|
|||
{
|
||||
Widget* relativeWidget = nullptr;
|
||||
RelativeLayoutParameter* layoutParameter = dynamic_cast<RelativeLayoutParameter*>(widget->getLayoutParameter());
|
||||
auto relativeName = layoutParameter->getRelativeToWidgetName();
|
||||
auto relativeName = layoutParameter->getRelativeToWidgetName();
|
||||
|
||||
if (!relativeName.empty())
|
||||
{
|
||||
|
|
|
@ -74,8 +74,7 @@ public:
|
|||
* @param fileName File name of texture.
|
||||
* @param resType @see TextureResType .
|
||||
*/
|
||||
void setIndexNodesTexture(std::string_view texName,
|
||||
Widget::TextureResType texType = Widget::TextureResType::LOCAL);
|
||||
void setIndexNodesTexture(std::string_view texName, Widget::TextureResType texType = Widget::TextureResType::LOCAL);
|
||||
|
||||
protected:
|
||||
bool init() override;
|
||||
|
|
|
@ -915,8 +915,8 @@ void MyXMLVisitor::setTagDescription(std::string_view tag,
|
|||
MyXMLVisitor::_tagTables, tag,
|
||||
TagBehavior{
|
||||
isFontElement,
|
||||
std::move(
|
||||
handleVisitEnter)}); // MyXMLVisitor::_tagTables[tag] = {isFontElement, std::move(handleVisitEnter)};
|
||||
std::move(
|
||||
handleVisitEnter)}); // MyXMLVisitor::_tagTables[tag] = {isFontElement, std::move(handleVisitEnter)};
|
||||
}
|
||||
|
||||
void MyXMLVisitor::removeTagDescription(std::string_view tag)
|
||||
|
@ -2080,7 +2080,7 @@ float RichText::stripTrailingWhitespace(const Vector<cocos2d::Node*>& row)
|
|||
{
|
||||
if (auto label = dynamic_cast<Label*>(row.back()))
|
||||
{
|
||||
const auto width = label->getContentSize().width;
|
||||
const auto width = label->getContentSize().width;
|
||||
std::string trimmedString{label->getString()};
|
||||
rtrim(trimmedString);
|
||||
if (label->getString() != trimmedString)
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
std::string_view fontName,
|
||||
float fontSize,
|
||||
uint32_t flags = 0,
|
||||
std::string_view url = "",
|
||||
std::string_view url = "",
|
||||
const Color3B& outlineColor = Color3B::WHITE,
|
||||
int outlineSize = -1,
|
||||
const Color3B& shadowColor = Color3B::BLACK,
|
||||
|
@ -245,7 +245,7 @@ public:
|
|||
const Color3B& color,
|
||||
uint8_t opacity,
|
||||
std::string_view filePath,
|
||||
std::string_view url = "",
|
||||
std::string_view url = "",
|
||||
Widget::TextureResType texType = Widget::TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
|
@ -263,7 +263,7 @@ public:
|
|||
const Color3B& color,
|
||||
uint8_t opacity,
|
||||
std::string_view filePath,
|
||||
std::string_view url = "",
|
||||
std::string_view url = "",
|
||||
Widget::TextureResType texType = Widget::TextureResType::LOCAL);
|
||||
|
||||
void setWidth(int width);
|
||||
|
@ -517,24 +517,24 @@ public:
|
|||
HorizontalAlignment a); /*!< sets the horizontal alignment mode: LEFT, CENTER, or RIGHT */
|
||||
HorizontalAlignment getHorizontalAlignment() const; /*!< returns the current horizontal alignment mode */
|
||||
void setFontColor(
|
||||
std::string_view color); /*!< Set the font color. @param color the #RRGGBB hexadecimal notation. */
|
||||
std::string getFontColor(); /*!< return the current font color */
|
||||
Color3B getFontColor3B(); /*!< return the current font color */
|
||||
void setFontSize(float size); /*!< Set the font size. @param size the font size. */
|
||||
float getFontSize(); /*!< return the current font size */
|
||||
void setFontFace(std::string_view face); /*!< Set the font face. @param face the font face. */
|
||||
std::string getFontFace(); /*!< return the current font face */
|
||||
std::string_view color); /*!< Set the font color. @param color the #RRGGBB hexadecimal notation. */
|
||||
std::string getFontColor(); /*!< return the current font color */
|
||||
Color3B getFontColor3B(); /*!< return the current font color */
|
||||
void setFontSize(float size); /*!< Set the font size. @param size the font size. */
|
||||
float getFontSize(); /*!< return the current font size */
|
||||
void setFontFace(std::string_view face); /*!< Set the font face. @param face the font face. */
|
||||
std::string getFontFace(); /*!< return the current font face */
|
||||
void setAnchorFontColor(std::string_view color); /*!< Set the font color of a-tag. @param face the font color. */
|
||||
std::string getAnchorFontColor(); /*!< return the current font color of a-tag */
|
||||
cocos2d::Color3B getAnchorFontColor3B(); /*!< return the current font color of a-tag */
|
||||
void setAnchorTextBold(bool enable); /*!< enable bold text of a-tag */
|
||||
bool isAnchorTextBoldEnabled(); /*!< valid style is bold text of a-tag? */
|
||||
void setAnchorTextItalic(bool enable); /*!< enable italic text of a-tag */
|
||||
bool isAnchorTextItalicEnabled(); /*!< valid style is italic text of a-tag? */
|
||||
void setAnchorTextDel(bool enable); /*!< enable the strikethrough of a-tag */
|
||||
bool isAnchorTextDelEnabled(); /*!< valid strikethrough of a-tag? */
|
||||
void setAnchorTextUnderline(bool enable); /*!< enable the underline of a-tag */
|
||||
bool isAnchorTextUnderlineEnabled(); /*!< valid underline of a-tag? */
|
||||
std::string getAnchorFontColor(); /*!< return the current font color of a-tag */
|
||||
cocos2d::Color3B getAnchorFontColor3B(); /*!< return the current font color of a-tag */
|
||||
void setAnchorTextBold(bool enable); /*!< enable bold text of a-tag */
|
||||
bool isAnchorTextBoldEnabled(); /*!< valid style is bold text of a-tag? */
|
||||
void setAnchorTextItalic(bool enable); /*!< enable italic text of a-tag */
|
||||
bool isAnchorTextItalicEnabled(); /*!< valid style is italic text of a-tag? */
|
||||
void setAnchorTextDel(bool enable); /*!< enable the strikethrough of a-tag */
|
||||
bool isAnchorTextDelEnabled(); /*!< valid strikethrough of a-tag? */
|
||||
void setAnchorTextUnderline(bool enable); /*!< enable the underline of a-tag */
|
||||
bool isAnchorTextUnderlineEnabled(); /*!< valid underline of a-tag? */
|
||||
/** @brief enable the outline of a-tag */
|
||||
void setAnchorTextOutline(bool enable, const Color3B& outlineColor = Color3B::WHITE, int outlineSize = -1);
|
||||
bool isAnchorTextOutlineEnabled(); /*!< valid outline of a-tag? */
|
||||
|
@ -555,7 +555,7 @@ public:
|
|||
void setDefaults(const ValueMap& defaults); /*!< set the default values */
|
||||
ValueMap getDefaults() const; /*!< returns the default values */
|
||||
|
||||
cocos2d::Color3B color3BWithString(std::string_view color); /*!< convert a color string into a Color3B. */
|
||||
cocos2d::Color3B color3BWithString(std::string_view color); /*!< convert a color string into a Color3B. */
|
||||
std::string stringWithColor3B(const cocos2d::Color3B& color3b); /*!< convert a Color3B into a color string. */
|
||||
std::string stringWithColor4B(const cocos2d::Color4B& color4b); /*!< convert a Color4B into a color string. */
|
||||
|
||||
|
@ -599,7 +599,7 @@ protected:
|
|||
const Color3B& color,
|
||||
uint8_t opacity,
|
||||
uint32_t flags,
|
||||
std::string_view url = "",
|
||||
std::string_view url = "",
|
||||
const Color3B& outlineColor = Color3B::WHITE,
|
||||
int outlineSize = -1,
|
||||
const Color3B& shadowColor = Color3B::BLACK,
|
||||
|
|
|
@ -103,9 +103,7 @@ Slider* Slider::create()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Slider* Slider::create(std::string_view barTextureName,
|
||||
std::string_view normalBallTextureName,
|
||||
TextureResType resType)
|
||||
Slider* Slider::create(std::string_view barTextureName, std::string_view normalBallTextureName, TextureResType resType)
|
||||
{
|
||||
Slider* widget = new Slider();
|
||||
if (widget->init())
|
||||
|
|
|
@ -165,7 +165,7 @@ public:
|
|||
void loadSlidBallTextures(std::string_view normal,
|
||||
std::string_view pressed = "",
|
||||
std::string_view disabled = "",
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
TextureResType texType = TextureResType::LOCAL);
|
||||
|
||||
/**
|
||||
* Load normal state texture for slider ball.
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
using namespace cocos2d::ui;
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#include "platform/ios/CCEAGLView-ios.h"
|
||||
#import <AVKit/AVPlayerViewController.h>
|
||||
#import <CoreMedia/CMTime.h>
|
||||
#include "base/CCDirector.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
# include "platform/ios/CCEAGLView-ios.h"
|
||||
# import <AVKit/AVPlayerViewController.h>
|
||||
# import <CoreMedia/CMTime.h>
|
||||
# include "base/CCDirector.h"
|
||||
# include "platform/CCFileUtils.h"
|
||||
|
||||
@interface UIVideoViewWrapperIos : NSObject
|
||||
|
||||
|
@ -47,31 +47,29 @@ typedef NS_ENUM(NSInteger, PlayerbackState) {
|
|||
PlayerbackStateCompleted
|
||||
};
|
||||
|
||||
@property (assign, nonatomic) AVPlayerViewController * playerController;
|
||||
@property(assign, nonatomic) AVPlayerViewController* playerController;
|
||||
|
||||
- (void) setFrame:(int) left :(int) top :(int) width :(int) height;
|
||||
- (void) setURL:(int) videoSource :(std::string&) videoUrl;
|
||||
- (void) play;
|
||||
- (void) pause;
|
||||
- (void) resume;
|
||||
- (void) stop;
|
||||
- (void) seekTo:(float) sec;
|
||||
- (void) setVisible:(BOOL) visible;
|
||||
- (void) setKeepRatioEnabled:(BOOL) enabled;
|
||||
- (void) setFullScreenEnabled:(BOOL) enabled;
|
||||
- (BOOL) isFullScreenEnabled;
|
||||
- (void) showPlaybackControls:(BOOL) value;
|
||||
- (void) setRepeatEnabled:(BOOL)enabled;
|
||||
- (void) setUserInteractionEnabled:(BOOL)userInteractionEnabled;
|
||||
- (void)setFrame:(int)left:(int)top:(int)width:(int)height;
|
||||
- (void)setURL:(int)videoSource:(std::string&)videoUrl;
|
||||
- (void)play;
|
||||
- (void)pause;
|
||||
- (void)resume;
|
||||
- (void)stop;
|
||||
- (void)seekTo:(float)sec;
|
||||
- (void)setVisible:(BOOL)visible;
|
||||
- (void)setKeepRatioEnabled:(BOOL)enabled;
|
||||
- (void)setFullScreenEnabled:(BOOL)enabled;
|
||||
- (BOOL)isFullScreenEnabled;
|
||||
- (void)showPlaybackControls:(BOOL)value;
|
||||
- (void)setRepeatEnabled:(BOOL)enabled;
|
||||
- (void)setUserInteractionEnabled:(BOOL)userInteractionEnabled;
|
||||
|
||||
|
||||
-(id) init:(void*) videoPlayer;
|
||||
-(void) videoFinished:(NSNotification*) notification;
|
||||
- (id)init:(void*)videoPlayer;
|
||||
- (void)videoFinished:(NSNotification*)notification;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIVideoViewWrapperIos
|
||||
{
|
||||
@implementation UIVideoViewWrapperIos {
|
||||
int _left;
|
||||
int _top;
|
||||
int _width;
|
||||
|
@ -84,24 +82,25 @@ typedef NS_ENUM(NSInteger, PlayerbackState) {
|
|||
VideoPlayer* _videoPlayer;
|
||||
}
|
||||
|
||||
-(id)init:(void*)videoPlayer
|
||||
- (id)init:(void*)videoPlayer
|
||||
{
|
||||
if (self = [super init]) {
|
||||
if (self = [super init])
|
||||
{
|
||||
self.playerController = [AVPlayerViewController new];
|
||||
|
||||
[self setRepeatEnabled:FALSE];
|
||||
[self showPlaybackControls:TRUE];
|
||||
[self setUserInteractionEnabled:TRUE];
|
||||
[self setKeepRatioEnabled:FALSE];
|
||||
|
||||
|
||||
_videoPlayer = (VideoPlayer*)videoPlayer;
|
||||
_state = PlayerbackStateUnknown;
|
||||
_state = PlayerbackStateUnknown;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
- (void)dealloc
|
||||
{
|
||||
_videoPlayer = nullptr;
|
||||
[self clean];
|
||||
|
@ -109,44 +108,44 @@ typedef NS_ENUM(NSInteger, PlayerbackState) {
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void) clean
|
||||
- (void)clean
|
||||
{
|
||||
[self stop];
|
||||
[self removePlayerEventListener];
|
||||
[self.playerController.view removeFromSuperview];
|
||||
}
|
||||
|
||||
-(void) setFrame:(int)left :(int)top :(int)width :(int)height
|
||||
- (void)setFrame:(int)left:(int)top:(int)width:(int)height
|
||||
{
|
||||
_left = left;
|
||||
_width = width;
|
||||
_top = top;
|
||||
_left = left;
|
||||
_width = width;
|
||||
_top = top;
|
||||
_height = height;
|
||||
[self.playerController.view setFrame:CGRectMake(left, top, width, height)];
|
||||
}
|
||||
|
||||
-(void) setFullScreenEnabled:(BOOL) enabled
|
||||
- (void)setFullScreenEnabled:(BOOL)enabled
|
||||
{
|
||||
// AVPlayerViewController doesn't provide API to enable fullscreen. But you can toggle
|
||||
// fullsreen by the playback controllers.
|
||||
}
|
||||
|
||||
-(BOOL) isFullScreenEnabled
|
||||
- (BOOL)isFullScreenEnabled
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
-(void) showPlaybackControls:(BOOL)value
|
||||
- (void)showPlaybackControls:(BOOL)value
|
||||
{
|
||||
_showPlaybackControls = value;
|
||||
_showPlaybackControls = value;
|
||||
self.playerController.showsPlaybackControls = value;
|
||||
}
|
||||
|
||||
-(void) setRepeatEnabled:(BOOL)enabled
|
||||
- (void)setRepeatEnabled:(BOOL)enabled
|
||||
{
|
||||
_repeatEnabled = enabled;
|
||||
if (self.playerController.player) {
|
||||
if (self.playerController.player)
|
||||
{
|
||||
if (_repeatEnabled)
|
||||
self.playerController.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
|
||||
else
|
||||
|
@ -154,57 +153,61 @@ typedef NS_ENUM(NSInteger, PlayerbackState) {
|
|||
}
|
||||
}
|
||||
|
||||
-(void) setUserInteractionEnabled:(BOOL)userInteractionEnabled
|
||||
- (void)setUserInteractionEnabled:(BOOL)userInteractionEnabled
|
||||
{
|
||||
_userInteractionEnabled = userInteractionEnabled;
|
||||
_userInteractionEnabled = userInteractionEnabled;
|
||||
self.playerController.view.userInteractionEnabled = _userInteractionEnabled;
|
||||
}
|
||||
|
||||
-(void) setURL:(int)videoSource :(std::string &)videoUrl
|
||||
- (void)setURL:(int)videoSource:(std::string&)videoUrl
|
||||
{
|
||||
[self clean];
|
||||
|
||||
if (videoSource == 1)
|
||||
self.playerController.player = [[[AVPlayer alloc] initWithURL:[NSURL URLWithString:@(videoUrl.c_str())]] autorelease];
|
||||
self.playerController.player =
|
||||
[[[AVPlayer alloc] initWithURL:[NSURL URLWithString:@(videoUrl.c_str())]] autorelease];
|
||||
else
|
||||
self.playerController.player = [[[AVPlayer alloc] initWithURL:[NSURL fileURLWithPath:@(videoUrl.c_str())]] autorelease];
|
||||
self.playerController.player =
|
||||
[[[AVPlayer alloc] initWithURL:[NSURL fileURLWithPath:@(videoUrl.c_str())]] autorelease];
|
||||
|
||||
[self setRepeatEnabled:_repeatEnabled];
|
||||
[self setKeepRatioEnabled:_keepRatioEnabled];
|
||||
[self setUserInteractionEnabled:_userInteractionEnabled];
|
||||
[self showPlaybackControls:_showPlaybackControls];
|
||||
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
auto eaglview = (CCEAGLView *) view->getEAGLView();
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
auto eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
[eaglview addSubview:self.playerController.view];
|
||||
[self registerPlayerEventListener];
|
||||
}
|
||||
|
||||
-(void) videoFinished:(NSNotification *)notification
|
||||
- (void)videoFinished:(NSNotification*)notification
|
||||
{
|
||||
if(_videoPlayer != nullptr) {
|
||||
if (_videoPlayer != nullptr)
|
||||
{
|
||||
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::COMPLETED);
|
||||
_state = PlayerbackStateCompleted;
|
||||
|
||||
if (_repeatEnabled) {
|
||||
if (_repeatEnabled)
|
||||
{
|
||||
[self seekTo:0];
|
||||
[self play];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void) seekTo:(float)sec
|
||||
- (void)seekTo:(float)sec
|
||||
{
|
||||
if (self.playerController.player)
|
||||
[self.playerController.player seekToTime:CMTimeMake(sec, 1)];
|
||||
}
|
||||
|
||||
-(void) setVisible:(BOOL)visible
|
||||
- (void)setVisible:(BOOL)visible
|
||||
{
|
||||
[self.playerController.view setHidden:!visible];
|
||||
}
|
||||
|
||||
-(void) setKeepRatioEnabled:(BOOL)enabled
|
||||
- (void)setKeepRatioEnabled:(BOOL)enabled
|
||||
{
|
||||
_keepRatioEnabled = enabled;
|
||||
if (_keepRatioEnabled)
|
||||
|
@ -213,38 +216,41 @@ typedef NS_ENUM(NSInteger, PlayerbackState) {
|
|||
self.playerController.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||||
}
|
||||
|
||||
-(void) play
|
||||
- (void)play
|
||||
{
|
||||
if (self.playerController.player && _state != PlayerbackStatePlaying) {
|
||||
if (self.playerController.player && _state != PlayerbackStatePlaying)
|
||||
{
|
||||
[self.playerController.player play];
|
||||
_state = PlayerbackStatePlaying;
|
||||
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) pause
|
||||
- (void)pause
|
||||
{
|
||||
if (self.playerController.player && _state == PlayerbackStatePlaying) {
|
||||
if (self.playerController.player && _state == PlayerbackStatePlaying)
|
||||
{
|
||||
[self.playerController.player pause];
|
||||
_state = PlayerbackStatePaused;
|
||||
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::PAUSED);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) resume
|
||||
- (void)resume
|
||||
{
|
||||
if (self.playerController.player && _state == PlayerbackStatePaused)
|
||||
[self play];
|
||||
}
|
||||
|
||||
-(void) stop
|
||||
- (void)stop
|
||||
{
|
||||
// AVPlayer doesn't have stop, so just pause it, and seek time to 0.
|
||||
if (self.playerController.player && _state != PlayerbackStopped) {
|
||||
if (self.playerController.player && _state != PlayerbackStopped)
|
||||
{
|
||||
[self seekTo:0];
|
||||
[self.playerController.player pause];
|
||||
_state = PlayerbackStopped;
|
||||
|
||||
|
||||
// stop() will be invoked in dealloc, which is invoked by _videoPlayer's destructor,
|
||||
// so do't send the message when _videoPlayer is being deleted.
|
||||
if (_videoPlayer)
|
||||
|
@ -252,21 +258,21 @@ typedef NS_ENUM(NSInteger, PlayerbackState) {
|
|||
}
|
||||
}
|
||||
|
||||
-(void) registerPlayerEventListener
|
||||
- (void)registerPlayerEventListener
|
||||
{
|
||||
if (self.playerController.player)
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(videoFinished:)
|
||||
name:AVPlayerItemDidPlayToEndTimeNotification
|
||||
object:self.playerController.player.currentItem];
|
||||
name:AVPlayerItemDidPlayToEndTimeNotification
|
||||
object:self.playerController.player.currentItem];
|
||||
}
|
||||
|
||||
-(void) removePlayerEventListener
|
||||
- (void)removePlayerEventListener
|
||||
{
|
||||
if (self.playerController.player)
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:AVPlayerItemDidPlayToEndTimeNotification
|
||||
object:self.playerController.player.currentItem];
|
||||
name:AVPlayerItemDidPlayToEndTimeNotification
|
||||
object:self.playerController.player.currentItem];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -276,15 +282,15 @@ VideoPlayer::VideoPlayer()
|
|||
{
|
||||
_videoView = [[UIVideoViewWrapperIos alloc] init:this];
|
||||
|
||||
#if CC_VIDEOPLAYER_DEBUG_DRAW
|
||||
# if CC_VIDEOPLAYER_DEBUG_DRAW
|
||||
_debugDrawNode = DrawNode::create();
|
||||
addChild(_debugDrawNode);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
VideoPlayer::~VideoPlayer()
|
||||
{
|
||||
if(_videoView)
|
||||
if (_videoView)
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) dealloc];
|
||||
}
|
||||
|
@ -292,16 +298,16 @@ VideoPlayer::~VideoPlayer()
|
|||
|
||||
void VideoPlayer::setFileName(std::string_view fileName)
|
||||
{
|
||||
_videoURL = FileUtils::getInstance()->fullPathForFilename(fileName);
|
||||
_videoURL = FileUtils::getInstance()->fullPathForFilename(fileName);
|
||||
_videoSource = VideoPlayer::Source::FILENAME;
|
||||
[((UIVideoViewWrapperIos*)_videoView) setURL:(int)_videoSource :_videoURL];
|
||||
[((UIVideoViewWrapperIos*)_videoView) setURL:(int) _videoSource:_videoURL];
|
||||
}
|
||||
|
||||
void VideoPlayer::setURL(std::string_view videoUrl)
|
||||
{
|
||||
_videoURL = videoUrl;
|
||||
_videoURL = videoUrl;
|
||||
_videoSource = VideoPlayer::Source::URL;
|
||||
[((UIVideoViewWrapperIos*)_videoView) setURL:(int)_videoSource :_videoURL];
|
||||
[((UIVideoViewWrapperIos*)_videoView) setURL:(int) _videoSource:_videoURL];
|
||||
}
|
||||
|
||||
void VideoPlayer::setLooping(bool looping)
|
||||
|
@ -320,56 +326,52 @@ void VideoPlayer::setStyle(StyleType style)
|
|||
{
|
||||
_styleType = style;
|
||||
|
||||
switch (style) {
|
||||
case StyleType::DEFAULT:
|
||||
[((UIVideoViewWrapperIos*)_videoView) showPlaybackControls:TRUE];
|
||||
break;
|
||||
switch (style)
|
||||
{
|
||||
case StyleType::DEFAULT:
|
||||
[((UIVideoViewWrapperIos*)_videoView) showPlaybackControls:TRUE];
|
||||
break;
|
||||
|
||||
case StyleType::NONE:
|
||||
[((UIVideoViewWrapperIos*)_videoView) showPlaybackControls:FALSE];
|
||||
break;
|
||||
case StyleType::NONE:
|
||||
[((UIVideoViewWrapperIos*)_videoView) showPlaybackControls:FALSE];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VideoPlayer::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags)
|
||||
void VideoPlayer::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
|
||||
{
|
||||
cocos2d::ui::Widget::draw(renderer,transform,flags);
|
||||
cocos2d::ui::Widget::draw(renderer, transform, flags);
|
||||
|
||||
if (flags & FLAGS_TRANSFORM_DIRTY)
|
||||
{
|
||||
auto directorInstance = Director::getInstance();
|
||||
auto glView = directorInstance->getOpenGLView();
|
||||
auto frameSize = glView->getFrameSize();
|
||||
auto scaleFactor = [static_cast<CCEAGLView *>(glView->getEAGLView()) contentScaleFactor];
|
||||
auto glView = directorInstance->getOpenGLView();
|
||||
auto frameSize = glView->getFrameSize();
|
||||
auto scaleFactor = [static_cast<CCEAGLView*>(glView->getEAGLView()) contentScaleFactor];
|
||||
|
||||
auto winSize = directorInstance->getWinSize();
|
||||
|
||||
auto leftBottom = convertToWorldSpace(Vec2::ZERO);
|
||||
auto rightTop = convertToWorldSpace(Vec2(_contentSize.width,_contentSize.height));
|
||||
auto rightTop = convertToWorldSpace(Vec2(_contentSize.width, _contentSize.height));
|
||||
|
||||
auto uiLeft = (frameSize.width / 2 + (leftBottom.x - winSize.width / 2 ) * glView->getScaleX()) / scaleFactor;
|
||||
auto uiTop = (frameSize.height /2 - (rightTop.y - winSize.height / 2) * glView->getScaleY()) / scaleFactor;
|
||||
auto uiLeft = (frameSize.width / 2 + (leftBottom.x - winSize.width / 2) * glView->getScaleX()) / scaleFactor;
|
||||
auto uiTop = (frameSize.height / 2 - (rightTop.y - winSize.height / 2) * glView->getScaleY()) / scaleFactor;
|
||||
|
||||
[((UIVideoViewWrapperIos*)_videoView) setFrame :uiLeft :uiTop
|
||||
:(rightTop.x - leftBottom.x) * glView->getScaleX() / scaleFactor
|
||||
:( (rightTop.y - leftBottom.y) * glView->getScaleY()/scaleFactor)];
|
||||
[((UIVideoViewWrapperIos*)_videoView) setFrame:
|
||||
uiLeft:uiTop:(rightTop.x - leftBottom.x) * glView->getScaleX() /
|
||||
scaleFactor:((rightTop.y - leftBottom.y) * glView->getScaleY() /
|
||||
scaleFactor)];
|
||||
}
|
||||
|
||||
#if CC_VIDEOPLAYER_DEBUG_DRAW
|
||||
# if CC_VIDEOPLAYER_DEBUG_DRAW
|
||||
_debugDrawNode->clear();
|
||||
auto size = getContentSize();
|
||||
Point vertices[4]=
|
||||
{
|
||||
Point::ZERO,
|
||||
Point(size.width, 0),
|
||||
Point(size.width, size.height),
|
||||
Point(0, size.height)
|
||||
};
|
||||
auto size = getContentSize();
|
||||
Point vertices[4] = {Point::ZERO, Point(size.width, 0), Point(size.width, size.height), Point(0, size.height)};
|
||||
_debugDrawNode->drawPoly(vertices, 4, true, Color4F(1.0, 1.0, 1.0, 1.0));
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
bool VideoPlayer::isFullScreenEnabled()const
|
||||
bool VideoPlayer::isFullScreenEnabled() const
|
||||
{
|
||||
return [((UIVideoViewWrapperIos*)_videoView) isFullScreenEnabled];
|
||||
}
|
||||
|
@ -390,7 +392,7 @@ void VideoPlayer::setKeepAspectRatioEnabled(bool enable)
|
|||
|
||||
void VideoPlayer::play()
|
||||
{
|
||||
if (! _videoURL.empty())
|
||||
if (!_videoURL.empty())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) play];
|
||||
}
|
||||
|
@ -398,7 +400,7 @@ void VideoPlayer::play()
|
|||
|
||||
void VideoPlayer::pause()
|
||||
{
|
||||
if (! _videoURL.empty())
|
||||
if (!_videoURL.empty())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) pause];
|
||||
}
|
||||
|
@ -406,7 +408,7 @@ void VideoPlayer::pause()
|
|||
|
||||
void VideoPlayer::resume()
|
||||
{
|
||||
if (! _videoURL.empty())
|
||||
if (!_videoURL.empty())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) resume];
|
||||
}
|
||||
|
@ -414,7 +416,7 @@ void VideoPlayer::resume()
|
|||
|
||||
void VideoPlayer::stop()
|
||||
{
|
||||
if (! _videoURL.empty())
|
||||
if (!_videoURL.empty())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) stop];
|
||||
}
|
||||
|
@ -422,7 +424,7 @@ void VideoPlayer::stop()
|
|||
|
||||
void VideoPlayer::seekTo(float sec)
|
||||
{
|
||||
if (! _videoURL.empty())
|
||||
if (!_videoURL.empty())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) seekTo:sec];
|
||||
}
|
||||
|
@ -451,7 +453,7 @@ void VideoPlayer::setVisible(bool visible)
|
|||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) setVisible:NO];
|
||||
}
|
||||
else if(isRunning())
|
||||
else if (isRunning())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) setVisible:YES];
|
||||
}
|
||||
|
@ -462,14 +464,14 @@ void VideoPlayer::onEnter()
|
|||
Widget::onEnter();
|
||||
if (isVisible())
|
||||
{
|
||||
[((UIVideoViewWrapperIos*)_videoView) setVisible: YES];
|
||||
[((UIVideoViewWrapperIos*)_videoView) setVisible:YES];
|
||||
}
|
||||
}
|
||||
|
||||
void VideoPlayer::onExit()
|
||||
{
|
||||
Widget::onExit();
|
||||
[((UIVideoViewWrapperIos*)_videoView) setVisible: NO];
|
||||
[((UIVideoViewWrapperIos*)_videoView) setVisible:NO];
|
||||
}
|
||||
|
||||
void VideoPlayer::addEventListener(const VideoPlayer::ccVideoPlayerCallback& callback)
|
||||
|
@ -479,9 +481,12 @@ void VideoPlayer::addEventListener(const VideoPlayer::ccVideoPlayerCallback& cal
|
|||
|
||||
void VideoPlayer::onPlayEvent(int event)
|
||||
{
|
||||
if (event == (int)VideoPlayer::EventType::PLAYING) {
|
||||
if (event == (int)VideoPlayer::EventType::PLAYING)
|
||||
{
|
||||
_isPlaying = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_isPlaying = false;
|
||||
}
|
||||
|
||||
|
@ -496,23 +501,23 @@ cocos2d::ui::Widget* VideoPlayer::createCloneInstance()
|
|||
return VideoPlayer::create();
|
||||
}
|
||||
|
||||
void VideoPlayer::copySpecialProperties(Widget *widget)
|
||||
void VideoPlayer::copySpecialProperties(Widget* widget)
|
||||
{
|
||||
VideoPlayer* videoPlayer = dynamic_cast<VideoPlayer*>(widget);
|
||||
if (videoPlayer)
|
||||
{
|
||||
_isPlaying = videoPlayer->_isPlaying;
|
||||
_isLooping = videoPlayer->_isLooping;
|
||||
_isUserInputEnabled = videoPlayer->_isUserInputEnabled;
|
||||
_styleType = videoPlayer->_styleType;
|
||||
_fullScreenEnabled = videoPlayer->_fullScreenEnabled;
|
||||
_fullScreenDirty = videoPlayer->_fullScreenDirty;
|
||||
_videoURL = videoPlayer->_videoURL;
|
||||
_isPlaying = videoPlayer->_isPlaying;
|
||||
_isLooping = videoPlayer->_isLooping;
|
||||
_isUserInputEnabled = videoPlayer->_isUserInputEnabled;
|
||||
_styleType = videoPlayer->_styleType;
|
||||
_fullScreenEnabled = videoPlayer->_fullScreenEnabled;
|
||||
_fullScreenDirty = videoPlayer->_fullScreenDirty;
|
||||
_videoURL = videoPlayer->_videoURL;
|
||||
_keepAspectRatioEnabled = videoPlayer->_keepAspectRatioEnabled;
|
||||
_videoSource = videoPlayer->_videoSource;
|
||||
_videoPlayerIndex = videoPlayer->_videoPlayerIndex;
|
||||
_eventCallback = videoPlayer->_eventCallback;
|
||||
_videoView = videoPlayer->_videoView;
|
||||
_videoSource = videoPlayer->_videoSource;
|
||||
_videoPlayerIndex = videoPlayer->_videoPlayerIndex;
|
||||
_eventCallback = videoPlayer->_eventCallback;
|
||||
_videoView = videoPlayer->_videoView;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,9 +232,9 @@ protected:
|
|||
virtual void copySpecialProperties(Widget* model) override;
|
||||
|
||||
std::function<bool(WebView* sender, std::string_view url)> _onShouldStartLoading = nullptr;
|
||||
ccWebViewCallback _onDidFinishLoading = nullptr;
|
||||
ccWebViewCallback _onDidFailLoading = nullptr;
|
||||
ccWebViewCallback _onJSCallback = nullptr;
|
||||
ccWebViewCallback _onDidFinishLoading = nullptr;
|
||||
ccWebViewCallback _onDidFailLoading = nullptr;
|
||||
ccWebViewCallback _onJSCallback = nullptr;
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS :
|
||||
/**
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
|
|
@ -219,8 +219,8 @@ void WebViewImpl::loadData(const Data& data,
|
|||
std::string_view baseURL)
|
||||
{
|
||||
std::string dataString(reinterpret_cast<char*>(data.getBytes()), static_cast<unsigned int>(data.getSize()));
|
||||
JniHelper::callStaticVoidMethod(className, "setJavascriptInterfaceScheme"sv, _viewTag, dataString, MIMEType, encoding,
|
||||
baseURL);
|
||||
JniHelper::callStaticVoidMethod(className, "setJavascriptInterfaceScheme"sv, _viewTag, dataString, MIMEType,
|
||||
encoding, baseURL);
|
||||
}
|
||||
|
||||
void WebViewImpl::loadHTMLString(std::string_view string, std::string_view baseURL)
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
|
@ -35,10 +35,10 @@
|
|||
#include "platform/CCFileUtils.h"
|
||||
|
||||
@interface UIWebViewWrapper : NSObject
|
||||
@property (nonatomic) std::function<bool(std::string url)> shouldStartLoading;
|
||||
@property (nonatomic) std::function<void(std::string url)> didFinishLoading;
|
||||
@property (nonatomic) std::function<void(std::string url)> didFailLoading;
|
||||
@property (nonatomic) std::function<void(std::string url)> onJsCallback;
|
||||
@property(nonatomic) std::function<bool(std::string url)> shouldStartLoading;
|
||||
@property(nonatomic) std::function<void(std::string url)> didFinishLoading;
|
||||
@property(nonatomic) std::function<void(std::string url)> didFailLoading;
|
||||
@property(nonatomic) std::function<void(std::string url)> onJsCallback;
|
||||
|
||||
@property(nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
|
||||
@property(nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
|
||||
|
@ -57,21 +57,24 @@
|
|||
|
||||
- (void)setFrameWithX:(float)x y:(float)y width:(float)width height:(float)height;
|
||||
|
||||
- (void)setJavascriptInterfaceScheme:(const std::string &)scheme;
|
||||
- (void)setJavascriptInterfaceScheme:(const std::string&)scheme;
|
||||
|
||||
- (void)loadData:(const std::string &)data MIMEType:(const std::string &)MIMEType textEncodingName:(const std::string &)encodingName baseURL:(const std::string &)baseURL;
|
||||
- (void)loadData:(const std::string&)data
|
||||
MIMEType:(const std::string&)MIMEType
|
||||
textEncodingName:(const std::string&)encodingName
|
||||
baseURL:(const std::string&)baseURL;
|
||||
|
||||
- (void)loadHTMLString:(const std::string &)string baseURL:(const std::string &)baseURL;
|
||||
- (void)loadHTMLString:(const std::string&)string baseURL:(const std::string&)baseURL;
|
||||
|
||||
- (void)loadUrl:(const std::string &)urlString cleanCachedData:(BOOL) needCleanCachedData;
|
||||
- (void)loadUrl:(const std::string&)urlString cleanCachedData:(BOOL)needCleanCachedData;
|
||||
|
||||
- (void)loadFile:(const std::string &)filePath;
|
||||
- (void)loadFile:(const std::string&)filePath;
|
||||
|
||||
- (void)stopLoading;
|
||||
|
||||
- (void)reload;
|
||||
|
||||
- (void)evaluateJS:(const std::string &)js;
|
||||
- (void)evaluateJS:(const std::string&)js;
|
||||
|
||||
- (void)goBack;
|
||||
|
||||
|
@ -80,178 +83,236 @@
|
|||
- (void)setScalesPageToFit:(const bool)scalesPageToFit;
|
||||
@end
|
||||
|
||||
|
||||
@interface UIWebViewWrapper () <WKUIDelegate, WKNavigationDelegate>
|
||||
@property(nonatomic) WKWebView *wkWebView;
|
||||
@property(nonatomic) WKWebView* wkWebView;
|
||||
|
||||
@property(nonatomic, copy) NSString *jsScheme;
|
||||
@property(nonatomic, copy) NSString* jsScheme;
|
||||
@end
|
||||
|
||||
@implementation UIWebViewWrapper {
|
||||
|
||||
}
|
||||
|
||||
+ (instancetype) newWebViewWrapper {
|
||||
+ (instancetype)newWebViewWrapper
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.wkWebView = nil;
|
||||
if (self)
|
||||
{
|
||||
self.wkWebView = nil;
|
||||
self.shouldStartLoading = nullptr;
|
||||
self.didFinishLoading = nullptr;
|
||||
self.didFailLoading = nullptr;
|
||||
self.didFinishLoading = nullptr;
|
||||
self.didFailLoading = nullptr;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
self.wkWebView.UIDelegate = nil;
|
||||
- (void)dealloc
|
||||
{
|
||||
self.wkWebView.UIDelegate = nil;
|
||||
self.wkWebView.navigationDelegate = nil;
|
||||
[self.wkWebView removeFromSuperview];
|
||||
[self.wkWebView release];
|
||||
self.wkWebView = nil;
|
||||
self.jsScheme = nil;
|
||||
self.jsScheme = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setupWebView {
|
||||
if (!self.wkWebView) {
|
||||
self.wkWebView = [[WKWebView alloc] init];
|
||||
self.wkWebView.UIDelegate = self;
|
||||
- (void)setupWebView
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
self.wkWebView = [[WKWebView alloc] init];
|
||||
self.wkWebView.UIDelegate = self;
|
||||
self.wkWebView.navigationDelegate = self;
|
||||
}
|
||||
if (!self.wkWebView.superview) {
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
auto eaglview = (CCEAGLView *) view->getEAGLView();
|
||||
if (!self.wkWebView.superview)
|
||||
{
|
||||
auto view = cocos2d::Director::getInstance()->getOpenGLView();
|
||||
auto eaglview = (CCEAGLView*)view->getEAGLView();
|
||||
[eaglview addSubview:self.wkWebView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setVisible:(bool)visible {
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
- (void)setVisible:(bool)visible
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
self.wkWebView.hidden = !visible;
|
||||
}
|
||||
|
||||
- (void)setBounces:(bool)bounces {
|
||||
self.wkWebView.scrollView.bounces = bounces;
|
||||
- (void)setBounces:(bool)bounces
|
||||
{
|
||||
self.wkWebView.scrollView.bounces = bounces;
|
||||
}
|
||||
|
||||
- (void)setOpacityWebView:(float)opacity {
|
||||
if (!self.wkWebView) { [self setupWebView]; }
|
||||
- (void)setOpacityWebView:(float)opacity
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
self.wkWebView.alpha = opacity;
|
||||
[self.wkWebView setOpaque:YES];
|
||||
}
|
||||
|
||||
-(float) getOpacityWebView{
|
||||
- (float)getOpacityWebView
|
||||
{
|
||||
return self.wkWebView.alpha;
|
||||
}
|
||||
|
||||
-(void) setBackgroundTransparent{
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
- (void)setBackgroundTransparent
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
[self.wkWebView setOpaque:NO];
|
||||
[self.wkWebView setBackgroundColor:[UIColor clearColor]];
|
||||
}
|
||||
|
||||
- (void)setFrameWithX:(float)x y:(float)y width:(float)width height:(float)height {
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
- (void)setFrameWithX:(float)x y:(float)y width:(float)width height:(float)height
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
CGRect newFrame = CGRectMake(x, y, width, height);
|
||||
if (!CGRectEqualToRect(self.wkWebView.frame, newFrame)) {
|
||||
if (!CGRectEqualToRect(self.wkWebView.frame, newFrame))
|
||||
{
|
||||
self.wkWebView.frame = CGRectMake(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setJavascriptInterfaceScheme:(const std::string &)scheme {
|
||||
- (void)setJavascriptInterfaceScheme:(const std::string&)scheme
|
||||
{
|
||||
self.jsScheme = @(scheme.c_str());
|
||||
}
|
||||
|
||||
- (void)loadData:(const std::string &)data MIMEType:(const std::string &)MIMEType textEncodingName:(const std::string &)encodingName baseURL:(const std::string &)baseURL {
|
||||
- (void)loadData:(const std::string&)data
|
||||
MIMEType:(const std::string&)MIMEType
|
||||
textEncodingName:(const std::string&)encodingName
|
||||
baseURL:(const std::string&)baseURL
|
||||
{
|
||||
auto path = [[NSBundle mainBundle] resourcePath];
|
||||
path = [path stringByAppendingPathComponent:@(baseURL.c_str() )];
|
||||
auto url = [NSURL fileURLWithPath:path];
|
||||
path = [path stringByAppendingPathComponent:@(baseURL.c_str())];
|
||||
auto url = [NSURL fileURLWithPath:path];
|
||||
|
||||
[self.wkWebView loadData:[NSData dataWithBytes:data.c_str() length:data.length()]
|
||||
MIMEType:@(MIMEType.c_str())
|
||||
characterEncodingName:@(encodingName.c_str())
|
||||
baseURL:url];
|
||||
MIMEType:@(MIMEType.c_str())
|
||||
characterEncodingName:@(encodingName.c_str())
|
||||
baseURL:url];
|
||||
}
|
||||
|
||||
- (void)loadHTMLString:(const std::string &)string baseURL:(const std::string &)baseURL {
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
- (void)loadHTMLString:(const std::string&)string baseURL:(const std::string&)baseURL
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
auto path = [[NSBundle mainBundle] resourcePath];
|
||||
path = [path stringByAppendingPathComponent:@(baseURL.c_str() )];
|
||||
auto url = [NSURL fileURLWithPath:path];
|
||||
path = [path stringByAppendingPathComponent:@(baseURL.c_str())];
|
||||
auto url = [NSURL fileURLWithPath:path];
|
||||
[self.wkWebView loadHTMLString:@(string.c_str()) baseURL:url];
|
||||
}
|
||||
|
||||
- (void)loadUrl:(const std::string &)urlString cleanCachedData:(BOOL) needCleanCachedData {
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
NSURL *url = [NSURL URLWithString:@(urlString.c_str())];
|
||||
- (void)loadUrl:(const std::string&)urlString cleanCachedData:(BOOL)needCleanCachedData
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
NSURL* url = [NSURL URLWithString:@(urlString.c_str())];
|
||||
|
||||
NSURLRequest *request = nil;
|
||||
NSURLRequest* request = nil;
|
||||
if (needCleanCachedData)
|
||||
request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
|
||||
request = [NSURLRequest requestWithURL:url
|
||||
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
|
||||
timeoutInterval:60];
|
||||
else
|
||||
request = [NSURLRequest requestWithURL:url];
|
||||
|
||||
[self.wkWebView loadRequest:request];
|
||||
}
|
||||
|
||||
- (void)loadFile:(const std::string &)filePath {
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
NSURL *url = [NSURL fileURLWithPath:@(filePath.c_str())];
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:url];
|
||||
- (void)loadFile:(const std::string&)filePath
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
NSURL* url = [NSURL fileURLWithPath:@(filePath.c_str())];
|
||||
NSURLRequest* request = [NSURLRequest requestWithURL:url];
|
||||
[self.wkWebView loadRequest:request];
|
||||
}
|
||||
|
||||
- (void)stopLoading {
|
||||
- (void)stopLoading
|
||||
{
|
||||
[self.wkWebView stopLoading];
|
||||
}
|
||||
|
||||
- (void)reload {
|
||||
- (void)reload
|
||||
{
|
||||
[self.wkWebView reload];
|
||||
}
|
||||
|
||||
- (BOOL)canGoForward {
|
||||
- (BOOL)canGoForward
|
||||
{
|
||||
return self.wkWebView.canGoForward;
|
||||
}
|
||||
|
||||
- (BOOL)canGoBack {
|
||||
- (BOOL)canGoBack
|
||||
{
|
||||
return self.wkWebView.canGoBack;
|
||||
}
|
||||
|
||||
- (void)goBack {
|
||||
- (void)goBack
|
||||
{
|
||||
[self.wkWebView goBack];
|
||||
}
|
||||
|
||||
- (void)goForward {
|
||||
- (void)goForward
|
||||
{
|
||||
[self.wkWebView goForward];
|
||||
}
|
||||
|
||||
- (void)evaluateJS:(const std::string &)js {
|
||||
if (!self.wkWebView) {[self setupWebView];}
|
||||
- (void)evaluateJS:(const std::string&)js
|
||||
{
|
||||
if (!self.wkWebView)
|
||||
{
|
||||
[self setupWebView];
|
||||
}
|
||||
[self.wkWebView evaluateJavaScript:@(js.c_str()) completionHandler:nil];
|
||||
}
|
||||
|
||||
- (void)setScalesPageToFit:(const bool)scalesPageToFit {
|
||||
// TODO: there is not corresponding API in WK.
|
||||
// https://stackoverflow.com/questions/26295277/wkwebview-equivalent-for-uiwebviews-scalespagetofit/43048514 seems has a solution,
|
||||
// but it doesn't support setting it dynamically. If we want to set this feature dynamically, then it will be too complex.
|
||||
- (void)setScalesPageToFit:(const bool)scalesPageToFit
|
||||
{
|
||||
// TODO: there is not corresponding API in WK.
|
||||
// https://stackoverflow.com/questions/26295277/wkwebview-equivalent-for-uiwebviews-scalespagetofit/43048514 seems
|
||||
// has a solution, but it doesn't support setting it dynamically. If we want to set this feature dynamically, then
|
||||
// it will be too complex.
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - WKNavigationDelegate
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
|
||||
NSString *url = [[[navigationAction request] URL] absoluteString];
|
||||
if ([[webView.URL scheme] isEqualToString:self.jsScheme]) {
|
||||
- (void)webView:(WKWebView*)webView
|
||||
decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction
|
||||
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
||||
{
|
||||
NSString* url = [[[navigationAction request] URL] absoluteString];
|
||||
if ([[webView.URL scheme] isEqualToString:self.jsScheme])
|
||||
{
|
||||
self.onJsCallback([url UTF8String]);
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
return;
|
||||
}
|
||||
if (self.shouldStartLoading && url) {
|
||||
if (self.shouldStartLoading([url UTF8String]) )
|
||||
if (self.shouldStartLoading && url)
|
||||
{
|
||||
if (self.shouldStartLoading([url UTF8String]))
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
else
|
||||
decisionHandler(WKNavigationActionPolicyCancel);
|
||||
|
@ -262,17 +323,22 @@
|
|||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
|
||||
if (self.didFinishLoading) {
|
||||
NSString *url = [webView.URL absoluteString];
|
||||
- (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation
|
||||
{
|
||||
if (self.didFinishLoading)
|
||||
{
|
||||
NSString* url = [webView.URL absoluteString];
|
||||
self.didFinishLoading([url UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
|
||||
if (self.didFailLoading) {
|
||||
NSString *errorInfo = error.userInfo[NSURLErrorFailingURLStringErrorKey];
|
||||
if (errorInfo) {
|
||||
- (void)webView:(WKWebView*)webView didFailProvisionalNavigation:(WKNavigation*)navigation withError:(NSError*)error
|
||||
{
|
||||
if (self.didFailLoading)
|
||||
{
|
||||
NSString* errorInfo = error.userInfo[NSURLErrorFailingURLStringErrorKey];
|
||||
if (errorInfo)
|
||||
{
|
||||
self.didFailLoading([errorInfo UTF8String]);
|
||||
}
|
||||
}
|
||||
|
@ -281,168 +347,196 @@
|
|||
#pragma WKUIDelegate
|
||||
|
||||
// Implement js alert function.
|
||||
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
|
||||
- (void)webView:(WKWebView*)webView
|
||||
runJavaScriptAlertPanelWithMessage:(NSString*)message
|
||||
initiatedByFrame:(WKFrameInfo*)frame
|
||||
completionHandler:(void (^)())completionHandler
|
||||
{
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
|
||||
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:message
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"Ok"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
completionHandler();
|
||||
handler:^(UIAlertAction* action) {
|
||||
completionHandler();
|
||||
}]];
|
||||
|
||||
auto rootViewController = [UIApplication sharedApplication].windows[0].rootViewController;
|
||||
[rootViewController presentViewController:alertController animated:YES completion:^{}];
|
||||
[rootViewController presentViewController:alertController
|
||||
animated:YES
|
||||
completion:^{
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
namespace ui
|
||||
{
|
||||
|
||||
WebViewImpl::WebViewImpl(WebView* webView) : _uiWebViewWrapper([UIWebViewWrapper newWebViewWrapper]), _webView(webView)
|
||||
{
|
||||
|
||||
namespace cocos2d {
|
||||
namespace ui{
|
||||
|
||||
WebViewImpl::WebViewImpl(WebView *webView)
|
||||
: _uiWebViewWrapper([UIWebViewWrapper newWebViewWrapper]),
|
||||
_webView(webView) {
|
||||
|
||||
_uiWebViewWrapper.shouldStartLoading = [this](std::string url) {
|
||||
if (this->_webView->_onShouldStartLoading) {
|
||||
if (this->_webView->_onShouldStartLoading)
|
||||
{
|
||||
return this->_webView->_onShouldStartLoading(this->_webView, url);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
_uiWebViewWrapper.didFinishLoading = [this](std::string url) {
|
||||
if (this->_webView->_onDidFinishLoading) {
|
||||
if (this->_webView->_onDidFinishLoading)
|
||||
{
|
||||
this->_webView->_onDidFinishLoading(this->_webView, url);
|
||||
}
|
||||
};
|
||||
_uiWebViewWrapper.didFailLoading = [this](std::string url) {
|
||||
if (this->_webView->_onDidFailLoading) {
|
||||
if (this->_webView->_onDidFailLoading)
|
||||
{
|
||||
this->_webView->_onDidFailLoading(this->_webView, url);
|
||||
}
|
||||
};
|
||||
_uiWebViewWrapper.onJsCallback = [this](std::string url) {
|
||||
if (this->_webView->_onJSCallback) {
|
||||
if (this->_webView->_onJSCallback)
|
||||
{
|
||||
this->_webView->_onJSCallback(this->_webView, url);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
WebViewImpl::~WebViewImpl(){
|
||||
WebViewImpl::~WebViewImpl()
|
||||
{
|
||||
[_uiWebViewWrapper release];
|
||||
_uiWebViewWrapper = nullptr;
|
||||
}
|
||||
|
||||
void WebViewImpl::setJavascriptInterfaceScheme(const std::string &scheme) {
|
||||
void WebViewImpl::setJavascriptInterfaceScheme(const std::string& scheme)
|
||||
{
|
||||
[_uiWebViewWrapper setJavascriptInterfaceScheme:scheme];
|
||||
}
|
||||
|
||||
void WebViewImpl::loadData(const Data &data,
|
||||
const std::string &MIMEType,
|
||||
const std::string &encoding,
|
||||
const std::string &baseURL) {
|
||||
|
||||
std::string dataString(reinterpret_cast<char *>(data.getBytes()), static_cast<unsigned int>(data.getSize()));
|
||||
void WebViewImpl::loadData(const Data& data,
|
||||
const std::string& MIMEType,
|
||||
const std::string& encoding,
|
||||
const std::string& baseURL)
|
||||
{
|
||||
|
||||
std::string dataString(reinterpret_cast<char*>(data.getBytes()), static_cast<unsigned int>(data.getSize()));
|
||||
[_uiWebViewWrapper loadData:dataString MIMEType:MIMEType textEncodingName:encoding baseURL:baseURL];
|
||||
}
|
||||
|
||||
void WebViewImpl::loadHTMLString(const std::string &string, const std::string &baseURL) {
|
||||
void WebViewImpl::loadHTMLString(const std::string& string, const std::string& baseURL)
|
||||
{
|
||||
[_uiWebViewWrapper loadHTMLString:string baseURL:baseURL];
|
||||
}
|
||||
|
||||
void WebViewImpl::loadURL(const std::string &url) {
|
||||
void WebViewImpl::loadURL(const std::string& url)
|
||||
{
|
||||
this->loadURL(url, false);
|
||||
}
|
||||
|
||||
void WebViewImpl::loadURL(const std::string &url, bool cleanCachedData) {
|
||||
void WebViewImpl::loadURL(const std::string& url, bool cleanCachedData)
|
||||
{
|
||||
[_uiWebViewWrapper loadUrl:url cleanCachedData:cleanCachedData];
|
||||
}
|
||||
|
||||
void WebViewImpl::loadFile(const std::string &fileName) {
|
||||
void WebViewImpl::loadFile(const std::string& fileName)
|
||||
{
|
||||
auto fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fileName);
|
||||
[_uiWebViewWrapper loadFile:fullPath];
|
||||
}
|
||||
|
||||
void WebViewImpl::stopLoading() {
|
||||
void WebViewImpl::stopLoading()
|
||||
{
|
||||
[_uiWebViewWrapper stopLoading];
|
||||
}
|
||||
|
||||
void WebViewImpl::reload() {
|
||||
void WebViewImpl::reload()
|
||||
{
|
||||
[_uiWebViewWrapper reload];
|
||||
}
|
||||
|
||||
bool WebViewImpl::canGoBack() {
|
||||
bool WebViewImpl::canGoBack()
|
||||
{
|
||||
return _uiWebViewWrapper.canGoBack;
|
||||
}
|
||||
|
||||
bool WebViewImpl::canGoForward() {
|
||||
bool WebViewImpl::canGoForward()
|
||||
{
|
||||
return _uiWebViewWrapper.canGoForward;
|
||||
}
|
||||
|
||||
void WebViewImpl::goBack() {
|
||||
void WebViewImpl::goBack()
|
||||
{
|
||||
[_uiWebViewWrapper goBack];
|
||||
}
|
||||
|
||||
void WebViewImpl::goForward() {
|
||||
void WebViewImpl::goForward()
|
||||
{
|
||||
[_uiWebViewWrapper goForward];
|
||||
}
|
||||
|
||||
void WebViewImpl::evaluateJS(const std::string &js) {
|
||||
void WebViewImpl::evaluateJS(const std::string& js)
|
||||
{
|
||||
[_uiWebViewWrapper evaluateJS:js];
|
||||
}
|
||||
|
||||
void WebViewImpl::setBounces(bool bounces) {
|
||||
void WebViewImpl::setBounces(bool bounces)
|
||||
{
|
||||
[_uiWebViewWrapper setBounces:bounces];
|
||||
}
|
||||
|
||||
void WebViewImpl::setScalesPageToFit(const bool scalesPageToFit) {
|
||||
void WebViewImpl::setScalesPageToFit(const bool scalesPageToFit)
|
||||
{
|
||||
[_uiWebViewWrapper setScalesPageToFit:scalesPageToFit];
|
||||
}
|
||||
|
||||
void WebViewImpl::draw(cocos2d::Renderer *renderer, cocos2d::Mat4 const &transform, uint32_t flags) {
|
||||
if (flags & cocos2d::Node::FLAGS_TRANSFORM_DIRTY) {
|
||||
|
||||
auto director = cocos2d::Director::getInstance();
|
||||
auto glView = director->getOpenGLView();
|
||||
void WebViewImpl::draw(cocos2d::Renderer* renderer, cocos2d::Mat4 const& transform, uint32_t flags)
|
||||
{
|
||||
if (flags & cocos2d::Node::FLAGS_TRANSFORM_DIRTY)
|
||||
{
|
||||
|
||||
auto director = cocos2d::Director::getInstance();
|
||||
auto glView = director->getOpenGLView();
|
||||
auto frameSize = glView->getFrameSize();
|
||||
|
||||
auto scaleFactor = [static_cast<CCEAGLView *>(glView->getEAGLView()) contentScaleFactor];
|
||||
|
||||
auto scaleFactor = [static_cast<CCEAGLView*>(glView->getEAGLView()) contentScaleFactor];
|
||||
|
||||
auto winSize = director->getWinSize();
|
||||
|
||||
auto leftBottom = this->_webView->convertToWorldSpace(cocos2d::Vec2::ZERO);
|
||||
auto rightTop = this->_webView->convertToWorldSpace(cocos2d::Vec2(this->_webView->getContentSize().width, this->_webView->getContentSize().height));
|
||||
auto rightTop = this->_webView->convertToWorldSpace(
|
||||
cocos2d::Vec2(this->_webView->getContentSize().width, this->_webView->getContentSize().height));
|
||||
|
||||
auto x = (frameSize.width / 2 + (leftBottom.x - winSize.width / 2) * glView->getScaleX()) / scaleFactor;
|
||||
auto y = (frameSize.height / 2 - (rightTop.y - winSize.height / 2) * glView->getScaleY()) / scaleFactor;
|
||||
auto width = (rightTop.x - leftBottom.x) * glView->getScaleX() / scaleFactor;
|
||||
auto x = (frameSize.width / 2 + (leftBottom.x - winSize.width / 2) * glView->getScaleX()) / scaleFactor;
|
||||
auto y = (frameSize.height / 2 - (rightTop.y - winSize.height / 2) * glView->getScaleY()) / scaleFactor;
|
||||
auto width = (rightTop.x - leftBottom.x) * glView->getScaleX() / scaleFactor;
|
||||
auto height = (rightTop.y - leftBottom.y) * glView->getScaleY() / scaleFactor;
|
||||
|
||||
[_uiWebViewWrapper setFrameWithX:x
|
||||
y:y
|
||||
width:width
|
||||
height:height];
|
||||
[_uiWebViewWrapper setFrameWithX:x y:y width:width height:height];
|
||||
}
|
||||
}
|
||||
|
||||
void WebViewImpl::setVisible(bool visible){
|
||||
void WebViewImpl::setVisible(bool visible)
|
||||
{
|
||||
[_uiWebViewWrapper setVisible:visible];
|
||||
}
|
||||
|
||||
void WebViewImpl::setOpacityWebView(float opacity){
|
||||
[_uiWebViewWrapper setOpacityWebView: opacity];
|
||||
|
||||
void WebViewImpl::setOpacityWebView(float opacity)
|
||||
{
|
||||
[_uiWebViewWrapper setOpacityWebView:opacity];
|
||||
}
|
||||
|
||||
float WebViewImpl::getOpacityWebView() const{
|
||||
|
||||
float WebViewImpl::getOpacityWebView() const
|
||||
{
|
||||
return [_uiWebViewWrapper getOpacityWebView];
|
||||
}
|
||||
|
||||
void WebViewImpl::setBackgroundTransparent(){
|
||||
void WebViewImpl::setBackgroundTransparent()
|
||||
{
|
||||
[_uiWebViewWrapper setBackgroundTransparent];
|
||||
}
|
||||
|
||||
|
||||
} // namespace ui
|
||||
} //namespace cocos2d
|
||||
} // namespace ui
|
||||
} // namespace cocos2d
|
||||
|
|
|
@ -69,8 +69,7 @@ void CCArmatureDisplay::dispatchDBEvent(std::string_view type, EventObject* valu
|
|||
_dispatcher->dispatchCustomEvent(type, value);
|
||||
}
|
||||
|
||||
void CCArmatureDisplay::removeDBEventListener(std::string_view type,
|
||||
const std::function<void(EventObject*)>& callback)
|
||||
void CCArmatureDisplay::removeDBEventListener(std::string_view type, const std::function<void(EventObject*)>& callback)
|
||||
{
|
||||
// TODO
|
||||
_dispatcher->removeCustomEventListeners(type);
|
||||
|
|
|
@ -91,8 +91,7 @@ public:
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
virtual void addDBEventListener(std::string_view type,
|
||||
const std::function<void(EventObject*)>& listener) override;
|
||||
virtual void addDBEventListener(std::string_view type, const std::function<void(EventObject*)>& listener) override;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
|
|
@ -104,7 +104,7 @@ protected:
|
|||
public:
|
||||
virtual DragonBonesData* loadDragonBonesData(std::string_view filePath,
|
||||
std::string_view name = "",
|
||||
float scale = 1.0f);
|
||||
float scale = 1.0f);
|
||||
/**
|
||||
* - Load and parse a texture atlas data and texture from the local and cache them to the factory.
|
||||
* @param filePath - The file path of texture atlas data.
|
||||
|
@ -134,7 +134,7 @@ public:
|
|||
*/
|
||||
virtual TextureAtlasData* loadTextureAtlasData(std::string_view filePath,
|
||||
std::string_view name = "",
|
||||
float scale = 1.0f);
|
||||
float scale = 1.0f);
|
||||
/**
|
||||
* - Create a armature from cached DragonBonesData instances and TextureAtlasData instances, then use the {@link
|
||||
* #clock} to update it. The difference is that the armature created by {@link #buildArmature} is not WorldClock
|
||||
|
|
|
@ -215,7 +215,7 @@ public:
|
|||
float fadeInTime = -1.f,
|
||||
int playTimes = -1,
|
||||
int layer = 0,
|
||||
std::string_view group = "",
|
||||
std::string_view group = "",
|
||||
AnimationFadeOutMode fadeOutMode = AnimationFadeOutMode::SameLayerAndGroup);
|
||||
/**
|
||||
* - Play a specific animation from the specific time.
|
||||
|
|
|
@ -47,7 +47,7 @@ bool BaseFactory::_fillBuildArmaturePackage(BuildArmaturePackage& dataPackage,
|
|||
std::string_view skinName,
|
||||
std::string_view textureAtlasName) const
|
||||
{
|
||||
auto mapName = dragonBonesName;
|
||||
auto mapName = dragonBonesName;
|
||||
DragonBonesData* dragonBonesData = nullptr;
|
||||
ArmatureData* armatureData = nullptr;
|
||||
|
||||
|
|
|
@ -151,9 +151,7 @@ public:
|
|||
* @version DragonBones 4.5
|
||||
* @language zh_CN
|
||||
*/
|
||||
virtual DragonBonesData* parseDragonBonesData(const char* rawData,
|
||||
std::string_view name = "",
|
||||
float scale = 1.0f);
|
||||
virtual DragonBonesData* parseDragonBonesData(const char* rawData, std::string_view name = "", float scale = 1.0f);
|
||||
/**
|
||||
* - Parse the raw texture atlas data and the texture atlas object to a TextureAtlasData instance and cache it to
|
||||
* the factory.
|
||||
|
@ -187,7 +185,7 @@ public:
|
|||
virtual TextureAtlasData* parseTextureAtlasData(const char* rawData,
|
||||
void* textureAtlas,
|
||||
std::string_view name = "",
|
||||
float scale = 1.0f);
|
||||
float scale = 1.0f);
|
||||
/**
|
||||
* - Get a specific DragonBonesData instance.
|
||||
* @param name - The DragonBonesData instance cache name.
|
||||
|
|
|
@ -260,9 +260,7 @@ public:
|
|||
/**
|
||||
* @private
|
||||
*/
|
||||
MeshDisplayData* getMesh(std::string_view skinName,
|
||||
std::string_view slotName,
|
||||
std::string_view meshName) const;
|
||||
MeshDisplayData* getMesh(std::string_view skinName, std::string_view slotName, std::string_view meshName) const;
|
||||
/**
|
||||
* - Get a specific animation data.
|
||||
* @param animationName - The animation animationName.
|
||||
|
|
|
@ -158,10 +158,7 @@ public:
|
|||
* @version DragonBones 3.0
|
||||
* @language zh_CN
|
||||
*/
|
||||
inline ArmatureData* getArmature(std::string_view armatureName) const
|
||||
{
|
||||
return mapFind(armatures, armatureName);
|
||||
}
|
||||
inline ArmatureData* getArmature(std::string_view armatureName) const { return mapFind(armatures, armatureName); }
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
|
|
@ -100,10 +100,7 @@ public:
|
|||
/**
|
||||
* @private
|
||||
*/
|
||||
inline TextureData* getTexture(std::string_view textureName) const
|
||||
{
|
||||
return mapFind(textures, textureName);
|
||||
}
|
||||
inline TextureData* getTexture(std::string_view textureName) const { return mapFind(textures, textureName); }
|
||||
|
||||
protected:
|
||||
virtual void _onClear() override;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue