[deploy] Merge pull request #36 from KiwanoEngine/dev

Add ResolutionMode && Update Layer, Tranform, ShapActor and so on...
This commit is contained in:
Haibo 2019-08-21 01:09:31 +08:00 committed by GitHub
commit 8d41576c7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1311 additions and 1031 deletions

View File

@ -23,13 +23,6 @@ environment:
flag_to_deploy: false flag_to_deploy: false
appveyor_api_token: appveyor_api_token:
secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E=
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
VS_PLATFORM_TOOLSET: v142
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
VS_PLATFORM_TOOLSET: v141
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
VS_PLATFORM_TOOLSET: v140
matrix: matrix:
fast_finish: true # set this flag to immediately finish build once one of the jobs fails fast_finish: true # set this flag to immediately finish build once one of the jobs fails
@ -48,6 +41,18 @@ only_commits:
- appveyor.yml - appveyor.yml
for: for:
-
branches:
only:
- master
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
VS_PLATFORM_TOOLSET: v142
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
VS_PLATFORM_TOOLSET: v141
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
VS_PLATFORM_TOOLSET: v140
- -
branches: branches:
except: except:

View File

@ -4,14 +4,14 @@
<ClInclude Include="..\src\kiwano-audio\kiwano-audio.h" /> <ClInclude Include="..\src\kiwano-audio\kiwano-audio.h" />
<ClInclude Include="..\src\kiwano-audio\src\audio-modules.h" /> <ClInclude Include="..\src\kiwano-audio\src\audio-modules.h" />
<ClInclude Include="..\src\kiwano-audio\src\audio.h" /> <ClInclude Include="..\src\kiwano-audio\src\audio.h" />
<ClInclude Include="..\src\kiwano-audio\src\Player.h" /> <ClInclude Include="..\src\kiwano-audio\src\SoundPlayer.h" />
<ClInclude Include="..\src\kiwano-audio\src\Sound.h" /> <ClInclude Include="..\src\kiwano-audio\src\Sound.h" />
<ClInclude Include="..\src\kiwano-audio\src\Transcoder.h" /> <ClInclude Include="..\src\kiwano-audio\src\Transcoder.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\kiwano-audio\src\audio-modules.cpp" /> <ClCompile Include="..\src\kiwano-audio\src\audio-modules.cpp" />
<ClCompile Include="..\src\kiwano-audio\src\audio.cpp" /> <ClCompile Include="..\src\kiwano-audio\src\audio.cpp" />
<ClCompile Include="..\src\kiwano-audio\src\Player.cpp" /> <ClCompile Include="..\src\kiwano-audio\src\SoundPlayer.cpp" />
<ClCompile Include="..\src\kiwano-audio\src\Sound.cpp" /> <ClCompile Include="..\src\kiwano-audio\src\Sound.cpp" />
<ClCompile Include="..\src\kiwano-audio\src\Transcoder.cpp" /> <ClCompile Include="..\src\kiwano-audio\src\Transcoder.cpp" />
</ItemGroup> </ItemGroup>

View File

@ -8,15 +8,15 @@
<ClInclude Include="..\src\kiwano-audio\src\audio-modules.h"> <ClInclude Include="..\src\kiwano-audio\src\audio-modules.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\kiwano-audio\src\Player.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\src\kiwano-audio\src\Sound.h"> <ClInclude Include="..\src\kiwano-audio\src\Sound.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\kiwano-audio\src\Transcoder.h"> <ClInclude Include="..\src\kiwano-audio\src\Transcoder.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\kiwano-audio\src\SoundPlayer.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\kiwano-audio\src\audio.cpp"> <ClCompile Include="..\src\kiwano-audio\src\audio.cpp">
@ -25,15 +25,15 @@
<ClCompile Include="..\src\kiwano-audio\src\audio-modules.cpp"> <ClCompile Include="..\src\kiwano-audio\src\audio-modules.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\kiwano-audio\src\Player.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\kiwano-audio\src\Sound.cpp"> <ClCompile Include="..\src\kiwano-audio\src\Sound.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\kiwano-audio\src\Transcoder.cpp"> <ClCompile Include="..\src\kiwano-audio\src\Transcoder.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\kiwano-audio\src\SoundPlayer.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="src"> <Filter Include="src">

View File

@ -29,7 +29,6 @@
<ClInclude Include="..\src\kiwano\2d\include-forwards.h" /> <ClInclude Include="..\src\kiwano\2d\include-forwards.h" />
<ClInclude Include="..\src\kiwano\2d\Canvas.h" /> <ClInclude Include="..\src\kiwano\2d\Canvas.h" />
<ClInclude Include="..\src\kiwano\2d\DebugActor.h" /> <ClInclude Include="..\src\kiwano\2d\DebugActor.h" />
<ClInclude Include="..\src\kiwano\2d\Font.hpp" />
<ClInclude Include="..\src\kiwano\2d\FrameSequence.h" /> <ClInclude Include="..\src\kiwano\2d\FrameSequence.h" />
<ClInclude Include="..\src\kiwano\2d\ShapeActor.h" /> <ClInclude Include="..\src\kiwano\2d\ShapeActor.h" />
<ClInclude Include="..\src\kiwano\2d\Layer.h" /> <ClInclude Include="..\src\kiwano\2d\Layer.h" />
@ -38,7 +37,7 @@
<ClInclude Include="..\src\kiwano\2d\Sprite.h" /> <ClInclude Include="..\src\kiwano\2d\Sprite.h" />
<ClInclude Include="..\src\kiwano\2d\Text.h" /> <ClInclude Include="..\src\kiwano\2d\Text.h" />
<ClInclude Include="..\src\kiwano\2d\TextStyle.hpp" /> <ClInclude Include="..\src\kiwano\2d\TextStyle.hpp" />
<ClInclude Include="..\src\kiwano\2d\Transform.hpp" /> <ClInclude Include="..\src\kiwano\2d\Transform.h" />
<ClInclude Include="..\src\kiwano\2d\Transition.h" /> <ClInclude Include="..\src\kiwano\2d\Transition.h" />
<ClInclude Include="..\src\kiwano\base\AsyncTask.h" /> <ClInclude Include="..\src\kiwano\base\AsyncTask.h" />
<ClInclude Include="..\src\kiwano\base\Component.h" /> <ClInclude Include="..\src\kiwano\base\Component.h" />
@ -112,6 +111,7 @@
<ClCompile Include="..\src\kiwano\2d\Stage.cpp" /> <ClCompile Include="..\src\kiwano\2d\Stage.cpp" />
<ClCompile Include="..\src\kiwano\2d\Sprite.cpp" /> <ClCompile Include="..\src\kiwano\2d\Sprite.cpp" />
<ClCompile Include="..\src\kiwano\2d\Text.cpp" /> <ClCompile Include="..\src\kiwano\2d\Text.cpp" />
<ClCompile Include="..\src\kiwano\2d\Transform.cpp" />
<ClCompile Include="..\src\kiwano\2d\Transition.cpp" /> <ClCompile Include="..\src\kiwano\2d\Transition.cpp" />
<ClCompile Include="..\src\kiwano\base\AsyncTask.cpp" /> <ClCompile Include="..\src\kiwano\base\AsyncTask.cpp" />
<ClCompile Include="..\src\kiwano\base\EventDispatcher.cpp" /> <ClCompile Include="..\src\kiwano\base\EventDispatcher.cpp" />

View File

@ -51,9 +51,6 @@
<ClInclude Include="..\src\kiwano\2d\Canvas.h"> <ClInclude Include="..\src\kiwano\2d\Canvas.h">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\kiwano\2d\Font.hpp">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\src\kiwano\2d\include-forwards.h"> <ClInclude Include="..\src\kiwano\2d\include-forwards.h">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </ClInclude>
@ -69,9 +66,6 @@
<ClInclude Include="..\src\kiwano\2d\TextStyle.hpp"> <ClInclude Include="..\src\kiwano\2d\TextStyle.hpp">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\kiwano\2d\Transform.hpp">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\src\kiwano\2d\Transition.h"> <ClInclude Include="..\src\kiwano\2d\Transition.h">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </ClInclude>
@ -309,6 +303,9 @@
<ClInclude Include="..\src\kiwano\core\types.h"> <ClInclude Include="..\src\kiwano\core\types.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\kiwano\2d\Transform.h">
<Filter>2d</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\kiwano\ui\Button.cpp"> <ClCompile Include="..\src\kiwano\ui\Button.cpp">
@ -482,5 +479,8 @@
<ClCompile Include="..\src\kiwano\renderer\FontCollection.cpp"> <ClCompile Include="..\src\kiwano\renderer\FontCollection.cpp">
<Filter>renderer</Filter> <Filter>renderer</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\kiwano\2d\Transform.cpp">
<Filter>2d</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -3,7 +3,13 @@ $replaceTo = "<DebugInformationFormat>None</DebugInformationFormat>"
Get-ChildItem -Path 'projects\' *.vcxproj | ForEach-Object { Get-ChildItem -Path 'projects\' *.vcxproj | ForEach-Object {
$filePath = 'projects\' + $_ $filePath = 'projects\' + $_
# Create a copy of .vcxproj file
Copy-Item -Path $filePath -Destination ($filePath + '.template') Copy-Item -Path $filePath -Destination ($filePath + '.template')
# Overlay some configurations
Get-Content ($filePath + '.template') -Encoding UTF8 | ForEach-Object { $_ -replace $replace, $replaceTo } | Out-File $filePath -Encoding UTF8 Get-Content ($filePath + '.template') -Encoding UTF8 | ForEach-Object { $_ -replace $replace, $replaceTo } | Out-File $filePath -Encoding UTF8
# Delete the copy file
Remove-Item -Path ($filePath + '.template') Remove-Item -Path ($filePath + '.template')
} }

View File

@ -25,11 +25,17 @@ Write-Host "Start to build nupkg files"
# This is the CoApp .autopkg file to create. # This is the CoApp .autopkg file to create.
$autopkgFile = "scripts\coapp\kiwano.autopkg" $autopkgFile = "scripts\coapp\kiwano.autopkg"
# Create a copy of ".autopkg" file
Copy-Item -Path $autopkgFile -Destination ($autopkgFile + '.template')
# Get the ".autopkg.template" file, replace "@appveyor_version" with the Appveyor version number, then save to the ".autopkg" file. # Get the ".autopkg.template" file, replace "@appveyor_version" with the Appveyor version number, then save to the ".autopkg" file.
Get-Content ($autopkgFile + ".template") | ForEach-Object { $_ -replace "@appveyor_version", $env:appveyor_build_version } > $autopkgFile Get-Content ($autopkgFile + ".template") -Encoding UTF8 | ForEach-Object { $_ -replace "@appveyor_version", $env:appveyor_build_version } | Out-File $autopkgFile -Encoding UTF8
# Delete the copy file
Remove-Item -Path ($autopkgFile + '.template')
# Use the CoApp tools to create NuGet native packages from the .autopkg. # Use the CoApp tools to create NuGet native packages from the .autopkg.
Write-NuGetPackage $autopkgFile Write-NuGetPackage $autopkgFile
# Push all newly created .nupkg files as Appveyor artifacts for later deployment. # Push all newly created .nupkg files as Appveyor artifacts for later deployment.
Get-ChildItem .\*.nupkg | ForEach-Object { Push-AppveyorArtifact $_.FullName -FileName $_.Name } Get-ChildItem .\*.nupkg | ForEach-Object { Push-AppveyorArtifact $_.FullName -FileName $_.Name }

View File

@ -1,4 +1,4 @@
#defines { #defines {
// Global variables may be added here. // Global variables may be added here.
// Variables on the "value" side of each definition will be processed at access time. // Variables on the "value" side of each definition will be processed at access time.
// GlobalVar1 = ""; // GlobalVar1 = "";

View File

@ -22,4 +22,4 @@
#include "src/audio.h" #include "src/audio.h"
#include "src/Sound.h" #include "src/Sound.h"
#include "src/Player.h" #include "src/SoundPlayer.h"

View File

@ -22,7 +22,6 @@
#include <kiwano/utils/FileUtil.h> #include <kiwano/utils/FileUtil.h>
#include "Sound.h" #include "Sound.h"
#include "audio.h" #include "audio.h"
#include "Transcoder.h"
namespace kiwano namespace kiwano
{ {
@ -32,12 +31,16 @@ namespace kiwano
Sound::Sound() Sound::Sound()
: opened_(false) : opened_(false)
, playing_(false) , playing_(false)
, size_(0)
, wave_data_(nullptr)
, voice_(nullptr) , voice_(nullptr)
{ {
} }
Sound::Sound(String const& file_path)
: Sound()
{
Load(file_path);
}
Sound::Sound(Resource const& res) Sound::Sound(Resource const& res)
: Sound() : Sound()
{ {
@ -51,21 +54,19 @@ namespace kiwano
bool Sound::Load(String const& file_path) bool Sound::Load(String const& file_path)
{ {
if (opened_)
{
Close();
}
#if defined(KGE_DEBUG)
if (!FileUtil::ExistsFile(file_path)) if (!FileUtil::ExistsFile(file_path))
{ {
KGE_WARNING_LOG(L"Media file '%s' not found", file_path.c_str()); KGE_WARNING_LOG(L"Media file '%s' not found", file_path.c_str());
return false; return false;
} }
#endif
if (opened_)
{
Close();
}
Transcoder transcoder; Transcoder transcoder;
HRESULT hr = transcoder.LoadMediaFile(file_path, &wave_data_, &size_); HRESULT hr = transcoder.LoadMediaFile(file_path);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -73,14 +74,11 @@ namespace kiwano
return false; return false;
} }
hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetBuffer().format);
if (FAILED(hr)) if (FAILED(hr))
{ {
if (wave_data_) Close();
{
delete[] wave_data_;
wave_data_ = nullptr;
}
KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr); KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr);
return false; return false;
} }
@ -97,7 +95,7 @@ namespace kiwano
} }
Transcoder transcoder; Transcoder transcoder;
HRESULT hr = transcoder.LoadMediaResource(res, &wave_data_, &size_); HRESULT hr = transcoder.LoadMediaResource(res);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -105,14 +103,11 @@ namespace kiwano
return false; return false;
} }
hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetBuffer().format);
if (FAILED(hr)) if (FAILED(hr))
{ {
if (wave_data_) Close();
{
delete[] wave_data_;
wave_data_ = nullptr;
}
KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr); KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr);
return false; return false;
} }
@ -140,10 +135,12 @@ namespace kiwano
// clamp loop count // clamp loop count
loop_count = (loop_count < 0) ? XAUDIO2_LOOP_INFINITE : std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1); loop_count = (loop_count < 0) ? XAUDIO2_LOOP_INFINITE : std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1);
auto wave_buffer = transcoder_.GetBuffer();
XAUDIO2_BUFFER buffer = { 0 }; XAUDIO2_BUFFER buffer = { 0 };
buffer.pAudioData = wave_data_; buffer.pAudioData = wave_buffer.data;
buffer.Flags = XAUDIO2_END_OF_STREAM; buffer.Flags = XAUDIO2_END_OF_STREAM;
buffer.AudioBytes = size_; buffer.AudioBytes = wave_buffer.size;
buffer.LoopCount = static_cast<UInt32>(loop_count); buffer.LoopCount = static_cast<UInt32>(loop_count);
HRESULT hr = voice_->SubmitSourceBuffer(&buffer); HRESULT hr = voice_->SubmitSourceBuffer(&buffer);
@ -202,11 +199,7 @@ namespace kiwano
voice_ = nullptr; voice_ = nullptr;
} }
if (wave_data_) transcoder_.ClearBuffer();
{
delete[] wave_data_;
wave_data_ = nullptr;
}
opened_ = false; opened_ = false;
playing_ = false; playing_ = false;

View File

@ -23,6 +23,7 @@
#include <kiwano/base/ObjectBase.h> #include <kiwano/base/ObjectBase.h>
#include <kiwano/base/Resource.h> #include <kiwano/base/Resource.h>
#include <xaudio2.h> #include <xaudio2.h>
#include "Transcoder.h"
namespace kiwano namespace kiwano
{ {
@ -86,11 +87,10 @@ namespace kiwano
); );
protected: protected:
bool opened_; bool opened_;
bool playing_; bool playing_;
UInt32 size_; Transcoder transcoder_;
BYTE* wave_data_; IXAudio2SourceVoice* voice_;
IXAudio2SourceVoice* voice_;
}; };
} }
} }

View File

@ -18,23 +18,23 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include "Player.h" #include "SoundPlayer.h"
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
Player::Player() SoundPlayer::SoundPlayer()
: volume_(1.f) : volume_(1.f)
{ {
} }
Player::~Player() SoundPlayer::~SoundPlayer()
{ {
ClearCache(); ClearCache();
} }
UInt32 Player::Load(String const& file_path) UInt32 SoundPlayer::Load(String const& file_path)
{ {
UInt32 hash_code = file_path.hash(); UInt32 hash_code = file_path.hash();
if (sound_cache_.end() != sound_cache_.find(hash_code)) if (sound_cache_.end() != sound_cache_.find(hash_code))
@ -54,7 +54,7 @@ namespace kiwano
return false; return false;
} }
UInt32 Player::Load(Resource const& res) UInt32 SoundPlayer::Load(Resource const& res)
{ {
UInt32 hash_code = res.GetId(); UInt32 hash_code = res.GetId();
if (sound_cache_.end() != sound_cache_.find(hash_code)) if (sound_cache_.end() != sound_cache_.find(hash_code))
@ -74,35 +74,35 @@ namespace kiwano
return false; return false;
} }
void Player::Play(UInt32 id, Int32 loop_count) void SoundPlayer::Play(UInt32 id, Int32 loop_count)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Play(loop_count); iter->second->Play(loop_count);
} }
void Player::Pause(UInt32 id) void SoundPlayer::Pause(UInt32 id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Pause(); iter->second->Pause();
} }
void Player::Resume(UInt32 id) void SoundPlayer::Resume(UInt32 id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Resume(); iter->second->Resume();
} }
void Player::Stop(UInt32 id) void SoundPlayer::Stop(UInt32 id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Stop(); iter->second->Stop();
} }
bool Player::IsPlaying(UInt32 id) bool SoundPlayer::IsPlaying(UInt32 id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
@ -110,12 +110,12 @@ namespace kiwano
return false; return false;
} }
Float32 Player::GetVolume() const Float32 SoundPlayer::GetVolume() const
{ {
return volume_; return volume_;
} }
void Player::SetVolume(Float32 volume) void SoundPlayer::SetVolume(Float32 volume)
{ {
volume_ = std::min(std::max(volume, -224.f), 224.f); volume_ = std::min(std::max(volume, -224.f), 224.f);
for (const auto& pair : sound_cache_) for (const auto& pair : sound_cache_)
@ -124,7 +124,7 @@ namespace kiwano
} }
} }
void Player::PauseAll() void SoundPlayer::PauseAll()
{ {
for (const auto& pair : sound_cache_) for (const auto& pair : sound_cache_)
{ {
@ -132,7 +132,7 @@ namespace kiwano
} }
} }
void Player::ResumeAll() void SoundPlayer::ResumeAll()
{ {
for (const auto& pair : sound_cache_) for (const auto& pair : sound_cache_)
{ {
@ -140,7 +140,7 @@ namespace kiwano
} }
} }
void Player::StopAll() void SoundPlayer::StopAll()
{ {
for (const auto& pair : sound_cache_) for (const auto& pair : sound_cache_)
{ {
@ -148,7 +148,7 @@ namespace kiwano
} }
} }
void Player::ClearCache() void SoundPlayer::ClearCache()
{ {
sound_cache_.clear(); sound_cache_.clear();
} }

View File

@ -27,23 +27,23 @@ namespace kiwano
{ {
namespace audio namespace audio
{ {
KGE_DECLARE_SMART_PTR(Player); KGE_DECLARE_SMART_PTR(SoundPlayer);
// 稜있꺄렴포 // 稜있꺄렴포
class KGE_API Player class KGE_API SoundPlayer
: protected ObjectBase : protected ObjectBase
{ {
public: public:
Player(); SoundPlayer();
~Player(); ~SoundPlayer();
// 加载本地音频文件, 返回该资源标识符 // 加载本地音频文件, 返回该资源标识符
UInt32 Load( UInt32 Load(
String const& file_path String const& file_path
); );
// 加载音乐资源, 返回该资源标识符 // 加载音乐资源, 返回该资源标识符
UInt32 Load( UInt32 Load(
Resource const& res /* 稜있栗都 */ Resource const& res /* 稜있栗都 */
); );
@ -51,7 +51,7 @@ namespace kiwano
// 꺄렴稜있 // 꺄렴稜있
void Play( void Play(
UInt32 id, /* 깃街륜 */ UInt32 id, /* 깃街륜 */
Int32 loop_count = 0 /* 播放循环次数 (-1 为循环播放) */ Int32 loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
); );
// 董界稜있 // 董界稜있

View File

@ -38,24 +38,39 @@ namespace kiwano
Transcoder::Transcoder() Transcoder::Transcoder()
: wave_format_(nullptr) : wave_format_(nullptr)
, wave_data_(nullptr)
, wave_size_(0)
{ {
} }
Transcoder::~Transcoder() Transcoder::~Transcoder()
{
ClearBuffer();
}
Transcoder::Buffer Transcoder::GetBuffer() const
{
return Buffer{ wave_data_, wave_size_, wave_format_ };
}
void Transcoder::ClearBuffer()
{ {
if (wave_format_) if (wave_format_)
{ {
::CoTaskMemFree(wave_format_); ::CoTaskMemFree(wave_format_);
wave_format_ = nullptr; wave_format_ = nullptr;
} }
if (wave_data_)
{
delete[] wave_data_;
wave_data_ = nullptr;
}
wave_size_ = 0;
} }
const WAVEFORMATEX* Transcoder::GetWaveFormatEx() const HRESULT Transcoder::LoadMediaFile(String const& file_path)
{
return wave_format_;
}
HRESULT Transcoder::LoadMediaFile(String const& file_path, BYTE** wave_data, UInt32* wave_data_size)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -69,13 +84,13 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ReadSource(reader.get(), wave_data, wave_data_size); hr = ReadSource(reader.get());
} }
return hr; return hr;
} }
HRESULT Transcoder::LoadMediaResource(Resource const& res, BYTE** wave_data, UInt32* wave_data_size) HRESULT Transcoder::LoadMediaResource(Resource const& res)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -87,7 +102,7 @@ namespace kiwano
if (!data) { return E_FAIL; } if (!data) { return E_FAIL; }
stream = kiwano::modules::Shlwapi::Get().SHCreateMemStream( stream = kiwano::modules::Shlwapi::Get().SHCreateMemStream(
static_cast<const BYTE*>(data.buffer), static_cast<const Byte*>(data.buffer),
static_cast<UInt32>(data.size) static_cast<UInt32>(data.size)
); );
@ -113,13 +128,13 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ReadSource(reader.get(), wave_data, wave_data_size); hr = ReadSource(reader.get());
} }
return hr; return hr;
} }
HRESULT Transcoder::ReadSource(IMFSourceReader* reader, BYTE** wave_data, UInt32* wave_data_size) HRESULT Transcoder::ReadSource(IMFSourceReader* reader)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
DWORD max_stream_size = 0; DWORD max_stream_size = 0;
@ -194,7 +209,7 @@ namespace kiwano
LONGLONG duration = prop.uhVal.QuadPart; LONGLONG duration = prop.uhVal.QuadPart;
max_stream_size = static_cast<DWORD>( max_stream_size = static_cast<DWORD>(
(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1 (duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1
); );
PropVariantClear(&prop); PropVariantClear(&prop);
} }
@ -203,7 +218,7 @@ namespace kiwano
{ {
DWORD flags = 0; DWORD flags = 0;
DWORD position = 0; DWORD position = 0;
BYTE* data = new (std::nothrow) BYTE[max_stream_size]; Byte* data = new (std::nothrow) Byte[max_stream_size];
ComPtr<IMFSample> sample; ComPtr<IMFSample> sample;
ComPtr<IMFMediaBuffer> buffer; ComPtr<IMFMediaBuffer> buffer;
@ -236,7 +251,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
BYTE* audio_data = nullptr; Byte* audio_data = nullptr;
DWORD sample_buffer_length = 0; DWORD sample_buffer_length = 0;
hr = buffer->Lock( hr = buffer->Lock(
@ -245,7 +260,7 @@ namespace kiwano
&sample_buffer_length &sample_buffer_length
); );
if (SUCCEEDED(hr)) if (SUCCEEDED(hr) && sample_buffer_length <= max_stream_size)
{ {
for (DWORD i = 0; i < sample_buffer_length; i++) for (DWORD i = 0; i < sample_buffer_length; i++)
{ {
@ -263,8 +278,8 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
*wave_data = data; wave_data_ = data;
*wave_data_size = position; wave_size_ = position;
} }
} }
} }

View File

@ -31,31 +31,36 @@ namespace kiwano
class KGE_API Transcoder class KGE_API Transcoder
{ {
public: public:
struct Buffer
{
Byte* data;
UInt32 size;
const WAVEFORMATEX* format;
};
Transcoder(); Transcoder();
~Transcoder(); ~Transcoder();
const WAVEFORMATEX* GetWaveFormatEx() const; Buffer GetBuffer() const;
void ClearBuffer();
HRESULT LoadMediaFile( HRESULT LoadMediaFile(
String const& file_path, String const& file_path
BYTE** wave_data,
UInt32* wave_data_size
); );
HRESULT LoadMediaResource( HRESULT LoadMediaResource(
Resource const& res, Resource const& res
BYTE** wave_data,
UInt32* wave_data_size
); );
HRESULT ReadSource( HRESULT ReadSource(
IMFSourceReader* reader, IMFSourceReader* reader
BYTE** wave_data,
UInt32* wave_data_size
); );
private: private:
Byte* wave_data_;
UInt32 wave_size_;
WAVEFORMATEX* wave_format_; WAVEFORMATEX* wave_format_;
}; };
} }

View File

@ -76,9 +76,17 @@ namespace kiwano
HRESULT Audio::CreateVoice(IXAudio2SourceVoice** voice, const WAVEFORMATEX* wfx) HRESULT Audio::CreateVoice(IXAudio2SourceVoice** voice, const WAVEFORMATEX* wfx)
{ {
KGE_ASSERT(x_audio2_ && "Audio engine hasn't been initialized!");
if (voice == nullptr) if (voice == nullptr)
{ {
return E_UNEXPECTED; return E_INVALIDARG;
}
if (*voice)
{
(*voice)->DestroyVoice();
(*voice) = nullptr;
} }
HRESULT hr = x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO); HRESULT hr = x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
@ -87,11 +95,15 @@ namespace kiwano
void Audio::Open() void Audio::Open()
{ {
KGE_ASSERT(x_audio2_ && "Audio engine hasn't been initialized!");
x_audio2_->StartEngine(); x_audio2_->StartEngine();
} }
void Audio::Close() void Audio::Close()
{ {
KGE_ASSERT(x_audio2_ && "Audio engine hasn't been initialized!");
x_audio2_->StopEngine(); x_audio2_->StopEngine();
} }
} }

View File

@ -33,9 +33,9 @@ namespace kiwano
{ {
} }
void ImGuiLayer::OnRender(Renderer* renderer) void ImGuiLayer::OnRender(RenderTarget* rt)
{ {
PrepareRender(renderer); PrepareRender(rt);
for (const auto& pipeline : pipelines_) for (const auto& pipeline : pipelines_)
{ {
pipeline.second(); pipeline.second();

View File

@ -52,7 +52,7 @@ namespace kiwano
void RemoveAllItems(); void RemoveAllItems();
public: public:
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
protected: protected:
Map<String, ImGuiPipeline> pipelines_; Map<String, ImGuiPipeline> pipelines_;

View File

@ -71,7 +71,7 @@ namespace kiwano
OnUpdate(dt); OnUpdate(dt);
} }
if (!children_.item_empty()) if (!children_.empty())
{ {
ActorPtr next; ActorPtr next;
for (auto child = children_.first_item(); child; child = next) for (auto child = children_.first_item(); child; child = next)
@ -82,16 +82,16 @@ namespace kiwano
} }
} }
void Actor::Render(Renderer* renderer) void Actor::Render(RenderTarget* rt)
{ {
if (!visible_) if (!visible_)
return; return;
UpdateTransform(); UpdateTransform();
if (children_.item_empty()) if (children_.empty())
{ {
OnRender(renderer); OnRender(rt);
} }
else else
{ {
@ -102,41 +102,40 @@ namespace kiwano
if (child->GetZOrder() >= 0) if (child->GetZOrder() >= 0)
break; break;
child->Render(renderer); child->Render(rt);
child = child->next_item().get(); child = child->next_item().get();
} }
OnRender(renderer); OnRender(rt);
while (child) while (child)
{ {
child->Render(renderer); child->Render(rt);
child = child->next_item().get(); child = child->next_item().get();
} }
} }
} }
void Actor::PrepareRender(Renderer* renderer) void Actor::PrepareRender(RenderTarget* rt)
{ {
renderer->SetTransform(transform_matrix_); rt->SetTransform(transform_matrix_);
renderer->SetOpacity(displayed_opacity_); rt->SetOpacity(displayed_opacity_);
} }
void Actor::RenderBorder() void Actor::RenderBorder(RenderTarget* rt)
{ {
if (show_border_) if (show_border_ && !size_.IsOrigin())
{ {
Rect bounds = GetBounds(); Rect bounds = GetBounds();
auto renderer = Renderer::GetInstance(); rt->SetTransform(transform_matrix_);
renderer->SetTransform(transform_matrix_); rt->FillRectangle(bounds, Color(Color::Red, .4f));
renderer->FillRectangle(bounds, Color(Color::Red, .4f)); rt->DrawRectangle(bounds, Color(Color::Red, .8f), 2.f);
renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 2.f);
} }
for (auto child = children_.first_item(); child; child = child->next_item()) for (auto child = children_.first_item(); child; child = child->next_item())
{ {
child->RenderBorder(); child->RenderBorder(rt);
} }
} }
@ -233,12 +232,7 @@ namespace kiwano
else else
{ {
// matrix multiplication is optimized by expression template // matrix multiplication is optimized by expression template
transform_matrix_ = Matrix3x2::SRT(transform_.position, transform_.scale, transform_.rotation); transform_matrix_ = transform_.ToMatrix();
if (!transform_.skew.IsOrigin())
{
transform_matrix_ = Matrix3x2::Skewing(transform_.skew) * transform_matrix_;
}
} }
transform_matrix_.Translate(Point{ -size_.x * anchor_.x, -size_.y * anchor_.y }); transform_matrix_.Translate(Point{ -size_.x * anchor_.x, -size_.y * anchor_.y });
@ -270,14 +264,14 @@ namespace kiwano
} }
} }
void Actor::SetStage(Stage* scene) void Actor::SetStage(Stage* stage)
{ {
if (scene && stage_ != scene) if (stage && stage_ != stage)
{ {
stage_ = scene; stage_ = stage;
for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) for (Actor* child = children_.first_item().get(); child; child = child->next_item().get())
{ {
child->stage_ = scene; child->stage_ = stage;
} }
} }
} }
@ -288,7 +282,7 @@ namespace kiwano
{ {
ActorPtr me = this; ActorPtr me = this;
parent_->children_.remove_item(me); parent_->children_.remove(me);
Actor* sibling = parent_->children_.last_item().get(); Actor* sibling = parent_->children_.last_item().get();
@ -309,7 +303,7 @@ namespace kiwano
} }
else else
{ {
parent_->children_.push_front_item(me); parent_->children_.push_front(me);
} }
} }
} }
@ -341,53 +335,31 @@ namespace kiwano
UpdateOpacity(); UpdateOpacity();
} }
void Actor::SetAnchorX(Float32 anchor_x) void Actor::SetAnchor(Vec2 const& anchor)
{ {
this->SetAnchor(anchor_x, anchor_.y); if (anchor_ == anchor)
}
void Actor::SetAnchorY(Float32 anchor_y)
{
this->SetAnchor(anchor_.x, anchor_y);
}
void Actor::SetAnchor(Float32 anchor_x, Float32 anchor_y)
{
if (anchor_.x == anchor_x && anchor_.y == anchor_y)
return; return;
anchor_.x = anchor_x; anchor_ = anchor;
anchor_.y = anchor_y;
dirty_transform_ = true; dirty_transform_ = true;
} }
void Actor::SetAnchor(Point const& anchor)
{
this->SetAnchor(anchor.x, anchor.y);
}
void Actor::SetWidth(Float32 width) void Actor::SetWidth(Float32 width)
{ {
this->SetSize(width, size_.y); SetSize(Size{ width, size_.y });
} }
void Actor::SetHeight(Float32 height) void Actor::SetHeight(Float32 height)
{ {
this->SetSize(size_.x, height); SetSize(Size{ size_.x, height });
} }
void Actor::SetSize(const Size& size) void Actor::SetSize(Size const& size)
{ {
this->SetSize(size.x, size.y); if (size_ == size)
}
void Actor::SetSize(Float32 width, Float32 height)
{
if (size_.x == width && size_.y == height)
return; return;
size_.x = width; size_ = size;
size_.y = height;
dirty_transform_ = true; dirty_transform_ = true;
} }
@ -412,98 +384,50 @@ namespace kiwano
} }
} }
void Actor::SetPosition(const Point & pos)
{
if (transform_.position == pos)
return;
transform_.position = pos;
dirty_transform_ = true;
}
void Actor::SetPositionX(Float32 x) void Actor::SetPositionX(Float32 x)
{ {
this->SetPosition(x, transform_.position.y); SetPosition(Point{ x, transform_.position.y });
} }
void Actor::SetPositionY(Float32 y) void Actor::SetPositionY(Float32 y)
{ {
this->SetPosition(transform_.position.x, y); SetPosition(Point{ transform_.position.x, y });
} }
void Actor::SetPosition(const Point & p) void Actor::Move(Vec2 const& v)
{ {
this->SetPosition(p.x, p.y); this->SetPosition(Point{ transform_.position.x + v.x, transform_.position.y + v.y });
} }
void Actor::SetPosition(Float32 x, Float32 y) void Actor::SetScale(Vec2 const& scale)
{ {
if (transform_.position.x == x && transform_.position.y == y) if (transform_.scale == scale)
return; return;
transform_.position.x = x; transform_.scale = scale;
transform_.position.y = y;
dirty_transform_ = true;
}
void Actor::Move(Float32 x, Float32 y)
{
this->SetPosition(transform_.position.x + x, transform_.position.y + y);
}
void Actor::Move(const Point & v)
{
this->Move(v.x, v.y);
}
void Actor::SetScaleX(Float32 scale_x)
{
this->SetScale(scale_x, transform_.scale.y);
}
void Actor::SetScaleY(Float32 scale_y)
{
this->SetScale(transform_.scale.x, scale_y);
}
void Actor::SetScale(Float32 scale)
{
this->SetScale(scale, scale);
}
void Actor::SetScale(Float32 scale_x, Float32 scale_y)
{
if (transform_.scale.x == scale_x && transform_.scale.y == scale_y)
return;
transform_.scale.x = scale_x;
transform_.scale.y = scale_y;
dirty_transform_ = true; dirty_transform_ = true;
is_fast_transform_ = false; is_fast_transform_ = false;
} }
void Actor::SetScale(Point const& scale) void Actor::SetSkew(Vec2 const& skew)
{ {
this->SetScale(scale.x, scale.y); if (transform_.skew == skew)
}
void Actor::SetSkewX(Float32 skew_x)
{
this->SetSkew(skew_x, transform_.skew.y);
}
void Actor::SetSkewY(Float32 skew_y)
{
this->SetSkew(transform_.skew.x, skew_y);
}
void Actor::SetSkew(Float32 skew_x, Float32 skew_y)
{
if (transform_.skew.x == skew_x && transform_.skew.y == skew_y)
return; return;
transform_.skew.x = skew_x; transform_.skew = skew;
transform_.skew.y = skew_y;
dirty_transform_ = true; dirty_transform_ = true;
is_fast_transform_ = false; is_fast_transform_ = false;
} }
void Actor::SetSkew(Point const& skew)
{
this->SetSkew(skew.x, skew.y);
}
void Actor::SetRotation(Float32 angle) void Actor::SetRotation(Float32 angle)
{ {
if (transform_.rotation == angle) if (transform_.rotation == angle)
@ -531,7 +455,7 @@ namespace kiwano
#endif // KGE_DEBUG #endif // KGE_DEBUG
children_.push_back_item(child); children_.push_back(child);
child->parent_ = this; child->parent_ = this;
child->SetStage(this->stage_); child->SetStage(this->stage_);
child->dirty_transform_ = true; child->dirty_transform_ = true;
@ -550,7 +474,7 @@ namespace kiwano
Rect Actor::GetBounds() const Rect Actor::GetBounds() const
{ {
return Rect(Point{}, size_); return Rect{ Point{}, size_ };
} }
Rect Actor::GetBoundingBox() const Rect Actor::GetBoundingBox() const
@ -609,20 +533,20 @@ namespace kiwano
{ {
KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception"); KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception");
if (children_.item_empty()) if (children_.empty())
return; return;
if (child) if (child)
{ {
child->parent_ = nullptr; child->parent_ = nullptr;
if (child->stage_) child->SetStage(nullptr); if (child->stage_) child->SetStage(nullptr);
children_.remove_item(ActorPtr(child)); children_.remove(ActorPtr(child));
} }
} }
void Actor::RemoveChildren(String const& child_name) void Actor::RemoveChildren(String const& child_name)
{ {
if (children_.item_empty()) if (children_.empty())
{ {
return; return;
} }
@ -643,7 +567,7 @@ namespace kiwano
void Actor::RemoveAllChildren() void Actor::RemoveAllChildren()
{ {
children_.clear_items(); children_.clear();
} }
void Actor::SetResponsible(bool enable) void Actor::SetResponsible(bool enable)

View File

@ -20,7 +20,7 @@
#pragma once #pragma once
#include "include-forwards.h" #include "include-forwards.h"
#include "Transform.hpp" #include "Transform.h"
#include "action/ActionManager.h" #include "action/ActionManager.h"
#include "../base/TimerManager.h" #include "../base/TimerManager.h"
#include "../base/EventDispatcher.h" #include "../base/EventDispatcher.h"
@ -28,7 +28,7 @@
namespace kiwano namespace kiwano
{ {
class Director; class Director;
class Renderer; class RenderTarget;
// 角色 // 角色
class KGE_API Actor class KGE_API Actor
@ -49,10 +49,10 @@ namespace kiwano
Actor(); Actor();
// 更新角色 // 更新角色
virtual void OnUpdate(Duration dt) { KGE_UNUSED(dt); } virtual void OnUpdate(Duration dt) { KGE_UNUSED(dt); }
// 渲染角色 // 渲染角色
virtual void OnRender(Renderer* renderer) { KGE_UNUSED(renderer); } virtual void OnRender(RenderTarget* rt) { KGE_UNUSED(rt); }
// 获取显示状态 // 获取显示状态
bool IsVisible() const { return visible_; } bool IsVisible() const { return visible_; }
@ -67,7 +67,7 @@ namespace kiwano
UInt32 GetHashName() const { return hash_name_; } UInt32 GetHashName() const { return hash_name_; }
// 获取 Z 轴顺序 // 获取 Z 轴顺序
Int32 GetZOrder() const { return z_order_; } Int32 GetZOrder() const { return z_order_; }
// 获取坐标 // 获取坐标
Point GetPosition() const { return transform_.position; } Point GetPosition() const { return transform_.position; }
@ -97,7 +97,7 @@ namespace kiwano
Float32 GetSkewY() const { return transform_.skew.y; } Float32 GetSkewY() const { return transform_.skew.y; }
// 获取旋转角度 // 获取旋转角度
Float32 GetRotation() const { return transform_.rotation; } Float32 GetRotation() const { return transform_.rotation; }
// 获取宽度 // 获取宽度
Float32 GetWidth() const { return size_.x; } Float32 GetWidth() const { return size_.x; }
@ -109,10 +109,10 @@ namespace kiwano
Size GetSize() const { return size_; } Size GetSize() const { return size_; }
// 获取缩放后的宽度 // 获取缩放后的宽度
Float32 GetScaledWidth() const { return size_.x * transform_.scale.x; } Float32 GetScaledWidth() const { return size_.x * transform_.scale.x; }
// 获取缩放后的高度 // 获取缩放后的高度
Float32 GetScaledHeight() const { return size_.y * transform_.scale.y; } Float32 GetScaledHeight() const { return size_.y * transform_.scale.y; }
// 获取缩放后的大小 // 获取缩放后的大小
Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; } Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; }
@ -121,16 +121,16 @@ namespace kiwano
Point GetAnchor() const { return anchor_; } Point GetAnchor() const { return anchor_; }
// 获取 x 方向锚点 // 获取 x 方向锚点
Float32 GetAnchorX() const { return anchor_.x; } Float32 GetAnchorX() const { return anchor_.x; }
// 获取 y 方向锚点 // 获取 y 方向锚点
Float32 GetAnchorY() const { return anchor_.y; } Float32 GetAnchorY() const { return anchor_.y; }
// 获取透明度 // 获取透明度
Float32 GetOpacity() const { return opacity_; } Float32 GetOpacity() const { return opacity_; }
// 获取显示透明度 // 获取显示透明度
Float32 GetDisplayedOpacity() const { return displayed_opacity_; } Float32 GetDisplayedOpacity() const { return displayed_opacity_; }
// 获取变换 // 获取变换
Transform GetTransform() const { return transform_; } Transform GetTransform() const { return transform_; }
@ -163,6 +163,20 @@ namespace kiwano
String const& name String const& name
); );
// 设置坐标
virtual void SetPosition(
Point const& point
);
// 设置坐标
inline void SetPosition(
Float32 x,
Float32 y
)
{
SetPosition(Point{ x, y });
}
// 设置横坐标 // 设置横坐标
void SetPositionX( void SetPositionX(
Float32 x Float32 x
@ -173,144 +187,101 @@ namespace kiwano
Float32 y Float32 y
); );
// 设置坐标 // 移动坐标
void SetPosition(
const Point & point
);
// 设置坐标
void SetPosition(
Float32 x,
Float32 y
);
// 移动
void Move( void Move(
Float32 x, Vec2 const& v
Float32 y
); );
// 移动 // 移动坐标
void Move( inline void Move(
const Point & vector Float32 vx,
); Float32 vy
)
{
Move(Vec2{ vx, vy });
}
// 设置横向缩放比例 // 设置缩放比例
// 默认为 1.0 // 默认为 (1.0, 1.0)
void SetScaleX( virtual void SetScale(
Float32 scale_x Vec2 const& scale
);
// 设置纵向缩放比例
// 默认为 1.0
void SetScaleY(
Float32 scale_y
); );
// 设置缩放比例 // 设置缩放比例
// 默认为 (1.0, 1.0) // 默认为 (1.0, 1.0)
void SetScale( inline void SetScale(
Float32 scale_x, Float32 scalex,
Float32 scale_y Float32 scaley
); )
{
SetScale(Vec2{ scalex, scaley });
}
// 设置缩放比例 // 设置错切角度
// 默认为 (1.0, 1.0) // 默认为 (0, 0)
void SetScale( virtual void SetSkew(
Point const& scale Vec2 const& skew
);
// 设置缩放比例
// 默认为 1.0
void SetScale(
Float32 scale
);
// 设置横向错切角度
// 默认为 0
void SetSkewX(
Float32 skew_x
);
// 设置纵向错切角度
// 默认为 0
void SetSkewY(
Float32 skew_y
); );
// 设置错切角度 // 设置错切角度
// 默认为 (0, 0) // 默认为 (0, 0)
void SetSkew( inline void SetSkew(
Float32 skew_x, Float32 skewx,
Float32 skew_y Float32 skewy
); )
{
// 设置错切角度 SetSkew(Vec2{ skewx, skewy });
// 默认为 (0, 0) }
void SetSkew(
Point const& skew
);
// 设置旋转角度 // 设置旋转角度
// 默认为 0 // 默认为 0
void SetRotation( virtual void SetRotation(
Float32 rotation Float32 rotation
); );
// 设置锚点的横向位置 // 设置锚点位置
// 默认为 0, 范围 [0, 1] // 默认为 (0, 0), 范围 [0, 1]
void SetAnchorX( virtual void SetAnchor(
Float32 anchor_x Vec2 const& anchor
);
// 设置锚点的纵向位置
// 默认为 0, 范围 [0, 1]
void SetAnchorY(
Float32 anchor_y
); );
// 设置锚点位置 // 设置锚点位置
// 默认为 (0, 0), 范围 [0, 1] // 默认为 (0, 0), 范围 [0, 1]
void SetAnchor( inline void SetAnchor(
Float32 anchor_x, Float32 anchorx,
Float32 anchor_y Float32 anchory
); )
{
// 设置锚点位置 SetAnchor(Vec2{ anchorx, anchory });
// 默认为 (0, 0), 范围 [0, 1] }
void SetAnchor(
Point const& anchor
);
// 修改宽度 // 修改宽度
void SetWidth( virtual void SetWidth(
Float32 width Float32 width
); );
// 修改高度 // 修改高度
void SetHeight( virtual void SetHeight(
Float32 height Float32 height
); );
// 修改大小 // 修改大小
void SetSize( virtual void SetSize(
Size const& size
);
// 修改大小
inline void SetSize(
Float32 width, Float32 width,
Float32 height Float32 height
); )
{
// 修改大小 SetSize(Size{ width, height });
void SetSize( }
const Size & size
);
// 设置二维仿射变换
void SetTransform(
Transform const& transform
);
// 设置透明度 // 设置透明度
// 默认为 1.0, 范围 [0, 1] // 默认为 1.0, 范围 [0, 1]
void SetOpacity( virtual void SetOpacity(
Float32 opacity Float32 opacity
); );
@ -319,6 +290,11 @@ namespace kiwano
bool enabled bool enabled
); );
// 设置二维仿射变换
void SetTransform(
Transform const& transform
);
// 设置 Z 轴顺序 // 设置 Z 轴顺序
// 默认为 0 // 默认为 0
void SetZOrder( void SetZOrder(
@ -331,11 +307,6 @@ namespace kiwano
bool enable bool enable
); );
// 判断点是否在角色内
bool ContainsPoint(
const Point& point
) const;
// 添加子角色 // 添加子角色
void AddChild( void AddChild(
ActorPtr child ActorPtr child
@ -380,8 +351,8 @@ namespace kiwano
// 从父角色移除 // 从父角色移除
void RemoveFromParent(); void RemoveFromParent();
// 事件分发 // 判断点是否在角色内
void Dispatch(Event& evt) override; virtual bool ContainsPoint(const Point& point) const;
// 暂停角色更新 // 暂停角色更新
inline void PauseUpdating() { update_pausing_ = true; } inline void PauseUpdating() { update_pausing_ = true; }
@ -401,6 +372,9 @@ namespace kiwano
// 渲染角色边界 // 渲染角色边界
inline void ShowBorder(bool show) { show_border_ = show; } inline void ShowBorder(bool show) { show_border_ = show; }
// 事件分发
void Dispatch(Event& evt) override;
// 设置默认锚点 // 设置默认锚点
static void SetDefaultAnchor( static void SetDefaultAnchor(
Float32 anchor_x, Float32 anchor_x,
@ -410,11 +384,11 @@ namespace kiwano
protected: protected:
virtual void Update(Duration dt); virtual void Update(Duration dt);
virtual void Render(Renderer* renderer); virtual void Render(RenderTarget* rt);
void PrepareRender(Renderer* renderer); virtual void PrepareRender(RenderTarget* rt);
void RenderBorder(); virtual void RenderBorder(RenderTarget* rt);
void UpdateTransform() const; void UpdateTransform() const;
@ -422,7 +396,7 @@ namespace kiwano
void Reorder(); void Reorder();
void SetStage(Stage* scene); void SetStage(Stage* stage);
protected: protected:
bool visible_; bool visible_;
@ -432,7 +406,7 @@ namespace kiwano
bool update_pausing_; bool update_pausing_;
bool cascade_opacity_; bool cascade_opacity_;
bool show_border_; bool show_border_;
Int32 z_order_; Int32 z_order_;
Float32 opacity_; Float32 opacity_;
Float32 displayed_opacity_; Float32 displayed_opacity_;
Actor* parent_; Actor* parent_;
@ -444,9 +418,9 @@ namespace kiwano
UpdateCallback cb_update_; UpdateCallback cb_update_;
Transform transform_; Transform transform_;
bool is_fast_transform_; bool is_fast_transform_;
mutable bool dirty_transform_; mutable bool dirty_transform_;
mutable bool dirty_transform_inverse_; mutable bool dirty_transform_inverse_;
mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_;
mutable Matrix3x2 transform_matrix_inverse_; mutable Matrix3x2 transform_matrix_inverse_;
}; };

View File

@ -34,17 +34,6 @@ namespace kiwano
Renderer::GetInstance()->CreateImageRenderTarget(rt_); Renderer::GetInstance()->CreateImageRenderTarget(rt_);
} }
Canvas::Canvas(Float32 width, Float32 height)
: Canvas()
{
this->SetSize(width, height);
}
Canvas::Canvas(Size const & size)
: Canvas(size.x, size.y)
{
}
Canvas::~Canvas() Canvas::~Canvas()
{ {
} }
@ -60,16 +49,16 @@ namespace kiwano
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::OnRender(Renderer* renderer) void Canvas::OnRender(RenderTarget* rt)
{ {
UpdateCache(); UpdateCache();
if (image_cached_.IsValid()) if (image_cached_.IsValid())
{ {
PrepareRender(renderer); PrepareRender(rt);
Rect bitmap_rect(0.f, 0.f, image_cached_.GetWidth(), image_cached_.GetHeight()); Rect bitmap_rect(0.f, 0.f, image_cached_.GetWidth(), image_cached_.GetHeight());
renderer->DrawImage(image_cached_, bitmap_rect, bitmap_rect); rt->DrawImage(image_cached_, bitmap_rect, bitmap_rect);
} }
} }
@ -130,13 +119,7 @@ namespace kiwano
void Canvas::SetBrushTransform(Transform const& transform) void Canvas::SetBrushTransform(Transform const& transform)
{ {
Matrix3x2 matrix = Matrix3x2::SRT(transform.position, transform.scale, transform.rotation); rt_.SetTransform(transform.ToMatrix());
if (!transform.skew.IsOrigin())
{
matrix = Matrix3x2::Skewing(transform.skew) * matrix;
}
rt_.SetTransform(matrix);
} }
void Canvas::SetBrushTransform(Matrix3x2 const & transform) void Canvas::SetBrushTransform(Matrix3x2 const & transform)
@ -144,6 +127,26 @@ namespace kiwano
rt_.SetTransform(transform); rt_.SetTransform(transform);
} }
void Canvas::PushLayerArea(LayerArea& area)
{
rt_.PushLayer(area);
}
void Canvas::PopLayerArea()
{
rt_.PopLayer();
}
void Canvas::PushClipRect(Rect const& clip_rect)
{
rt_.PushClipRect(clip_rect);
}
void Canvas::PopClipRect()
{
rt_.PopClipRect();
}
void Canvas::DrawLine(Point const& begin, Point const& end) void Canvas::DrawLine(Point const& begin, Point const& end)
{ {
rt_.DrawLine( rt_.DrawLine(
@ -333,7 +336,7 @@ namespace kiwano
{ {
if (cache_expired_) if (cache_expired_)
{ {
rt_.GetOutput(image_cached_); image_cached_ = rt_.GetOutput();
cache_expired_ = false; cache_expired_ = false;
} }
} }

View File

@ -35,15 +35,6 @@ namespace kiwano
public: public:
Canvas(); Canvas();
Canvas(
Size const& size
);
Canvas(
Float32 width,
Float32 height
);
virtual ~Canvas(); virtual ~Canvas();
// 开始绘图 // 开始绘图
@ -148,7 +139,7 @@ namespace kiwano
void AddArc( void AddArc(
Point const& point, /* 终点 */ Point const& point, /* 终点 */
Point const& radius, /* 椭圆半径 */ Point const& radius, /* 椭圆半径 */
Float32 rotation, /* ÍÖÔ²Ðýת½Ç¶È */ Float32 rotation, /* 椭圆旋转角度 */
bool clockwise = true, /* 顺时针 or 逆时针 */ bool clockwise = true, /* 顺时针 or 逆时针 */
bool is_small = true /* 是否取小于 180° 的弧 */ bool is_small = true /* 是否取小于 180° 的弧 */
); );
@ -202,6 +193,32 @@ namespace kiwano
Float32 opacity Float32 opacity
); );
// 画笔二维变换
void SetBrushTransform(
Transform const& transform
);
// 画笔二维变换
void SetBrushTransform(
Matrix3x2 const& transform
);
// 设置图层
void PushLayerArea(
LayerArea& area
);
// 弹出图层
void PopLayerArea();
// 设置裁剪区域
void PushClipRect(
Rect const& clip_rect
);
// 弹出裁剪区域
void PopClipRect();
// 获取填充颜色 // 获取填充颜色
Color GetFillColor() const; Color GetFillColor() const;
@ -214,20 +231,10 @@ namespace kiwano
// 获取画笔透明度 // 获取画笔透明度
Float32 GetBrushOpacity() const; Float32 GetBrushOpacity() const;
// »­±Ê¶þά±ä»»
void SetBrushTransform(
Transform const& transform
);
// »­±Ê¶þά±ä»»
void SetBrushTransform(
Matrix3x2 const& transform
);
// 导出为图片 // 导出为图片
Image ExportToImage() const; Image ExportToImage() const;
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
protected: protected:
void UpdateCache() const; void UpdateCache() const;

View File

@ -21,26 +21,43 @@
#include "DebugActor.h" #include "DebugActor.h"
#include "Text.h" #include "Text.h"
#include "../renderer/Renderer.h" #include "../renderer/Renderer.h"
#include <sstream>
#include <psapi.h> #include <psapi.h>
#pragma comment(lib, "psapi.lib") #pragma comment(lib, "psapi.lib")
namespace kiwano namespace kiwano
{ {
namespace
{
class comma_numpunct : public std::numpunct<wchar_t>
{
protected:
virtual wchar_t do_thousands_sep() const override
{
return L',';
}
virtual std::string do_grouping() const override
{
return "\03";
}
};
}
DebugActor::DebugActor() DebugActor::DebugActor()
: background_color_(0.0f, 0.0f, 0.0f, 0.7f) : background_color_(0.0f, 0.0f, 0.0f, 0.7f)
{ {
SetName(L"kiwano-debug-actor"); SetName(L"kiwano-debug-actor");
SetPosition(10, 10); SetPosition(Point{ 10, 10 });
SetResponsible(true); SetResponsible(true);
SetCascadeOpacityEnabled(true); SetCascadeOpacityEnabled(true);
debug_text_ = new Text; debug_text_ = new Text;
debug_text_->SetPosition(10, 10); debug_text_->SetPosition(Point{ 10, 10 });
this->AddChild(debug_text_); this->AddChild(debug_text_);
Font font; Font font;
font.family = L"Arial";
font.size = 16.f; font.size = 16.f;
font.weight = FontWeight::Normal; font.weight = FontWeight::Normal;
debug_text_->SetFont(font); debug_text_->SetFont(font);
@ -57,15 +74,11 @@ namespace kiwano
{ {
} }
void DebugActor::OnRender(Renderer* renderer) void DebugActor::OnRender(RenderTarget* rt)
{ {
PrepareRender(renderer); PrepareRender(rt);
renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); rt->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }, background_color_);
renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle(
D2D1::RoundedRect(DX::ConvertToRectF(GetBounds()), 5.f, 5.f),
renderer->GetSolidColorBrush()
);
} }
void DebugActor::OnUpdate(Duration dt) void DebugActor::OnUpdate(Duration dt)
@ -77,8 +90,15 @@ namespace kiwano
{ {
frame_time_.erase(frame_time_.begin()); frame_time_.erase(frame_time_.begin());
} }
std::wstringstream ss; StringStream ss;
{
// For formatting integers with commas
static std::locale comma_locale(std::locale(), new comma_numpunct);
(void)ss.imbue(comma_locale);
}
ss << "Fps: " << frame_time_.size() << std::endl; ss << "Fps: " << frame_time_.size() << std::endl;
#if defined(KGE_DEBUG) #if defined(KGE_DEBUG)
@ -90,11 +110,21 @@ namespace kiwano
ss << "Render: " << Renderer::GetInstance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; ss << "Render: " << Renderer::GetInstance()->GetStatus().duration.Milliseconds() << "ms" << std::endl;
ss << "Primitives / sec: " << Renderer::GetInstance()->GetStatus().primitives * frame_time_.size() << std::endl; ss << "Primitives / sec: " << std::fixed << Renderer::GetInstance()->GetStatus().primitives * frame_time_.size() << std::endl;
PROCESS_MEMORY_COUNTERS_EX pmc; ss << "Memory: ";
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); {
ss << "Memory: " << pmc.PrivateUsage / 1024 << "kb"; PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
if (pmc.PrivateUsage > 1024 * 1024)
{
ss << pmc.PrivateUsage / (1024 * 1024) << "Mb ";
pmc.PrivateUsage %= (1024 * 1024);
}
ss << pmc.PrivateUsage / 1024 << "Kb";
}
debug_text_->SetText(ss.str()); debug_text_->SetText(ss.str());
SetSize(Size{ 20 + debug_text_->GetSize().x, 20 + debug_text_->GetSize().y }); SetSize(Size{ 20 + debug_text_->GetSize().x, 20 + debug_text_->GetSize().y });

View File

@ -31,7 +31,7 @@ namespace kiwano
virtual ~DebugActor(); virtual ~DebugActor();
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;

View File

@ -69,10 +69,10 @@ namespace kiwano
if (image_.IsValid()) if (image_.IsValid())
{ {
auto bitmap_size = image_.GetSize(); auto bitmap_size = image_.GetSize();
crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.x); crop_rect_.left_top.x = std::min(std::max(crop_rect.left_top.x, 0.f), bitmap_size.x);
crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.y); crop_rect_.left_top.y = std::min(std::max(crop_rect.left_top.y, 0.f), bitmap_size.y);
crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.x - crop_rect.origin.x); crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x);
crop_rect_.size.y = std::min(std::max(crop_rect.size.y, 0.f), bitmap_size.y - crop_rect.origin.y); crop_rect_.right_bottom.y = std::min(std::max(crop_rect.right_bottom.y, 0.f), bitmap_size.y);
} }
} }
@ -81,9 +81,9 @@ namespace kiwano
image_ = image; image_ = image;
if (image_.IsValid()) if (image_.IsValid())
{ {
crop_rect_.origin.x = crop_rect_.origin.y = 0; crop_rect_.left_top.x = crop_rect_.left_top.y = 0;
crop_rect_.size.x = image_.GetWidth(); crop_rect_.right_bottom.x = image_.GetWidth();
crop_rect_.size.y = image_.GetHeight(); crop_rect_.right_bottom.y = image_.GetHeight();
} }
} }
} }

View File

@ -61,16 +61,16 @@ namespace kiwano
); );
// 获取宽度 // 获取宽度
Float32 GetWidth() const { return crop_rect_.size.x; } Float32 GetWidth() const { return crop_rect_.GetWidth(); }
// 获取高度 // 获取高度
Float32 GetHeight() const { return crop_rect_.size.y; } Float32 GetHeight() const { return crop_rect_.GetHeight(); }
// 获取大小 // 获取大小
Size GetSize() const { return crop_rect_.size; } Size GetSize() const { return crop_rect_.GetSize(); }
// 获取裁剪位置 // 获取裁剪位置
Point GetCropPoint() const { return crop_rect_.origin; } Point GetCropPoint() const { return crop_rect_.GetLeftTop(); }
// 获取裁剪矩形 // 获取裁剪矩形
inline Rect const& GetCropRect() const { return crop_rect_; } inline Rect const& GetCropRect() const { return crop_rect_; }

View File

@ -72,10 +72,7 @@ namespace kiwano
loop_count_ = 0; loop_count_ = 0;
disposal_type_ = DisposalType::None; disposal_type_ = DisposalType::None;
SetSize( SetSize(Size{ static_cast<Float32>(image_.GetWidthInPixels()), static_cast<Float32>(image_.GetHeightInPixels()) });
static_cast<Float32>(image_.GetWidthInPixels()),
static_cast<Float32>(image_.GetHeightInPixels())
);
if (!frame_rt_.IsValid()) if (!frame_rt_.IsValid())
{ {
@ -91,13 +88,13 @@ namespace kiwano
return false; return false;
} }
void GifSprite::OnRender(Renderer* renderer) void GifSprite::OnRender(RenderTarget* rt)
{ {
if (frame_.IsValid() && renderer->CheckVisibility(size_, transform_matrix_)) if (frame_.IsValid() && rt->CheckVisibility(GetBounds(), GetTransformMatrix()))
{ {
PrepareRender(renderer); PrepareRender(rt);
renderer->DrawImage(frame_); rt->DrawImage(frame_);
} }
} }
@ -195,8 +192,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
Image frame_to_render; Image frame_to_render = frame_rt_.GetOutput();
frame_rt_.GetOutput(frame_to_render);
hr = frame_to_render.IsValid() ? S_OK : E_FAIL; hr = frame_to_render.IsValid() ? S_OK : E_FAIL;
@ -222,8 +218,7 @@ namespace kiwano
void GifSprite::SaveComposedFrame() void GifSprite::SaveComposedFrame()
{ {
Image frame_to_be_saved; Image frame_to_be_saved = frame_rt_.GetOutput();
frame_rt_.GetOutput(frame_to_be_saved);
HRESULT hr = frame_to_be_saved.IsValid() ? S_OK : E_FAIL; HRESULT hr = frame_to_be_saved.IsValid() ? S_OK : E_FAIL;
@ -258,8 +253,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
Image frame_to_copy_to; Image frame_to_copy_to = frame_rt_.GetOutput();
frame_rt_.GetOutput(frame_to_copy_to);
hr = frame_to_copy_to.IsValid() ? S_OK : E_FAIL; hr = frame_to_copy_to.IsValid() ? S_OK : E_FAIL;

View File

@ -62,7 +62,7 @@ namespace kiwano
); );
// 设置 GIF 动画循环次数 // 设置 GIF 动画循环次数
inline void SetLoopCount(Int32 loops) { total_loop_count_ = loops; } inline void SetLoopCount(Int32 loops) { total_loop_count_ = loops; }
// 设置 GIF 动画每次循环结束回调函数 // 设置 GIF 动画每次循环结束回调函数
inline void SetLoopDoneCallback(LoopDoneCallback const& cb) { loop_cb_ = cb; } inline void SetLoopDoneCallback(LoopDoneCallback const& cb) { loop_cb_ = cb; }
@ -77,7 +77,7 @@ namespace kiwano
inline DoneCallback GetDoneCallback() const { return done_cb_; } inline DoneCallback GetDoneCallback() const { return done_cb_; }
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
@ -100,8 +100,8 @@ namespace kiwano
protected: protected:
bool animating_; bool animating_;
Int32 total_loop_count_; Int32 total_loop_count_;
Int32 loop_count_; Int32 loop_count_;
UInt32 next_index_; UInt32 next_index_;
Duration frame_delay_; Duration frame_delay_;
Duration frame_elapsed_; Duration frame_elapsed_;

View File

@ -27,8 +27,6 @@ namespace kiwano
Layer::Layer() Layer::Layer()
: swallow_(false) : swallow_(false)
{ {
SetSize(Renderer::GetInstance()->GetOutputSize());
auto handler = Closure(this, &Layer::HandleMessages); auto handler = Closure(this, &Layer::HandleMessages);
AddListener(Event::MouseBtnDown, handler); AddListener(Event::MouseBtnDown, handler);
@ -45,6 +43,27 @@ namespace kiwano
{ {
} }
void Layer::SetClipRect(Rect const& clip_rect)
{
area_.SetAreaRect(clip_rect);
}
void Layer::SetOpacity(Float32 opacity)
{
// Actor::SetOpacity(opacity);
area_.SetOpacity(opacity);
}
void Layer::SetMaskGeometry(Geometry const& mask)
{
area_.SetMaskGeometry(mask);
}
void Layer::SetMaskTransform(Matrix3x2 const& transform)
{
area_.SetMaskTransform(transform);
}
void Layer::Dispatch(Event& evt) void Layer::Dispatch(Event& evt)
{ {
if (!IsVisible()) if (!IsVisible())
@ -63,7 +82,19 @@ namespace kiwano
EventDispatcher::Dispatch(evt); EventDispatcher::Dispatch(evt);
} }
void Layer::HandleMessages(Event const & evt) void Layer::Render(RenderTarget* rt)
{
if (!children_.empty())
{
PrepareRender(rt);
rt->PushLayer(area_);
Actor::Render(rt);
rt->PopLayer();
}
}
void Layer::HandleMessages(Event const& evt)
{ {
switch (evt.type) switch (evt.type)
{ {

View File

@ -20,6 +20,8 @@
#pragma once #pragma once
#include "Actor.h" #include "Actor.h"
#include "..\renderer\LayerArea.h"
#include "..\renderer\RenderTarget.h"
namespace kiwano namespace kiwano
{ {
@ -31,25 +33,49 @@ namespace kiwano
virtual ~Layer(); virtual ~Layer();
// 重载下列函数以获取图层事件
virtual void OnMouseButtonDown(Int32 btn, Point const& p) {} virtual void OnMouseButtonDown(Int32 btn, Point const& p) {}
virtual void OnMouseButtonUp(Int32 btn, Point const& p) {} virtual void OnMouseButtonUp(Int32 btn, Point const& p) {}
virtual void OnMouseMoved(Point const& p) {} virtual void OnMouseMoved(Point const& p) {}
virtual void OnMouseWheel(Float32 wheel) {} virtual void OnMouseWheel(Float32 wheel) {}
virtual void OnKeyDown(Int32 key) {} virtual void OnKeyDown(Int32 key) {}
virtual void OnKeyUp(Int32 key) {} virtual void OnKeyUp(Int32 key) {}
virtual void OnChar(char c) {} virtual void OnChar(char c) {}
// 是否开启消息吞没
inline bool IsSwallowEventsEnabled() const { return swallow_; }
// ÍÌûÏûÏ¢ // ÍÌûÏûÏ¢
inline void SetSwallowEvents(bool enabled) { swallow_ = enabled; } inline void SetSwallowEvents(bool enabled) { swallow_ = enabled; }
// 设置裁剪区域
void SetClipRect(Rect const& clip_rect);
// 设置图层透明度
void SetOpacity(Float32 opacity) override;
// 设置几何蒙层
void SetMaskGeometry(Geometry const& mask);
// 设置几何蒙层的二维变换
void SetMaskTransform(Matrix3x2 const& transform);
// 设置图层区域
inline void SetArea(LayerArea const& area) { area_ = area; }
// 获取图层区域
inline LayerArea const& GetArea() const { return area_; }
public: public:
void Dispatch(Event& evt) override; void Dispatch(Event& evt) override;
protected: protected:
void Render(RenderTarget* rt) override;
void HandleMessages(Event const& evt); void HandleMessages(Event const& evt);
protected: protected:
bool swallow_; bool swallow_;
LayerArea area_;
}; };
} }

View File

@ -44,10 +44,7 @@ namespace kiwano
Rect ShapeActor::GetBounds() const Rect ShapeActor::GetBounds() const
{ {
if (!geo_) return bounds_;
return Rect{};
return geo_.GetBoundingBox(Matrix3x2());
} }
Rect ShapeActor::GetBoundingBox() const Rect ShapeActor::GetBoundingBox() const
@ -58,6 +55,11 @@ namespace kiwano
return geo_.GetBoundingBox(GetTransformMatrix()); return geo_.GetBoundingBox(GetTransformMatrix());
} }
bool ShapeActor::ContainsPoint(const Point& point) const
{
return geo_.ContainsPoint(point, GetTransformMatrix());
}
void ShapeActor::SetFillColor(const Color & color) void ShapeActor::SetFillColor(const Color & color)
{ {
fill_color_ = color; fill_color_ = color;
@ -78,18 +80,33 @@ namespace kiwano
stroke_style_ = stroke_style; stroke_style_ = stroke_style;
} }
void ShapeActor::OnRender(Renderer* renderer) void ShapeActor::SetGeometry(Geometry geometry)
{ {
geo_ = geometry;
if (geo_) if (geo_)
{ {
PrepareRender(renderer); bounds_ = geo_.GetBoundingBox(Matrix3x2());
SetSize(bounds_.GetSize());
}
else
{
bounds_ = Rect{};
SetSize(0.f, 0.f);
}
}
renderer->FillGeometry( void ShapeActor::OnRender(RenderTarget* rt)
{
if (geo_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix()))
{
PrepareRender(rt);
rt->FillGeometry(
geo_, geo_,
fill_color_ fill_color_
); );
renderer->DrawGeometry( rt->DrawGeometry(
geo_, geo_,
stroke_color_, stroke_color_,
stroke_width_, stroke_width_,
@ -106,22 +123,23 @@ namespace kiwano
{ {
} }
LineActor::LineActor(Point const& end) LineActor::LineActor(Point const& point)
{ {
SetEndPoint(end); SetPoint(point);
} }
LineActor::~LineActor() LineActor::~LineActor()
{ {
} }
void LineActor::SetEndPoint(Point const& end) void LineActor::SetPoint(Point const& point)
{ {
geo_ = Geometry::CreateLine(Point{}, end); Geometry geo = Geometry::CreateLine(Point{}, point);
if (geo_) if (geo)
{ {
SetSize(end); point_ = point;
SetGeometry(geo);
} }
} }
@ -145,11 +163,12 @@ namespace kiwano
void RectActor::SetRectSize(Size const& size) void RectActor::SetRectSize(Size const& size)
{ {
geo_ = Geometry::CreateRect(Rect{ Point{}, size }); Geometry geo = Geometry::CreateRect(Rect{ Point{}, size });
if (geo_) if (geo)
{ {
SetSize(size); rect_size_ = size;
SetGeometry(geo);
} }
} }
@ -183,11 +202,12 @@ namespace kiwano
void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius)
{ {
geo_ = Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius); Geometry geo = Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius);
if (geo_) if (geo)
{ {
SetSize(size); rect_size_ = size;
SetGeometry(geo);
} }
} }
@ -212,11 +232,11 @@ namespace kiwano
void CircleActor::SetRadius(Float32 radius) void CircleActor::SetRadius(Float32 radius)
{ {
geo_ = Geometry::CreateCircle(Point{}, radius); Geometry geo = Geometry::CreateCircle(Point{}, radius);
if (geo_) if (geo)
{ {
SetSize(radius * 2, radius * 2); SetGeometry(geo);
} }
} }
@ -240,11 +260,11 @@ namespace kiwano
void EllipseActor::SetRadius(Vec2 const& radius) void EllipseActor::SetRadius(Vec2 const& radius)
{ {
geo_ = Geometry::CreateEllipse(Point{}, radius); Geometry geo = Geometry::CreateEllipse(Point{}, radius);
if (geo_) if (geo)
{ {
SetSize(radius * 2); SetGeometry(geo);
} }
} }
@ -269,7 +289,12 @@ namespace kiwano
void PathActor::EndPath(bool closed) void PathActor::EndPath(bool closed)
{ {
sink_.EndPath(closed); sink_.EndPath(closed);
geo_ = sink_.GetGeometry(); Geometry geo = sink_.GetGeometry();
if (geo)
{
SetGeometry(geo);
}
} }
void PathActor::AddLine(Point const& point) void PathActor::AddLine(Point const& point)

View File

@ -38,16 +38,19 @@ namespace kiwano
virtual ~ShapeActor(); virtual ~ShapeActor();
// 获取填充颜色 // 获取填充颜色
Color GetFillColor() const { return fill_color_; } inline Color GetFillColor() const { return fill_color_; }
// 获取线条颜色 // 获取线条颜色
Color GetStrokeColor() const { return stroke_color_; } inline Color GetStrokeColor() const { return stroke_color_; }
// 获取线条宽度 // 获取线条宽度
Float32 GetStrokeWidth() const { return stroke_width_; } inline Float32 GetStrokeWidth() const { return stroke_width_; }
// 获取线条样式 // 获取线条样式
StrokeStyle SetStrokeStyle() const { return stroke_style_; } inline StrokeStyle SetStrokeStyle() const { return stroke_style_; }
// 获取形状
inline Geometry GetGeometry() const { return geo_; }
// 获取边界 // 获取边界
Rect GetBounds() const override; Rect GetBounds() const override;
@ -55,44 +58,37 @@ namespace kiwano
// 获取外切包围盒 // 获取外切包围盒
Rect GetBoundingBox() const override; Rect GetBoundingBox() const override;
// 判断点是否在形状内
bool ContainsPoint(const Point& point) const override;
// 设置填充颜色 // 设置填充颜色
void SetFillColor( void SetFillColor(const Color& color);
const Color& color
);
// 设置线条颜色 // 设置线条颜色
void SetStrokeColor( void SetStrokeColor(const Color& color);
const Color& color
);
// 设置线条宽度 // 设置线条宽度
void SetStrokeWidth( void SetStrokeWidth(Float32 width);
Float32 width
);
// 设置线条样式 // 设置线条样式
void SetStrokeStyle( void SetStrokeStyle(StrokeStyle stroke_style);
StrokeStyle stroke_style
);
// 设置形状 // 设置形状
inline void SetGeometry(Geometry geometry) { geo_ = geometry; } void SetGeometry(Geometry geometry);
// »ñÈ¡ÐÎ×´ void OnRender(RenderTarget* rt) override;
inline Geometry GetGeometry() const { return geo_; }
void OnRender(Renderer* renderer) override;
protected: protected:
Color fill_color_; Color fill_color_;
Color stroke_color_; Color stroke_color_;
Float32 stroke_width_; Float32 stroke_width_;
StrokeStyle stroke_style_; StrokeStyle stroke_style_;
Rect bounds_;
Geometry geo_; Geometry geo_;
}; };
// Ö±Ïß // 直线角色
class KGE_API LineActor class KGE_API LineActor
: public ShapeActor : public ShapeActor
{ {
@ -100,19 +96,19 @@ namespace kiwano
LineActor(); LineActor();
LineActor( LineActor(
Point const& end_pos Point const& point
); );
virtual ~LineActor(); virtual ~LineActor();
Point const& GetEndPoint() const { return end_; } Point const& GetPoint() const { return point_; }
void SetEndPoint( void SetPoint(
Point const& end Point const& point
); );
protected: protected:
Point end_; Point point_;
}; };
@ -131,10 +127,10 @@ namespace kiwano
void SetRectSize(Size const& size); void SetRectSize(Size const& size);
inline Size const& GetRectSize() const { return size_; } inline Size const& GetRectSize() const { return rect_size_; }
protected: protected:
Size size_; Size rect_size_;
}; };
@ -170,7 +166,7 @@ namespace kiwano
inline Size GetRectSize() const { return size_; } inline Size GetRectSize() const { return size_; }
protected: protected:
Size size_; Size rect_size_;
Vec2 radius_; Vec2 radius_;
}; };
@ -261,7 +257,7 @@ namespace kiwano
void AddArc( void AddArc(
Point const& point, /* 终点 */ Point const& point, /* 终点 */
Size const& radius, /* 椭圆半径 */ Size const& radius, /* 椭圆半径 */
Float32 rotation, /* ÍÖÔ²Ðýת½Ç¶È */ Float32 rotation, /* 椭圆旋转角度 */
bool clockwise = true, /* 顺时针 or 逆时针 */ bool clockwise = true, /* 顺时针 or 逆时针 */
bool is_small = true /* 是否取小于 180° 的弧 */ bool is_small = true /* 是否取小于 180° 的弧 */
); );

View File

@ -86,7 +86,7 @@ namespace kiwano
if (frame_) if (frame_)
{ {
frame_->SetCropRect(crop_rect); frame_->SetCropRect(crop_rect);
SetSize(frame_->GetWidth(), frame_->GetHeight()); SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
} }
} }
@ -97,18 +97,18 @@ namespace kiwano
frame_ = frame; frame_ = frame;
if (frame_) if (frame_)
{ {
SetSize(frame_->GetWidth(), frame_->GetHeight()); SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
} }
} }
} }
void Sprite::OnRender(Renderer* renderer) void Sprite::OnRender(RenderTarget* rt)
{ {
if (frame_ && renderer->CheckVisibility(size_, transform_matrix_)) if (frame_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix()))
{ {
PrepareRender(renderer); PrepareRender(rt);
renderer->DrawImage(frame_->GetImage(), &frame_->GetCropRect(), nullptr); rt->DrawImage(frame_->GetImage(), &frame_->GetCropRect(), nullptr);
} }
} }
} }

View File

@ -77,7 +77,7 @@ namespace kiwano
void SetFrame(FramePtr frame); void SetFrame(FramePtr frame);
// äÖČžžŤÁé // äÖČžžŤÁé
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
protected: protected:
FramePtr frame_; FramePtr frame_;

View File

@ -28,7 +28,7 @@ namespace kiwano
{ {
stage_ = this; stage_ = this;
SetAnchor(0, 0); SetAnchor(Vec2{ 0, 0 });
SetSize(Renderer::GetInstance()->GetOutputSize()); SetSize(Renderer::GetInstance()->GetOutputSize());
} }

View File

@ -200,14 +200,14 @@ namespace kiwano
style_.outline_stroke = outline_stroke; style_.outline_stroke = outline_stroke;
} }
void Text::OnRender(Renderer* renderer) void Text::OnRender(RenderTarget* rt)
{ {
UpdateLayout(); UpdateLayout();
if (text_layout_ && renderer->CheckVisibility(size_, transform_matrix_)) if (text_layout_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix()))
{ {
PrepareRender(renderer); PrepareRender(rt);
renderer->DrawTextLayout(text_layout_); rt->DrawTextLayout(text_layout_);
} }
} }

View File

@ -160,7 +160,7 @@ namespace kiwano
TextStyle const& style TextStyle const& style
); );
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
protected: protected:
void UpdateLayout(); void UpdateLayout();

View File

@ -0,0 +1,49 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// 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
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "Transform.h"
namespace kiwano
{
Transform::Transform()
: position()
, rotation(0.f)
, scale(1.f, 1.f)
, skew(0.f, 0.f)
{
}
Matrix3x2 Transform::ToMatrix() const
{
if (!skew.IsOrigin())
{
return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation);
}
return Matrix3x2::SRT(position, scale, rotation);
}
bool Transform::operator== (Transform const& rhs) const
{
return position == rhs.position &&
rotation == rhs.rotation &&
scale == rhs.scale &&
skew == rhs.skew;
}
}

View File

@ -19,32 +19,23 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../math/Vec2.hpp" #include "../math/math.h"
namespace kiwano namespace kiwano
{ {
class Transform class Transform
{ {
public: public:
Float32 rotation; // Ðýת Float32 rotation; // Ðýת
Point position; // ×ø±ê Point position; // ×ø±ê
Point scale; // Ëõ·Å Point scale; // Ëõ·Å
Point skew; // ´íÇÐ½Ç¶È Point skew; // ´íÇнǶÈ
public: public:
Transform() Transform();
: position()
, rotation(0.f)
, scale(1.f, 1.f)
, skew(0.f, 0.f)
{}
bool operator== (const Transform& other) const Matrix3x2 ToMatrix() const;
{
return position == other.position && bool operator== (const Transform& rhs) const;
scale == other.scale &&
skew == other.skew &&
rotation == other.rotation;
}
}; };
} }

View File

@ -37,8 +37,8 @@ namespace kiwano
, delta_() , delta_()
, process_(0) , process_(0)
, window_size_() , window_size_()
, out_scene_(nullptr) , out_stage_(nullptr)
, in_scene_(nullptr) , in_stage_(nullptr)
, out_layer_() , out_layer_()
, in_layer_() , in_layer_()
{ {
@ -58,22 +58,19 @@ namespace kiwano
process_ = 0; process_ = 0;
delta_ = Duration{}; delta_ = Duration{};
out_scene_ = prev; out_stage_ = prev;
in_scene_ = next; in_stage_ = next;
if (in_scene_)
{
Renderer::GetInstance()->CreateLayer(in_layer_);
}
if (out_scene_)
{
Renderer::GetInstance()->CreateLayer(out_layer_);
}
window_size_ = Renderer::GetInstance()->GetOutputSize(); window_size_ = Renderer::GetInstance()->GetOutputSize();
out_layer_.SetAreaRect(Rect{ Point(), window_size_ });
in_layer_.SetAreaRect(Rect{ Point(), window_size_ }); if (in_stage_)
{
in_layer_.SetAreaRect(Rect{ Point(), window_size_ });
}
if (out_stage_)
{
out_layer_.SetAreaRect(Rect{ Point(), window_size_ });
}
} }
void Transition::Update(Duration dt) void Transition::Update(Duration dt)
@ -94,30 +91,30 @@ namespace kiwano
} }
} }
void Transition::Render(Renderer* renderer) void Transition::Render(RenderTarget* rt)
{ {
if (out_scene_) if (out_stage_)
{ {
renderer->SetTransform(out_scene_->GetTransformMatrix()); out_stage_->PrepareRender(rt);
renderer->PushClipRect(Rect{ Point{}, window_size_ }); rt->PushClipRect(Rect{ Point{}, window_size_ });
renderer->PushLayer(out_layer_); rt->PushLayer(out_layer_);
out_scene_->Render(renderer); out_stage_->Render(rt);
renderer->PopLayer(); rt->PopLayer();
renderer->PopClipRect(); rt->PopClipRect();
} }
if (in_scene_) if (in_stage_)
{ {
renderer->SetTransform(in_scene_->GetTransformMatrix()); in_stage_->PrepareRender(rt);
renderer->PushClipRect(Rect{ Point{}, window_size_ }); rt->PushClipRect(Rect{ Point{}, window_size_ });
renderer->PushLayer(in_layer_); rt->PushLayer(in_layer_);
in_scene_->Render(renderer); in_stage_->Render(rt);
renderer->PopLayer(); rt->PopLayer();
renderer->PopClipRect(); rt->PopClipRect();
} }
} }
@ -153,8 +150,8 @@ namespace kiwano
Rect( Rect(
window_size_.x * process_, window_size_.x * process_,
window_size_.y * process_, window_size_.y * process_,
window_size_.x * (1 - process_ * 2), window_size_.x * (1 - process_),
window_size_.y * (1 - process_ * 2) window_size_.y * (1 - process_)
) )
); );
} }
@ -166,8 +163,8 @@ namespace kiwano
Rect( Rect(
window_size_.x * (1 - process_), window_size_.x * (1 - process_),
window_size_.y * (1 - process_), window_size_.y * (1 - process_),
window_size_.x * (2 * process_ - 1), window_size_.x * process_,
window_size_.y * (2 * process_ - 1) window_size_.y * process_
) )
); );
} }
@ -265,16 +262,16 @@ namespace kiwano
break; break;
} }
if (out_scene_) if (out_stage_)
{ {
out_scene_->SetTransform(Transform{}); out_stage_->SetTransform(Transform{});
} }
if (in_scene_) if (in_stage_)
{ {
auto transform = Transform{}; auto transform = Transform{};
transform.position = start_pos_; transform.position = start_pos_;
in_scene_->SetTransform(transform); in_stage_->SetTransform(transform);
} }
} }
@ -282,31 +279,31 @@ namespace kiwano
{ {
Transition::Update(dt); Transition::Update(dt);
if (out_scene_) if (out_stage_)
{ {
auto transform = Transform{}; auto transform = Transform{};
transform.position = pos_delta_ * process_; transform.position = pos_delta_ * process_;
out_scene_->SetTransform(transform); out_stage_->SetTransform(transform);
} }
if (in_scene_) if (in_stage_)
{ {
auto transform = Transform{}; auto transform = Transform{};
transform.position = start_pos_ + pos_delta_ * process_; transform.position = start_pos_ + pos_delta_ * process_;
in_scene_->SetTransform(transform); in_stage_->SetTransform(transform);
} }
} }
void MoveTransition::Reset() void MoveTransition::Reset()
{ {
if (out_scene_) if (out_stage_)
{ {
out_scene_->SetTransform(Transform{}); out_stage_->SetTransform(Transform{});
} }
if (in_scene_) if (in_stage_)
{ {
in_scene_->SetTransform(Transform{}); in_stage_->SetTransform(Transform{});
} }
} }
@ -327,16 +324,16 @@ namespace kiwano
auto transform = Transform{}; auto transform = Transform{};
transform.position = Point{ window_size_.x / 2, window_size_.y / 2 }; transform.position = Point{ window_size_.x / 2, window_size_.y / 2 };
if (out_scene_) if (out_stage_)
{ {
out_scene_->SetTransform(transform); out_stage_->SetTransform(transform);
out_scene_->SetAnchor(0.5f, 0.5f); out_stage_->SetAnchor(Vec2{ 0.5f, 0.5f });
} }
if (in_scene_) if (in_stage_)
{ {
in_scene_->SetTransform(transform); in_stage_->SetTransform(transform);
in_scene_->SetAnchor(0.5f, 0.5f); in_stage_->SetAnchor(Vec2{ 0.5f, 0.5f });
} }
in_layer_.SetOpacity(0.f); in_layer_.SetOpacity(0.f);
@ -348,42 +345,42 @@ namespace kiwano
if (process_ < .5f) if (process_ < .5f)
{ {
if (out_scene_) if (out_stage_)
{ {
auto transform = out_scene_->GetTransform(); auto transform = out_stage_->GetTransform();
transform.scale = Point{ (.5f - process_) * 2, (.5f - process_) * 2 }; transform.scale = Point{ (.5f - process_) * 2, (.5f - process_) * 2 };
transform.rotation = rotation_ * (.5f - process_) * 2; transform.rotation = rotation_ * (.5f - process_) * 2;
out_scene_->SetTransform(transform); out_stage_->SetTransform(transform);
} }
} }
else else
{ {
if (in_scene_) if (in_stage_)
{ {
out_layer_.SetOpacity(0.f); out_layer_.SetOpacity(0.f);
in_layer_.SetOpacity(1.f); in_layer_.SetOpacity(1.f);
auto transform = in_scene_->GetTransform(); auto transform = in_stage_->GetTransform();
transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 }; transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 };
transform.rotation = rotation_ * (process_ - .5f) * 2; transform.rotation = rotation_ * (process_ - .5f) * 2;
in_scene_->SetTransform(transform); in_stage_->SetTransform(transform);
} }
} }
} }
void RotationTransition::Reset() void RotationTransition::Reset()
{ {
if (out_scene_) if (out_stage_)
{ {
out_scene_->SetTransform(Transform{}); out_stage_->SetTransform(Transform{});
out_scene_->SetAnchor(0.f, 0.f); out_stage_->SetAnchor(Vec2{ 0.f, 0.f });
} }
if (in_scene_) if (in_stage_)
{ {
in_scene_->SetTransform(Transform{}); in_stage_->SetTransform(Transform{});
in_scene_->SetAnchor(0.f, 0.f); in_stage_->SetAnchor(Vec2{ 0.f, 0.f });
} }
} }
} }

View File

@ -25,7 +25,7 @@
namespace kiwano namespace kiwano
{ {
class Director; class Director;
class Renderer; class RenderTarget;
// 舞台过渡 // 舞台过渡
class KGE_API Transition class KGE_API Transition
@ -50,7 +50,7 @@ namespace kiwano
virtual void Update(Duration dt); virtual void Update(Duration dt);
virtual void Render(Renderer* renderer); virtual void Render(RenderTarget* rt);
virtual void Stop(); virtual void Stop();
@ -62,8 +62,8 @@ namespace kiwano
Duration duration_; Duration duration_;
Duration delta_; Duration delta_;
Size window_size_; Size window_size_;
StagePtr out_scene_; StagePtr out_stage_;
StagePtr in_scene_; StagePtr in_stage_;
LayerArea out_layer_; LayerArea out_layer_;
LayerArea in_layer_; LayerArea in_layer_;
}; };

View File

@ -62,7 +62,7 @@ namespace kiwano
inline void SetDelay(Duration delay) { delay_ = delay; } inline void SetDelay(Duration delay) { delay_ = delay; }
// 设置循环次数 (-1 为永久循环) // 设置循环次数 (-1 为永久循环)
inline void SetLoops(Int32 loops) { loops_ = loops; } inline void SetLoops(Int32 loops) { loops_ = loops; }
// 动作结束时移除目标角色 // 动作结束时移除目标角色
inline void RemoveTargetWhenDone() { detach_target_ = true; } inline void RemoveTargetWhenDone() { detach_target_ = true; }
@ -89,7 +89,7 @@ namespace kiwano
inline bool IsRemoveable() const { return status_ == Status::Removeable; } inline bool IsRemoveable() const { return status_ == Status::Removeable; }
inline Int32 GetLoops() const { return loops_; } inline Int32 GetLoops() const { return loops_; }
inline Duration GetDelay() const { return delay_; } inline Duration GetDelay() const { return delay_; }
@ -114,8 +114,8 @@ namespace kiwano
Status status_; Status status_;
bool running_; bool running_;
bool detach_target_; bool detach_target_;
Int32 loops_; Int32 loops_;
Int32 loops_done_; Int32 loops_done_;
Duration delay_; Duration delay_;
Duration elapsed_; Duration elapsed_;
ActionCallback cb_done_; ActionCallback cb_done_;

View File

@ -45,7 +45,7 @@ namespace kiwano
void ActionGroup::Init(ActorPtr target) void ActionGroup::Init(ActorPtr target)
{ {
if (actions_.item_empty()) if (actions_.empty())
{ {
Done(); Done();
return; return;
@ -106,7 +106,7 @@ namespace kiwano
{ {
if (action) if (action)
{ {
actions_.push_back_item(action); actions_.push_back(action);
} }
} }
@ -135,7 +135,7 @@ namespace kiwano
ActionPtr ActionGroup::Reverse() const ActionPtr ActionGroup::Reverse() const
{ {
auto group = new (std::nothrow) ActionGroup(); auto group = new (std::nothrow) ActionGroup();
if (group && !actions_.item_empty()) if (group && !actions_.empty())
{ {
for (auto action = actions_.last_item(); action; action = action->prev_item()) for (auto action = actions_.last_item(); action; action = action->prev_item())
{ {

View File

@ -64,7 +64,7 @@ namespace kiwano
inline TweenHelper& SetDuration(Duration dur) { base->SetDuration(dur); return (*this); } inline TweenHelper& SetDuration(Duration dur) { base->SetDuration(dur); return (*this); }
// 设置循环次数 // 设置循环次数
inline TweenHelper& SetLoops(Int32 loops) { base->SetLoops(loops); return (*this); } inline TweenHelper& SetLoops(Int32 loops) { base->SetLoops(loops); return (*this); }
// 设置缓动函数 // 设置缓动函数
inline TweenHelper& SetEaseFunc(EaseFunc ease) { base->SetEaseFunc(ease); return (*this); } inline TweenHelper& SetEaseFunc(EaseFunc ease) { base->SetEaseFunc(ease); return (*this); }
@ -118,7 +118,7 @@ namespace kiwano
Duration dur, Duration dur,
Point const& pos, /* 目的坐标 */ Point const& pos, /* 目的坐标 */
Float32 height, /* 跳跃高度 */ Float32 height, /* 跳跃高度 */
Int32 jumps = 1) /* 跳跃次数 */ Int32 jumps = 1) /* 跳跃次数 */
{ {
return TweenHelper(new kiwano::ActionJumpBy(dur, pos, height, jumps)); return TweenHelper(new kiwano::ActionJumpBy(dur, pos, height, jumps));
} }
@ -128,7 +128,7 @@ namespace kiwano
Duration dur, Duration dur,
Point const& pos, /* 目的坐标 */ Point const& pos, /* 目的坐标 */
Float32 height, /* 跳跃高度 */ Float32 height, /* 跳跃高度 */
Int32 jumps = 1) /* 跳跃次数 */ Int32 jumps = 1) /* 跳跃次数 */
{ {
return TweenHelper(new kiwano::ActionJumpTo(dur, pos, height, jumps)); return TweenHelper(new kiwano::ActionJumpTo(dur, pos, height, jumps));
} }

View File

@ -26,7 +26,7 @@ namespace kiwano
{ {
void ActionManager::UpdateActions(ActorPtr target, Duration dt) void ActionManager::UpdateActions(ActorPtr target, Duration dt)
{ {
if (actions_.item_empty() || !target) if (actions_.empty() || !target)
return; return;
ActionPtr next; ActionPtr next;
@ -38,7 +38,7 @@ namespace kiwano
action->UpdateStep(target, dt); action->UpdateStep(target, dt);
if (action->IsRemoveable()) if (action->IsRemoveable())
actions_.remove_item(action); actions_.remove(action);
} }
} }
@ -48,14 +48,14 @@ namespace kiwano
if (action) if (action)
{ {
actions_.push_back_item(action); actions_.push_back(action);
} }
return action.get(); return action.get();
} }
ActionPtr ActionManager::GetAction(String const & name) ActionPtr ActionManager::GetAction(String const & name)
{ {
if (actions_.item_empty()) if (actions_.empty())
return nullptr; return nullptr;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@ -66,7 +66,7 @@ namespace kiwano
void ActionManager::ResumeAllActions() void ActionManager::ResumeAllActions()
{ {
if (actions_.item_empty()) if (actions_.empty())
return; return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@ -77,7 +77,7 @@ namespace kiwano
void ActionManager::PauseAllActions() void ActionManager::PauseAllActions()
{ {
if (actions_.item_empty()) if (actions_.empty())
return; return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@ -88,7 +88,7 @@ namespace kiwano
void ActionManager::StopAllActions() void ActionManager::StopAllActions()
{ {
if (actions_.item_empty()) if (actions_.empty())
return; return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) for (auto action = actions_.first_item().get(); action; action = action->next_item().get())

View File

@ -281,7 +281,7 @@ namespace kiwano
void ActionScaleBy::UpdateTween(ActorPtr target, Float32 percent) void ActionScaleBy::UpdateTween(ActorPtr target, Float32 percent)
{ {
target->SetScale(start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent); target->SetScale(Vec2{ start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent });
} }
ActionPtr ActionScaleBy::Clone() const ActionPtr ActionScaleBy::Clone() const

View File

@ -166,7 +166,7 @@ namespace kiwano
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Point const& vec, /* 跳跃距离 */ Point const& vec, /* 跳跃距离 */
Float32 height, /* 跳跃高度 */ Float32 height, /* 跳跃高度 */
Int32 jumps = 1, /* 跳跃次数 */ Int32 jumps = 1, /* 跳跃次数 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );
@ -199,7 +199,7 @@ namespace kiwano
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Point const& pos, /* 目的坐标 */ Point const& pos, /* 目的坐标 */
Float32 height, /* 跳跃高度 */ Float32 height, /* 跳跃高度 */
Int32 jumps = 1, /* 跳跃次数 */ Int32 jumps = 1, /* 跳跃次数 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );
@ -234,8 +234,8 @@ namespace kiwano
ActionScaleBy( ActionScaleBy(
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Float32 scale_x, /* 横向缩放相对变化值 */ Float32 scale_x, /* 横向缩放相对变化值 */
Float32 scale_y, /* 纵向缩放相对变化值 */ Float32 scale_y, /* 纵向缩放相对变化值 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );
@ -271,8 +271,8 @@ namespace kiwano
ActionScaleTo( ActionScaleTo(
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Float32 scale_x, /* 横向缩放目标值 */ Float32 scale_x, /* 横向缩放目标值 */
Float32 scale_y, /* 纵向缩放目标值 */ Float32 scale_y, /* 纵向缩放目标值 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );
@ -302,7 +302,7 @@ namespace kiwano
public: public:
ActionFadeTo( ActionFadeTo(
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Float32 opacity, /* 目标值 */ Float32 opacity, /* 目标值 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );
@ -361,7 +361,7 @@ namespace kiwano
public: public:
ActionRotateBy( ActionRotateBy(
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Float32 rotation, /* 相对变化值 */ Float32 rotation, /* 相对变化值 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );
@ -389,7 +389,7 @@ namespace kiwano
public: public:
ActionRotateTo( ActionRotateTo(
Duration duration, /* 持续时长 */ Duration duration, /* 持续时长 */
Float32 rotation, /* 目标值 */ Float32 rotation, /* 目标值 */
EaseFunc func = nullptr /* 速度变化 */ EaseFunc func = nullptr /* 速度变化 */
); );

View File

@ -25,7 +25,7 @@
namespace kiwano namespace kiwano
{ {
class Renderer; class RenderTarget;
class KGE_API Component class KGE_API Component
{ {
@ -38,7 +38,7 @@ namespace kiwano
virtual void AfterUpdate() {} virtual void AfterUpdate() {}
virtual void BeforeRender() {} virtual void BeforeRender() {}
virtual void OnRender(Renderer*) {} virtual void OnRender(RenderTarget*) {}
virtual void AfterRender() {} virtual void AfterRender() {}
virtual void HandleEvent(Event&) {} virtual void HandleEvent(Event&) {}

View File

@ -23,6 +23,7 @@
#include "../2d/Stage.h" #include "../2d/Stage.h"
#include "../2d/Transition.h" #include "../2d/Transition.h"
#include "../2d/DebugActor.h" #include "../2d/DebugActor.h"
#include "../renderer/RenderTarget.h"
namespace kiwano namespace kiwano
{ {
@ -35,34 +36,34 @@ namespace kiwano
{ {
} }
void Director::EnterStage(StagePtr scene) void Director::EnterStage(StagePtr stage)
{ {
KGE_ASSERT(scene && "Director::EnterStage failed, NULL pointer exception"); KGE_ASSERT(stage && "Director::EnterStage failed, NULL pointer exception");
if (curr_scene_ == scene || next_scene_ == scene) if (curr_stage_ == stage || next_stage_ == stage)
return; return;
next_scene_ = scene; next_stage_ = stage;
} }
void Director::EnterStage(StagePtr scene, TransitionPtr transition) void Director::EnterStage(StagePtr stage, TransitionPtr transition)
{ {
EnterStage(scene); EnterStage(stage);
if (transition && next_scene_) if (transition && next_stage_)
{ {
if (transition_) if (transition_)
{ {
transition_->Stop(); transition_->Stop();
} }
transition_ = transition; transition_ = transition;
transition_->Init(curr_scene_, next_scene_); transition_->Init(curr_stage_, next_stage_);
} }
} }
StagePtr Director::GetCurrentStage() StagePtr Director::GetCurrentStage()
{ {
return curr_scene_; return curr_stage_;
} }
void Director::SetRenderBorderEnabled(bool enabled) void Director::SetRenderBorderEnabled(bool enabled)
@ -85,8 +86,8 @@ namespace kiwano
void Director::ClearStages() void Director::ClearStages()
{ {
curr_scene_.reset(); curr_stage_.reset();
next_scene_.reset(); next_stage_.reset();
debug_actor_.reset(); debug_actor_.reset();
transition_.reset(); transition_.reset();
} }
@ -101,54 +102,52 @@ namespace kiwano
transition_ = nullptr; transition_ = nullptr;
} }
if (next_scene_ && !transition_) if (next_stage_ && !transition_)
{ {
if (curr_scene_) if (curr_stage_)
{ {
curr_scene_->OnExit(); curr_stage_->OnExit();
} }
next_scene_->OnEnter(); next_stage_->OnEnter();
curr_scene_ = next_scene_; curr_stage_ = next_stage_;
next_scene_ = nullptr; next_stage_ = nullptr;
} }
if (curr_scene_) if (curr_stage_)
curr_scene_->Update(dt); curr_stage_->Update(dt);
if (next_scene_) if (next_stage_)
next_scene_->Update(dt); next_stage_->Update(dt);
if (debug_actor_) if (debug_actor_)
debug_actor_->Update(dt); debug_actor_->Update(dt);
} }
void Director::OnRender(Renderer* renderer) void Director::OnRender(RenderTarget* rt)
{ {
if (transition_) if (transition_)
{ {
transition_->Render(renderer); transition_->Render(rt);
} }
else if (curr_scene_) else if (curr_stage_)
{ {
curr_scene_->Render(renderer); curr_stage_->Render(rt);
}
if (render_border_enabled_)
{
rt->SetOpacity(1.f);
if (curr_stage_)
{
curr_stage_->RenderBorder(rt);
}
} }
if (debug_actor_) if (debug_actor_)
{ {
debug_actor_->Render(renderer); debug_actor_->Render(rt);
}
}
void Director::AfterRender()
{
if (render_border_enabled_)
{
if (curr_scene_)
{
curr_scene_->RenderBorder();
}
} }
} }
@ -157,8 +156,8 @@ namespace kiwano
if (debug_actor_) if (debug_actor_)
debug_actor_->Dispatch(evt); debug_actor_->Dispatch(evt);
if (curr_scene_) if (curr_stage_)
curr_scene_->Dispatch(evt); curr_stage_->Dispatch(evt);
} }
} }

View File

@ -35,12 +35,12 @@ namespace kiwano
public: public:
// 切换舞台 // 切换舞台
void EnterStage( void EnterStage(
StagePtr scene /* Îę̀ */ StagePtr stage /* Îę̀ */
); );
// 切换舞台 // 切换舞台
void EnterStage( void EnterStage(
StagePtr scene, /* Îę̀ */ StagePtr stage, /* Îę̀ */
TransitionPtr transition /* 过渡动画 */ TransitionPtr transition /* 过渡动画 */
); );
@ -63,9 +63,7 @@ namespace kiwano
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;
void OnRender(Renderer* renderer) override; void OnRender(RenderTarget* rt) override;
void AfterRender() override;
void HandleEvent(Event& evt) override; void HandleEvent(Event& evt) override;
@ -76,8 +74,8 @@ namespace kiwano
protected: protected:
bool render_border_enabled_; bool render_border_enabled_;
StagePtr curr_scene_; StagePtr curr_stage_;
StagePtr next_scene_; StagePtr next_stage_;
ActorPtr debug_actor_; ActorPtr debug_actor_;
TransitionPtr transition_; TransitionPtr transition_;
}; };

View File

@ -25,7 +25,7 @@ namespace kiwano
{ {
void EventDispatcher::Dispatch(Event& evt) void EventDispatcher::Dispatch(Event& evt)
{ {
if (listeners_.item_empty()) if (listeners_.empty())
return; return;
EventListenerPtr next; EventListenerPtr next;
@ -40,24 +40,21 @@ namespace kiwano
} }
} }
EventListenerPtr EventDispatcher::AddListener(EventListenerPtr listener) EventListener* EventDispatcher::AddListener(EventListenerPtr listener)
{ {
KGE_ASSERT(listener && "AddListener failed, NULL pointer exception"); KGE_ASSERT(listener && "AddListener failed, NULL pointer exception");
if (listener) if (listener)
{ {
listeners_.push_back_item(listener); listeners_.push_back(listener);
} }
return listener; return listener.get();
} }
void EventDispatcher::AddListener(UInt32 type, EventCallback callback, String const& name) EventListener* EventDispatcher::AddListener(UInt32 type, EventCallback callback, String const& name)
{ {
EventListenerPtr listener = new EventListener(type, callback, name); EventListenerPtr listener = new EventListener(type, callback, name);
if (listener) return AddListener(listener);
{
listeners_.push_back_item(listener);
}
} }
void EventDispatcher::StartListeners(String const & listener_name) void EventDispatcher::StartListeners(String const & listener_name)
@ -91,7 +88,7 @@ namespace kiwano
if (listener->IsName(listener_name)) if (listener->IsName(listener_name))
{ {
listeners_.remove_item(listener); listeners_.remove(listener);
} }
} }
} }
@ -127,7 +124,7 @@ namespace kiwano
if (listener->type_ == type) if (listener->type_ == type)
{ {
listeners_.remove_item(listener); listeners_.remove(listener);
} }
} }
} }

View File

@ -29,12 +29,12 @@ namespace kiwano
public: public:
// 添加监听器 // 添加监听器
EventListenerPtr AddListener( EventListener* AddListener(
EventListenerPtr listener EventListenerPtr listener
); );
// 添加监听器 // 添加监听器
void AddListener( EventListener* AddListener(
UInt32 type, UInt32 type,
EventCallback callback, EventCallback callback,
String const& name = L"" String const& name = L""

View File

@ -279,7 +279,7 @@ namespace kiwano
{ {
static WChar temp_buffer[1024 * 3 + 1]; static WChar temp_buffer[1024 * 3 + 1];
std::wstringstream ss; StringStream ss;
ss << Logger::OutPrefix; ss << Logger::OutPrefix;
if (prompt) if (prompt)

View File

@ -263,7 +263,7 @@ namespace kiwano
template <typename ..._Args> template <typename ..._Args>
std::wstring Logger::MakeOutputString(const WChar* prompt, _Args&& ... args) const std::wstring Logger::MakeOutputString(const WChar* prompt, _Args&& ... args) const
{ {
std::wstringstream ss; StringStream ss;
ss << Logger::OutPrefix; ss << Logger::OutPrefix;
if (prompt) if (prompt)

View File

@ -46,7 +46,7 @@ namespace kiwano
inline bool IsName(String const& name) const { return name_ ? (*name_ == name) : name.empty(); } inline bool IsName(String const& name) const { return name_ ? (*name_ == name) : name.empty(); }
inline UInt32 GetObjectID() const { return id_; } inline UInt32 GetObjectID() const { return id_; }
String DumpObject(); String DumpObject();

View File

@ -31,7 +31,7 @@ namespace kiwano
} }
Resource::Resource(UInt32 id, LPCWSTR type) Resource::Resource(UInt32 id, const WChar* type)
: id_(id) : id_(id)
, type_(type) , type_(type)
{ {

View File

@ -49,8 +49,8 @@ namespace kiwano
Resource(); Resource();
Resource( Resource(
UInt32 id, /* ×ÊÔ´Ãû³Æ */ UInt32 id, /* ×ÊÔ´ ID */
LPCWSTR type /* ×ÊÔ´ÀàÐÍ */ const WChar* type /* ×ÊÔ´ÀàÐÍ */
); );
// 获取二进制数据 // 获取二进制数据
@ -58,11 +58,12 @@ namespace kiwano
inline UInt32 GetId() const { return id_; } inline UInt32 GetId() const { return id_; }
inline LPCWSTR GetType() const { return type_; } inline const WChar* GetType() const { return type_; }
private: private:
UInt32 id_; UInt32 id_;
LPCWSTR type_; const WChar* type_;
mutable Resource::Data data_; mutable Resource::Data data_;
}; };
} }

View File

@ -22,11 +22,6 @@
namespace kiwano namespace kiwano
{ {
Timer::Timer(Callback const& func, String const& name)
: Timer(func, Duration{}, -1, name)
{
}
Timer::Timer(Callback const& func, Duration delay, Int32 times, String const& name) Timer::Timer(Callback const& func, Duration delay, Int32 times, String const& name)
: running_(true) : running_(true)
, run_times_(0) , run_times_(0)
@ -91,4 +86,4 @@ namespace kiwano
return running_; return running_;
} }
} }

View File

@ -40,15 +40,10 @@ namespace kiwano
using Callback = Function<void()>; using Callback = Function<void()>;
public: public:
explicit Timer( Timer(
Callback const& func, /* 执行函数 */
String const& name = L"" /* 任务名称 */
);
explicit Timer(
Callback const& func, /* 执行函数 */ Callback const& func, /* 执行函数 */
Duration delay, /* 时间间隔(秒) */ Duration delay, /* 时间间隔(秒) */
Int32 times = -1, /* 执行次数(设 -1 为永久执行) */ Int32 times = -1, /* 执行次数(设 -1 为永久执行) */
String const& name = L"" /* 任务名称 */ String const& name = L"" /* 任务名称 */
); );
@ -68,8 +63,8 @@ namespace kiwano
protected: protected:
bool running_; bool running_;
Int32 run_times_; Int32 run_times_;
Int32 total_times_; Int32 total_times_;
Duration delay_; Duration delay_;
Duration delta_; Duration delta_;
Callback callback_; Callback callback_;

View File

@ -25,7 +25,7 @@ namespace kiwano
{ {
void TimerManager::UpdateTimers(Duration dt) void TimerManager::UpdateTimers(Duration dt)
{ {
if (timers_.item_empty()) if (timers_.empty())
return; return;
TimerPtr next; TimerPtr next;
@ -37,24 +37,32 @@ namespace kiwano
timer->Update(dt, remove_after_update); timer->Update(dt, remove_after_update);
if (remove_after_update) if (remove_after_update)
timers_.remove_item(timer); timers_.remove(timer);
} }
} }
void TimerManager::AddTimer(TimerPtr timer) Timer* TimerManager::AddTimer(Timer::Callback const& func, Duration delay, Int32 times, String const& name)
{
TimerPtr timer = new Timer(func, delay, times, name);
return AddTimer(timer);
}
Timer* TimerManager::AddTimer(TimerPtr timer)
{ {
KGE_ASSERT(timer && "AddTimer failed, NULL pointer exception"); KGE_ASSERT(timer && "AddTimer failed, NULL pointer exception");
if (timer) if (timer)
{ {
timer->Reset(); timer->Reset();
timers_.push_back_item(timer); timers_.push_back(timer);
} }
return timer.get();
} }
void TimerManager::StopTimers(String const& name) void TimerManager::StopTimers(String const& name)
{ {
if (timers_.item_empty()) if (timers_.empty())
return; return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -68,7 +76,7 @@ namespace kiwano
void TimerManager::StartTimers(String const& name) void TimerManager::StartTimers(String const& name)
{ {
if (timers_.item_empty()) if (timers_.empty())
return; return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -82,7 +90,7 @@ namespace kiwano
void TimerManager::RemoveTimers(String const& name) void TimerManager::RemoveTimers(String const& name)
{ {
if (timers_.item_empty()) if (timers_.empty())
return; return;
TimerPtr next; TimerPtr next;
@ -91,14 +99,14 @@ namespace kiwano
next = timer->next_item(); next = timer->next_item();
if (timer->IsName(name)) if (timer->IsName(name))
{ {
timers_.remove_item(timer); timers_.remove(timer);
} }
} }
} }
void TimerManager::StopAllTimers() void TimerManager::StopAllTimers()
{ {
if (timers_.item_empty()) if (timers_.empty())
return; return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -109,7 +117,7 @@ namespace kiwano
void TimerManager::StartAllTimers() void TimerManager::StartAllTimers()
{ {
if (timers_.item_empty()) if (timers_.empty())
return; return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -120,7 +128,7 @@ namespace kiwano
void TimerManager::RemoveAllTimers() void TimerManager::RemoveAllTimers()
{ {
timers_.clear_items(); timers_.clear();
} }
const TimerManager::Timers & TimerManager::GetAllTimers() const const TimerManager::Timers & TimerManager::GetAllTimers() const

View File

@ -28,8 +28,16 @@ namespace kiwano
using Timers = intrusive_list<TimerPtr>; using Timers = intrusive_list<TimerPtr>;
public: public:
// Ìí¼ÓÈÎÎñ // 添加定时器
void AddTimer( Timer* AddTimer(
Timer::Callback const& func, /* 执行函数 */
Duration delay, /* 时间间隔(秒) */
Int32 times = -1, /* 执行次数(设 -1 为永久执行) */
String const& name = L"" /* 任务名称 */
);
// 添加定时器
Timer* AddTimer(
TimerPtr timer TimerPtr timer
); );

View File

@ -21,7 +21,8 @@
#include "Window.h" #include "Window.h"
#include "Logger.h" #include "Logger.h"
#define WINDOW_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX #define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
#define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP #define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
#define KGE_WND_CLASS_NAME L"KiwanoAppWnd" #define KGE_WND_CLASS_NAME L"KiwanoAppWnd"
@ -44,7 +45,8 @@ namespace kiwano
, height_(0) , height_(0)
, device_name_(nullptr) , device_name_(nullptr)
, is_fullscreen_(false) , is_fullscreen_(false)
, mouse_cursor_(MouseCursor(-1)) , resizable_(false)
, mouse_cursor_(MouseCursor::Arrow)
{ {
} }
@ -66,7 +68,7 @@ namespace kiwano
} }
} }
void Window::Init(String const& title, Int32 width, Int32 height, LPCWSTR icon, bool fullscreen, WNDPROC proc) void Window::Init(String const& title, Int32 width, Int32 height, UInt32 icon, bool resizable, bool fullscreen, WNDPROC proc)
{ {
HINSTANCE hinst = GetModuleHandleW(nullptr); HINSTANCE hinst = GetModuleHandleW(nullptr);
WNDCLASSEX wcex = { 0 }; WNDCLASSEX wcex = { 0 };
@ -80,11 +82,11 @@ namespace kiwano
wcex.hInstance = hinst; wcex.hInstance = hinst;
wcex.hbrBackground = nullptr; wcex.hbrBackground = nullptr;
wcex.lpszMenuName = nullptr; wcex.lpszMenuName = nullptr;
wcex.hCursor = nullptr; wcex.hCursor = ::LoadCursorW(hinst, IDC_ARROW);
if (icon) if (icon)
{ {
wcex.hIcon = (HICON)::LoadImageW(hinst, icon, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); wcex.hIcon = (HICON)::LoadImageW(hinst, MAKEINTRESOURCE(icon), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
} }
::RegisterClassExW(&wcex); ::RegisterClassExW(&wcex);
@ -106,6 +108,7 @@ namespace kiwano
Int32 left = -1; Int32 left = -1;
Int32 top = -1; Int32 top = -1;
resizable_ = resizable;
is_fullscreen_ = fullscreen; is_fullscreen_ = fullscreen;
if (is_fullscreen_) if (is_fullscreen_)
@ -165,8 +168,6 @@ namespace kiwano
GetClientRect(handle_, &rc); GetClientRect(handle_, &rc);
width_ = rc.right - rc.left; width_ = rc.right - rc.left;
height_ = rc.bottom - rc.top; height_ = rc.bottom - rc.top;
SetMouseCursor(MouseCursor::Arrow);
} }
} }
@ -216,14 +217,14 @@ namespace kiwano
return static_cast<Float32>(height_); return static_cast<Float32>(height_);
} }
void Window::SetIcon(LPCWSTR icon_resource) void Window::SetIcon(UInt32 icon_resource)
{ {
if (handle_) if (handle_)
{ {
HINSTANCE hinstance = GetModuleHandle(nullptr); HINSTANCE hinstance = GetModuleHandle(nullptr);
HICON icon = (HICON)::LoadImage( HICON icon = (HICON)::LoadImage(
hinstance, hinstance,
icon_resource, MAKEINTRESOURCE(icon_resource),
IMAGE_ICON, IMAGE_ICON,
0, 0,
0, 0,
@ -296,24 +297,7 @@ namespace kiwano
void Window::SetMouseCursor(MouseCursor cursor) void Window::SetMouseCursor(MouseCursor cursor)
{ {
if (mouse_cursor_ != cursor) mouse_cursor_ = cursor;
{
mouse_cursor_ = cursor;
LPTSTR win32_cursor = IDC_ARROW;
switch (cursor)
{
case MouseCursor::Arrow: win32_cursor = IDC_ARROW; break;
case MouseCursor::TextInput: win32_cursor = IDC_IBEAM; break;
case MouseCursor::SizeAll: win32_cursor = IDC_SIZEALL; break;
case MouseCursor::SizeWE: win32_cursor = IDC_SIZEWE; break;
case MouseCursor::SizeNS: win32_cursor = IDC_SIZENS; break;
case MouseCursor::SizeNESW: win32_cursor = IDC_SIZENESW; break;
case MouseCursor::SizeNWSE: win32_cursor = IDC_SIZENWSE; break;
case MouseCursor::Hand: win32_cursor = IDC_HAND; break;
}
::SetCursor(::LoadCursorW(nullptr, win32_cursor));
}
} }
HWND Window::GetHandle() const HWND Window::GetHandle() const
@ -323,7 +307,7 @@ namespace kiwano
DWORD Window::GetWindowStyle() const DWORD Window::GetWindowStyle() const
{ {
return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (WINDOW_STYLE); return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (resizable_ ? (WINDOW_RESIZABLE_STYLE) : (WINDOW_FIXED_STYLE));
} }
void Window::UpdateWindowRect() void Window::UpdateWindowRect()
@ -338,6 +322,23 @@ namespace kiwano
height_ = rc.bottom - rc.top; height_ = rc.bottom - rc.top;
} }
void Window::UpdateCursor()
{
LPTSTR win32_cursor = IDC_ARROW;
switch (mouse_cursor_)
{
case MouseCursor::Arrow: win32_cursor = IDC_ARROW; break;
case MouseCursor::TextInput: win32_cursor = IDC_IBEAM; break;
case MouseCursor::SizeAll: win32_cursor = IDC_SIZEALL; break;
case MouseCursor::SizeWE: win32_cursor = IDC_SIZEWE; break;
case MouseCursor::SizeNS: win32_cursor = IDC_SIZENS; break;
case MouseCursor::SizeNESW: win32_cursor = IDC_SIZENESW; break;
case MouseCursor::SizeNWSE: win32_cursor = IDC_SIZENWSE; break;
case MouseCursor::Hand: win32_cursor = IDC_HAND; break;
}
::SetCursor(::LoadCursorW(nullptr, win32_cursor));
}
void Window::SetActive(bool actived) void Window::SetActive(bool actived)
{ {
if (!handle_) if (!handle_)

View File

@ -48,7 +48,7 @@ namespace kiwano
void SetTitle(String const& title); void SetTitle(String const& title);
// 设置窗口图标 // 设置窗口图标
void SetIcon(LPCWSTR icon_resource); void SetIcon(UInt32 icon_resource);
// 重设窗口大小 // 重设窗口大小
void Resize(Int32 width, Int32 height); void Resize(Int32 width, Int32 height);
@ -62,9 +62,10 @@ namespace kiwano
public: public:
void Init( void Init(
String const& title, String const& title,
Int32 width, Int32 width,
Int32 height, Int32 height,
LPCWSTR icon, UInt32 icon,
bool resizable,
bool fullscreen, bool fullscreen,
WNDPROC proc WNDPROC proc
); );
@ -77,6 +78,8 @@ namespace kiwano
void UpdateWindowRect(); void UpdateWindowRect();
void UpdateCursor();
void SetActive(bool actived); void SetActive(bool actived);
protected: protected:
@ -85,11 +88,12 @@ namespace kiwano
~Window(); ~Window();
private: private:
HWND handle_; bool resizable_;
bool is_fullscreen_; bool is_fullscreen_;
HWND handle_;
Int32 width_; Int32 width_;
Int32 height_; Int32 height_;
WCHAR* device_name_; WCHAR* device_name_;
MouseCursor mouse_cursor_; MouseCursor mouse_cursor_;
}; };
} }

View File

@ -51,4 +51,13 @@ namespace kiwano
GrayScale, // 灰度抗锯齿 GrayScale, // 灰度抗锯齿
None // 不启用抗锯齿 None // 不启用抗锯齿
}; };
// 分辨率模式
enum class ResolutionMode
{
Fixed, /* 固定 */
Center, /* 居中 */
Stretch, /* 拉伸 */
Adaptive, /* 宽高自适应 */
};
} }

View File

@ -33,6 +33,7 @@
#include <queue> #include <queue>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
#include <sstream>
namespace kiwano namespace kiwano
{ {

View File

@ -71,9 +71,9 @@ class intrusive_list
public: public:
using ItemType = T; using ItemType = T;
intrusive_list() : first_(), last_() {} intrusive_list() : first_(), last_() {}
~intrusive_list() { clear_items(); } ~intrusive_list() { clear(); }
T const& first_item() const { return first_; } T const& first_item() const { return first_; }
@ -83,9 +83,9 @@ public:
T& last_item() { return last_; } T& last_item() { return last_; }
bool item_empty() const { return !first_; } bool empty() const { return !first_; }
void push_back_item(T const& child) void push_back(T const& child)
{ {
if (child->prev_) if (child->prev_)
child->prev_->next_ = child->next_; child->prev_->next_ = child->next_;
@ -109,7 +109,7 @@ public:
KGE_DEBUG_CHECK_LIST(this); KGE_DEBUG_CHECK_LIST(this);
} }
void push_front_item(T const& child) void push_front(T const& child)
{ {
if (child->prev_) if (child->prev_)
child->prev_->next_ = child->next_; child->prev_->next_ = child->next_;
@ -171,7 +171,7 @@ public:
KGE_DEBUG_CHECK_LIST(this); KGE_DEBUG_CHECK_LIST(this);
} }
void remove_item(T const& child) void remove(T const& child)
{ {
#ifdef KGE_DEBUG_ENABLE_LIST_CHECK #ifdef KGE_DEBUG_ENABLE_LIST_CHECK
T tmp = first_; T tmp = first_;
@ -206,7 +206,7 @@ public:
KGE_DEBUG_CHECK_LIST(this); KGE_DEBUG_CHECK_LIST(this);
} }
void clear_items() void clear()
{ {
T p = first_; T p = first_;
while (p) while (p)

View File

@ -28,6 +28,7 @@ namespace kiwano
KGE_DEFINE_NUMERIC_TYPE(Char, signed char); KGE_DEFINE_NUMERIC_TYPE(Char, signed char);
KGE_DEFINE_NUMERIC_TYPE(UChar, unsigned char); KGE_DEFINE_NUMERIC_TYPE(UChar, unsigned char);
KGE_DEFINE_NUMERIC_TYPE(WChar, wchar_t); KGE_DEFINE_NUMERIC_TYPE(WChar, wchar_t);
KGE_DEFINE_NUMERIC_TYPE(Byte, UChar);
KGE_DEFINE_NUMERIC_TYPE(Int8, std::int8_t); KGE_DEFINE_NUMERIC_TYPE(Int8, std::int8_t);
KGE_DEFINE_NUMERIC_TYPE(Int16, std::int16_t); KGE_DEFINE_NUMERIC_TYPE(Int16, std::int16_t);

View File

@ -95,7 +95,7 @@
// //
#include "2d/Transform.hpp" #include "2d/Transform.h"
#include "2d/TextStyle.hpp" #include "2d/TextStyle.hpp"
#include "2d/Frame.h" #include "2d/Frame.h"

View File

@ -172,7 +172,7 @@ namespace kiwano
value_type top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y)); value_type top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y));
value_type bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y)); value_type bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y));
return rect_type{ left, top, (right - left), (bottom - top) }; return rect_type{ left, top, right, bottom };
} }
inline void Translate(const vec2_type& v) inline void Translate(const vec2_type& v)
@ -324,8 +324,3 @@ namespace kiwano
} }
} }
} }
namespace kiwano
{
using Matrix3x2 = kiwano::math::Matrix3x2T<Float32>;
}

View File

@ -25,100 +25,105 @@ namespace kiwano
{ {
namespace math namespace math
{ {
// 矩形
template <typename _Ty> template <typename _Ty>
struct RectT struct RectT
{ {
public: public:
using value_type = _Ty; using value_type = _Ty;
Vec2T<value_type> origin; // 左上角坐标 Vec2T<value_type> left_top;
Vec2T<value_type> size; // 宽度和高度 Vec2T<value_type> right_bottom;
public: public:
RectT() {} RectT() {}
RectT( RectT(
value_type x, value_type left,
value_type y, value_type top,
value_type width, value_type right,
value_type height value_type bottom
) )
: origin(x, y) : left_top(left, top)
, size(width, height) , right_bottom(right, bottom)
{} {}
RectT( RectT(
const Vec2T<value_type>& pos, const Vec2T<value_type>& left_top,
const Vec2T<value_type>& size const Vec2T<value_type>& right_bottom
) )
: origin(pos.x, pos.y) : left_top(left_top)
, size(size.x, size.y) , right_bottom(right_bottom)
{} {}
RectT( RectT(
const RectT& other const RectT& other
) )
: origin(other.origin.x, other.origin.y) : left_top(other.left_top)
, size(other.size.x, other.size.y) , right_bottom(other.right_bottom)
{} {}
RectT& operator= (const RectT& other) RectT& operator= (const RectT& other)
{ {
origin = other.origin; left_top = other.left_top;
size = other.size; right_bottom = other.right_bottom;
return *this; return *this;
} }
inline bool operator== (const RectT& rect) const inline bool operator== (const RectT& rect) const
{ {
return (origin == rect.origin) && (size == rect.size); return (left_top == rect.left_top) && (right_bottom == rect.right_bottom);
} }
inline void Set(value_type x, value_type y, value_type width, value_type height) inline void Set(value_type left, value_type top, value_type right, value_type bottom)
{ {
origin = Vec2T<value_type>{ x, y }; left_top = Vec2T<value_type>{ left, top };
size = Vec2T<value_type>{ width, height }; right_bottom = Vec2T<value_type>{ right, bottom };
} }
inline Vec2T<value_type> GetCenter() const { return Vec2T<value_type>{ origin.x + size.x / 2, origin.y + size.y / 2 }; } inline Vec2T<value_type> GetCenter() const { return Vec2T<value_type>{ (left_top.x + right_bottom.x) / 2, (left_top.y + right_bottom.y) / 2 }; }
inline Vec2T<value_type> GetLeftTop() const { return origin; } inline Vec2T<value_type> GetLeftTop() const { return left_top; }
inline Vec2T<value_type> GetRightBottom() const { return Vec2T<value_type>{ GetRight(), GetBottom() }; } inline Vec2T<value_type> GetRightBottom() const { return right_bottom; }
inline Vec2T<value_type> GetRightTop() const { return Vec2T<value_type>{ GetRight(), GetTop() }; } inline Vec2T<value_type> GetRightTop() const { return Vec2T<value_type>{ right_bottom.x, left_top.y }; }
inline Vec2T<value_type> GetLeftBottom() const { return Vec2T<value_type>{ GetLeft(), GetBottom() }; } inline Vec2T<value_type> GetLeftBottom() const { return Vec2T<value_type>{ left_top.x, right_bottom.y }; }
inline value_type GetLeft() const { return origin.x; } inline value_type GetLeft() const { return left_top.x; }
inline value_type GetTop() const { return origin.y; } inline value_type GetTop() const { return left_top.y; }
inline value_type GetRight() const { return origin.x + size.x; } inline value_type GetRight() const { return right_bottom.x; }
inline value_type GetBottom() const { return origin.y + size.y; } inline value_type GetBottom() const { return right_bottom.y; }
inline bool IsEmpty() const { return origin.IsOrigin() && size.IsOrigin(); } inline value_type GetWidth() const { return right_bottom.x - left_top.x; }
inline value_type GetHeight() const { return right_bottom.y - left_top.y; }
inline Vec2T<value_type> GetSize() const { return Vec2T<value_type>{ GetWidth(), GetHeight() }; }
inline bool IsEmpty() const { return left_top.IsOrigin() && right_bottom.IsOrigin(); }
inline bool ContainsPoint(const Vec2T<value_type>& point) const inline bool ContainsPoint(const Vec2T<value_type>& point) const
{ {
return point.x >= origin.x && point.x <= (origin.x + size.x) && return point.x >= left_top.x && point.x <= right_bottom.x &&
point.y >= origin.y && point.y <= (origin.y + size.y); point.y >= left_top.y && point.y <= right_bottom.y;
} }
inline bool Intersects(const RectT& rect) const inline bool Intersects(const RectT& rect) const
{ {
return !((origin.x + size.x) < rect.origin.x || return !(right_bottom.x < rect.left_top.x ||
(rect.origin.x + rect.size.x) < origin.x || rect.right_bottom.x < left_top.x ||
(origin.y + size.y) < rect.origin.y || right_bottom.y < rect.left_top.y ||
(rect.origin.y + rect.size.y) < origin.y); rect.right_bottom.y < left_top.y);
}
static inline RectT Infinite()
{
return RectT{ -math::constants::FLOAT_MAX, -math::constants::FLOAT_MAX, math::constants::FLOAT_MAX, math::constants::FLOAT_MAX };
} }
}; };
} }
} }
namespace kiwano
{
using Rect = kiwano::math::RectT<Float32>;
}

View File

@ -120,8 +120,3 @@ namespace kiwano
}; };
} }
} }
namespace kiwano
{
using Vec2 = kiwano::math::Vec2T<Float32>;
}

View File

@ -26,13 +26,16 @@ namespace kiwano
{ {
namespace constants namespace constants
{ {
const auto PI_F = 3.141592653589793f; constexpr auto PI_F = 3.141592653589793f;
const auto PI_F_2 = 1.570796326794896f; constexpr auto PI_F_2 = 1.570796326794896f;
const auto PI_F_X_2 = 6.283185307179586f; constexpr auto PI_F_X_2 = 6.283185307179586f;
const auto PI_D = 3.14159265358979323846; constexpr auto PI_D = 3.14159265358979323846;
const auto PI_D_2 = 1.57079632679489661923; constexpr auto PI_D_2 = 1.57079632679489661923;
const auto PI_D_X_2 = 6.28318530717958647692; constexpr auto PI_D_X_2 = 6.28318530717958647692;
constexpr auto FLOAT_MAX = 3.402823466e+38F;
constexpr auto FLOAT_MIN = 1.175494351e-38F;
} }
} }
} }

View File

@ -19,6 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "..\core\core.h"
#include "constants.hpp" #include "constants.hpp"
#include "ease.hpp" #include "ease.hpp"
#include "scalar.hpp" #include "scalar.hpp"
@ -28,6 +29,10 @@
namespace kiwano namespace kiwano
{ {
using Vec2 = kiwano::math::Vec2T<Float32>;
using Rect = kiwano::math::RectT<Float32>;
using Matrix3x2 = kiwano::math::Matrix3x2T<Float32>;
using Point = Vec2; using Point = Vec2;
using Size = Vec2; using Size = Vec2;
} }

View File

@ -22,61 +22,60 @@
#include "constants.hpp" #include "constants.hpp"
#include <cmath> #include <cmath>
namespace kiwano namespace kiwano
{ {
namespace math namespace math
{ {
inline Int32 Abs(Int32 val) { return ::abs(val); } inline Int32 Abs(Int32 val) { return ::abs(val); }
inline Float32 Abs(Float32 val) { return ::fabsf(val); } inline Float32 Abs(Float32 val) { return ::fabsf(val); }
inline Float64 Abs(Float64 val) { return ::fabs(val); } inline Float64 Abs(Float64 val) { return ::fabs(val); }
inline Float32 Sqrt(Float32 val) { return ::sqrtf(val); } inline Float32 Sqrt(Float32 val) { return ::sqrtf(val); }
inline Float64 Sqrt(Float64 val) { return ::sqrt(val); } inline Float64 Sqrt(Float64 val) { return ::sqrt(val); }
inline Float32 Pow(Float32 base, Float32 exponent) { return ::powf(base, exponent); } inline Float32 Pow(Float32 base, Float32 exponent) { return ::powf(base, exponent); }
inline Float64 Pow(Float64 base, Float64 exponent) { return ::pow(base, exponent); } inline Float64 Pow(Float64 base, Float64 exponent) { return ::pow(base, exponent); }
inline Int32 Sign(Int32 val) { return val < 0 ? -1 : 1; } inline Int32 Sign(Int32 val) { return val < 0 ? -1 : 1; }
inline Float32 Sign(Float32 val) { return val < 0 ? -1.f : 1.f; } inline Float32 Sign(Float32 val) { return val < 0 ? -1.f : 1.f; }
inline Float64 Sign(Float64 val) { return val < 0 ? -1.0 : 1.0; } inline Float64 Sign(Float64 val) { return val < 0 ? -1.0 : 1.0; }
inline Float32 Sin(Float32 val) { return ::sinf(val * constants::PI_F / 180.f); } inline Float32 Sin(Float32 val) { return ::sinf(val * constants::PI_F / 180.f); }
inline Float64 Sin(Float64 val) { return ::sin(val * constants::PI_D / 180.0); } inline Float64 Sin(Float64 val) { return ::sin(val * constants::PI_D / 180.0); }
inline Float32 Cos(Float32 val) { return ::cosf(val * constants::PI_F / 180.f); } inline Float32 Cos(Float32 val) { return ::cosf(val * constants::PI_F / 180.f); }
inline Float64 Cos(Float64 val) { return ::cos(val * constants::PI_D / 180.0); } inline Float64 Cos(Float64 val) { return ::cos(val * constants::PI_D / 180.0); }
inline Float32 Tan(Float32 val) { return ::tanf(val * constants::PI_F / 180.f); } inline Float32 Tan(Float32 val) { return ::tanf(val * constants::PI_F / 180.f); }
inline Float64 Tan(Float64 val) { return ::tan(val * constants::PI_D / 180.0); } inline Float64 Tan(Float64 val) { return ::tan(val * constants::PI_D / 180.0); }
inline Float32 Asin(Float32 val) { return ::asinf(val) * 180.f / constants::PI_F; } inline Float32 Asin(Float32 val) { return ::asinf(val) * 180.f / constants::PI_F; }
inline Float64 Asin(Float64 val) { return ::asin(val) * 180.f / constants::PI_F; } inline Float64 Asin(Float64 val) { return ::asin(val) * 180.f / constants::PI_F; }
inline Float32 Acos(Float32 val) { return ::acosf(val) * 180.f / constants::PI_F; } inline Float32 Acos(Float32 val) { return ::acosf(val) * 180.f / constants::PI_F; }
inline Float64 Acos(Float64 val) { return ::acos(val) * 180.f / constants::PI_F; } inline Float64 Acos(Float64 val) { return ::acos(val) * 180.f / constants::PI_F; }
inline Float32 Atan(Float32 val) { return ::atanf(val) * 180.f / constants::PI_F; } inline Float32 Atan(Float32 val) { return ::atanf(val) * 180.f / constants::PI_F; }
inline Float64 Atan(Float64 val) { return ::atan(val) * 180.f / constants::PI_F; } inline Float64 Atan(Float64 val) { return ::atan(val) * 180.f / constants::PI_F; }
inline Float32 Ceil(Float32 val) { return ::ceil(val); } inline Float32 Ceil(Float32 val) { return ::ceil(val); }
inline Float64 Ceil(Float64 val) { return ::ceil(val); } inline Float64 Ceil(Float64 val) { return ::ceil(val); }
inline Float32 Floor(Float32 val) { return ::floor(val); } inline Float32 Floor(Float32 val) { return ::floor(val); }
inline Float64 Floor(Float64 val) { return ::floor(val); } inline Float64 Floor(Float64 val) { return ::floor(val); }
} }
} }

View File

@ -43,13 +43,14 @@ namespace kiwano
Queue<FunctionToPerform> functions_to_perform_; Queue<FunctionToPerform> functions_to_perform_;
} }
Options::Options(String const& title, Int32 width, Int32 height, LPCWSTR icon, Color clear_color, bool vsync, bool fullscreen, bool debug) Options::Options(String const& title, Int32 width, Int32 height, UInt32 icon, Color clear_color, bool vsync, bool resizable, bool fullscreen, bool debug)
: title(title) : title(title)
, width(width) , width(width)
, height(height) , height(height)
, icon(icon) , icon(icon)
, clear_color(clear_color) , clear_color(clear_color)
, vsync(vsync) , vsync(vsync)
, resizable(resizable)
, fullscreen(fullscreen) , fullscreen(fullscreen)
, debug(debug) , debug(debug)
{} {}
@ -85,6 +86,7 @@ namespace kiwano
options.width, options.width,
options.height, options.height,
options.icon, options.icon,
options.resizable,
options.fullscreen, options.fullscreen,
Application::WndProc Application::WndProc
); );
@ -380,11 +382,11 @@ namespace kiwano
{ {
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam) if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{ {
KGE_LOG(L"Window minimized"); // KGE_LOG(L"Window minimized");
} }
else else
{ {
KGE_LOG(L"Window resized"); // KGE_LOG(L"Window resized");
Window::GetInstance()->UpdateWindowRect(); Window::GetInstance()->UpdateWindowRect();
@ -422,7 +424,7 @@ namespace kiwano
case WM_SETTEXT: case WM_SETTEXT:
{ {
KGE_LOG(L"Window title changed"); // KGE_LOG(L"Window title changed");
Event evt(Event::WindowTitleChanged); Event evt(Event::WindowTitleChanged);
evt.win.title = reinterpret_cast<const WChar*>(lparam); evt.win.title = reinterpret_cast<const WChar*>(lparam);
@ -432,21 +434,27 @@ namespace kiwano
case WM_SETICON: case WM_SETICON:
{ {
KGE_LOG(L"Window icon changed"); // KGE_LOG(L"Window icon changed");
} }
break; break;
case WM_DISPLAYCHANGE: case WM_DISPLAYCHANGE:
{ {
KGE_LOG(L"The display resolution has changed"); // KGE_LOG(L"The display resolution has changed");
::InvalidateRect(hwnd, nullptr, FALSE); ::InvalidateRect(hwnd, nullptr, FALSE);
} }
break; break;
case WM_SETCURSOR:
{
Window::GetInstance()->UpdateCursor();
}
break;
case WM_CLOSE: case WM_CLOSE:
{ {
KGE_LOG(L"Window is closing"); // KGE_LOG(L"Window is closing");
if (!app->OnClosing()) if (!app->OnClosing())
{ {

View File

@ -30,23 +30,25 @@ namespace kiwano
struct Options struct Options
{ {
String title; // 标题 String title; // 标题
Int32 width; // 宽度 Int32 width; // 宽度
Int32 height; // 高度 Int32 height; // 高度
LPCWSTR icon; // 图标 UInt32 icon; // 图标资源 ID
Color clear_color; // 清屏颜色 Color clear_color; // 清屏颜色
bool vsync; // 垂直同步 bool vsync; // 垂直同步
bool resizable; // 窗口大小可拉伸
bool fullscreen; // 全屏模式 bool fullscreen; // 全屏模式
bool debug; // 调试模式 bool debug; // 调试模式
Options( Options(
String const& title = L"Kiwano Game", String const& title = L"Kiwano Game",
Int32 width = 640, Int32 width = 640,
Int32 height = 480, Int32 height = 480,
LPCWSTR icon = nullptr, UInt32 icon = 0,
Color clear_color = Color::Black, Color clear_color = Color::Black,
bool vsync = true, bool vsync = true,
bool fullscreen = false, bool resizable = false,
bool debug = false bool fullscreen = false,
bool debug = false
); );
}; };

View File

@ -43,15 +43,15 @@ namespace kiwano
public: public:
String family; // 字体族 String family; // 字体族
Float32 size; // 字号 Float32 size; // 字号
UInt32 weight; // ´Öϸֵ UInt32 weight; // ´Öϸֵ
bool italic; // 是否斜体 bool italic; // 是否斜体
FontCollection collection; // 字体集 FontCollection collection; // 字体集
public: public:
Font( Font(
const String& family = L"", const String& family = L"",
Float32 size = 18, Float32 size = 18,
UInt32 weight = FontWeight::Normal, UInt32 weight = FontWeight::Normal,
bool italic = false, bool italic = false,
FontCollection collection = FontCollection() FontCollection collection = FontCollection()
); );

View File

@ -38,18 +38,23 @@ namespace kiwano
{ {
} }
bool Geometry::IsValid() const
{
return geo_ != nullptr;
}
Rect Geometry::GetBoundingBox(Matrix3x2 const& transform) const Rect Geometry::GetBoundingBox(Matrix3x2 const& transform) const
{ {
if (!geo_) if (!geo_)
return Rect{}; return Rect{};
D2D1_RECT_F rect; Rect rect;
// no matter it failed or not // no matter it failed or not
geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), &rect); geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&rect));
return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; return rect;
} }
Float32 Geometry::GetLength() Float32 Geometry::GetLength() const
{ {
Float32 length = 0.f; Float32 length = 0.f;
if (geo_) if (geo_)
@ -60,7 +65,7 @@ namespace kiwano
return length; return length;
} }
bool Geometry::ComputePointAtLength(Float32 length, Point& point, Vec2& tangent) bool Geometry::ComputePointAtLength(Float32 length, Point& point, Vec2& tangent) const
{ {
if (geo_) if (geo_)
{ {
@ -76,7 +81,7 @@ namespace kiwano
return false; return false;
} }
Geometry Geometry::CombineWith(Geometry input, CombineMode mode, Matrix3x2 const& input_matrix) Geometry Geometry::CombineWith(Geometry input, CombineMode mode, Matrix3x2 const& input_matrix) const
{ {
if (geo_ && input.geo_) if (geo_ && input.geo_)
{ {
@ -129,7 +134,7 @@ namespace kiwano
return Geometry(); return Geometry();
} }
Float32 Geometry::ComputeArea() Float32 Geometry::ComputeArea() const
{ {
if (!geo_) if (!geo_)
return 0.f; return 0.f;
@ -140,7 +145,7 @@ namespace kiwano
return area; return area;
} }
bool Geometry::ContainsPoint(Point const& point) bool Geometry::ContainsPoint(Point const& point, Matrix3x2 const& transform) const
{ {
if (!geo_) if (!geo_)
return false; return false;
@ -149,7 +154,7 @@ namespace kiwano
// no matter it failed or not // no matter it failed or not
geo_->FillContainsPoint( geo_->FillContainsPoint(
DX::ConvertToPoint2F(point), DX::ConvertToPoint2F(point),
D2D1::Matrix3x2F::Identity(), DX::ConvertToMatrix3x2F(transform),
&ret &ret
); );
return !!ret; return !!ret;

View File

@ -42,6 +42,8 @@ namespace kiwano
Geometry(ComPtr<ID2D1Geometry> geo); Geometry(ComPtr<ID2D1Geometry> geo);
bool IsValid() const;
// 获取外切包围盒 // 获取外切包围盒
Rect GetBoundingBox( Rect GetBoundingBox(
Matrix3x2 const& transform = Matrix3x2() Matrix3x2 const& transform = Matrix3x2()
@ -49,28 +51,29 @@ namespace kiwano
// 判断图形是否包含点 // 判断图形是否包含点
bool ContainsPoint( bool ContainsPoint(
Point const& point Point const& point,
); Matrix3x2 const& transform = Matrix3x2()
) const;
// 获取图形展开成一条直线的长度 // 获取图形展开成一条直线的长度
Float32 GetLength(); Float32 GetLength() const;
// 计算面积 // 计算面积
Float32 ComputeArea(); Float32 ComputeArea() const;
// 计算图形路径上点的位置和切线向量 // 计算图形路径上点的位置和切线向量
bool ComputePointAtLength( bool ComputePointAtLength(
Float32 length, Float32 length,
Point& point, Point& point,
Vec2& tangent Vec2& tangent
); ) const;
// 组合几何体 // 组合几何体
Geometry CombineWith( Geometry CombineWith(
Geometry input, Geometry input,
CombineMode mode, CombineMode mode,
Matrix3x2 const& input_matrix = Matrix3x2() Matrix3x2 const& input_matrix = Matrix3x2()
); ) const;
// 组合多个几何体 // 组合多个几何体
// 参数 modes 和 matrixs 的数量应为 1 或 geos 的数量减一 // 参数 modes 和 matrixs 的数量应为 1 或 geos 的数量减一
@ -114,7 +117,7 @@ namespace kiwano
inline void SetGeometry(ComPtr<ID2D1Geometry> geometry) { geo_ = geometry; } inline void SetGeometry(ComPtr<ID2D1Geometry> geometry) { geo_ = geometry; }
inline operator bool() const { return static_cast<bool>(geo_); } inline operator bool() const { return IsValid(); }
protected: protected:
ComPtr<ID2D1Geometry> geo_; ComPtr<ID2D1Geometry> geo_;

View File

@ -191,7 +191,7 @@ namespace kiwano
HRESULT GifImage::GetBackgroundColor(ComPtr<IWICMetadataQueryReader> metadata_reader) HRESULT GifImage::GetBackgroundColor(ComPtr<IWICMetadataQueryReader> metadata_reader)
{ {
BYTE bg_index = 0; UChar bg_index = 0;
WICColor bgcolors[256]; WICColor bgcolors[256];
UInt32 colors_copied = 0; UInt32 colors_copied = 0;
ComPtr<IWICPalette> wic_palette; ComPtr<IWICPalette> wic_palette;
@ -317,7 +317,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL); hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame_rect.origin.x = static_cast<Float32>(prop_val.uiVal); frame_rect.left_top.x = static_cast<Float32>(prop_val.uiVal);
} }
PropVariantClear(&prop_val); PropVariantClear(&prop_val);
} }
@ -331,7 +331,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL); hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame_rect.origin.y = static_cast<Float32>(prop_val.uiVal); frame_rect.left_top.y = static_cast<Float32>(prop_val.uiVal);
} }
PropVariantClear(&prop_val); PropVariantClear(&prop_val);
} }
@ -345,7 +345,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL); hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame_rect.size.x = static_cast<Float32>(prop_val.uiVal); frame_rect.right_bottom.x = frame_rect.left_top.x + static_cast<Float32>(prop_val.uiVal);
} }
PropVariantClear(&prop_val); PropVariantClear(&prop_val);
} }
@ -359,7 +359,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL); hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame_rect.size.y = static_cast<Float32>(prop_val.uiVal); frame_rect.right_bottom.y = frame_rect.left_top.y + static_cast<Float32>(prop_val.uiVal);
} }
PropVariantClear(&prop_val); PropVariantClear(&prop_val);
} }

View File

@ -24,6 +24,7 @@ namespace kiwano
{ {
LayerArea::LayerArea() LayerArea::LayerArea()
: opacity_(1.f) : opacity_(1.f)
, area_(Rect::Infinite())
{ {
} }

View File

@ -33,27 +33,36 @@ namespace kiwano
Size GetSize() const; Size GetSize() const;
inline Rect const& GetAreaRect() const { return area_; } inline Rect const& GetAreaRect() const { return area_; }
inline void SetAreaRect(Rect const& area) { area_ = area; }
inline Float32 GetOpacity() const { return opacity_; } inline Float32 GetOpacity() const { return opacity_; }
inline void SetOpacity(Float32 opacity) { opacity_ = opacity; } inline Geometry const& GetMaskGeometry() const { return mask_; }
inline Geometry const& GetMaskGeometry() const { return mask_; } inline Matrix3x2 const& GetMaskTransform() const { return mask_transform_; }
inline void SetMaskGeometry(Geometry const& mask) { mask_ = mask; } // <20>零暠꿔혐堵
inline void SetAreaRect(Rect const& area) { area_ = area; }
// <20>零暠꿔拷츠똑
inline void SetOpacity(Float32 opacity) { opacity_ = opacity; }
// <20>零섯부촁꿔
inline void SetMaskGeometry(Geometry const& mask) { mask_ = mask; }
// <20>零섯부촁꿔긴뻣
inline void SetMaskTransform(Matrix3x2 const& matrix) { mask_transform_ = matrix; }
public: public:
inline ComPtr<ID2D1Layer> GetLayer() const { return layer_; } inline ComPtr<ID2D1Layer> GetLayer() const { return layer_; }
inline void SetLayer(ComPtr<ID2D1Layer> layer) { layer_ = layer; } inline void SetLayer(ComPtr<ID2D1Layer> layer) { layer_ = layer; }
protected: protected:
Rect area_; Rect area_;
Float32 opacity_; Float32 opacity_;
Geometry mask_; Geometry mask_;
Matrix3x2 mask_transform_;
ComPtr<ID2D1Layer> layer_; ComPtr<ID2D1Layer> layer_;
}; };
} }

View File

@ -36,14 +36,14 @@ namespace kiwano
status_.primitives = 0; status_.primitives = 0;
} }
HRESULT RenderTarget::InitDeviceResources(ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2DDeviceResources> dev_res) HRESULT RenderTarget::CreateDeviceResources(ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2DDeviceResources> dev_res)
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
if (rt && dev_res) if (rt && dev_res)
{ {
render_target_ = rt; render_target_ = rt;
d2d_res_ = dev_res; device_resources_ = dev_res;
hr = S_OK; hr = S_OK;
} }
@ -58,20 +58,29 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_.reset(); default_brush_.reset();
hr = render_target_->CreateSolidColorBrush( hr = render_target_->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White), D2D1::ColorF(D2D1::ColorF::White),
D2D1::BrushProperties(), D2D1::BrushProperties(),
&solid_color_brush_ &default_brush_
); );
} }
return hr; return hr;
} }
void RenderTarget::DiscardDeviceResources()
{
text_renderer_.reset();
render_target_.reset();
default_brush_.reset();
current_brush_.reset();
device_resources_.reset();
}
bool RenderTarget::IsValid() const bool RenderTarget::IsValid() const
{ {
return render_target_ && d2d_res_; return render_target_ && device_resources_;
} }
void RenderTarget::BeginDraw() void RenderTarget::BeginDraw()
@ -111,20 +120,20 @@ namespace kiwano
) const ) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr) && geometry.GetGeometry()) if (SUCCEEDED(hr) && geometry.GetGeometry())
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawGeometry( render_target_->DrawGeometry(
geometry.GetGeometry().get(), geometry.GetGeometry().get(),
solid_color_brush_.get(), default_brush_.get(),
stroke_width, stroke_width,
d2d_res_->GetStrokeStyle(stroke) device_resources_->GetStrokeStyle(stroke)
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -136,17 +145,17 @@ namespace kiwano
void RenderTarget::FillGeometry(Geometry const& geometry, Color const& fill_color) const void RenderTarget::FillGeometry(Geometry const& geometry, Color const& fill_color) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr) && geometry.GetGeometry()) if (SUCCEEDED(hr) && geometry.GetGeometry())
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillGeometry( render_target_->FillGeometry(
geometry.GetGeometry().get(), geometry.GetGeometry().get(),
solid_color_brush_.get() default_brush_.get()
); );
} }
@ -156,21 +165,21 @@ namespace kiwano
void RenderTarget::DrawLine(Point const& point1, Point const& point2, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const void RenderTarget::DrawLine(Point const& point1, Point const& point2, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawLine( render_target_->DrawLine(
DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point1),
DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point2),
solid_color_brush_.get(), default_brush_.get(),
stroke_width, stroke_width,
d2d_res_->GetStrokeStyle(stroke) device_resources_->GetStrokeStyle(stroke)
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -182,20 +191,20 @@ namespace kiwano
void RenderTarget::DrawRectangle(Rect const& rect, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const void RenderTarget::DrawRectangle(Rect const& rect, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawRectangle( render_target_->DrawRectangle(
DX::ConvertToRectF(rect), DX::ConvertToRectF(rect),
solid_color_brush_.get(), default_brush_.get(),
stroke_width, stroke_width,
d2d_res_->GetStrokeStyle(stroke) device_resources_->GetStrokeStyle(stroke)
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -207,17 +216,17 @@ namespace kiwano
void RenderTarget::FillRectangle(Rect const& rect, Color const& fill_color) const void RenderTarget::FillRectangle(Rect const& rect, Color const& fill_color) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillRectangle( render_target_->FillRectangle(
DX::ConvertToRectF(rect), DX::ConvertToRectF(rect),
solid_color_brush_.get() default_brush_.get()
); );
} }
@ -227,14 +236,14 @@ namespace kiwano
void RenderTarget::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const void RenderTarget::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawRoundedRectangle( render_target_->DrawRoundedRectangle(
D2D1::RoundedRect( D2D1::RoundedRect(
@ -242,9 +251,9 @@ namespace kiwano
radius.x, radius.x,
radius.y radius.y
), ),
solid_color_brush_.get(), default_brush_.get(),
stroke_width, stroke_width,
d2d_res_->GetStrokeStyle(stroke) device_resources_->GetStrokeStyle(stroke)
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -256,21 +265,21 @@ namespace kiwano
void RenderTarget::FillRoundedRectangle(Rect const& rect, Vec2 const& radius, Color const& fill_color) const void RenderTarget::FillRoundedRectangle(Rect const& rect, Vec2 const& radius, Color const& fill_color) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillRoundedRectangle( render_target_->FillRoundedRectangle(
D2D1::RoundedRect( D2D1::RoundedRect(
DX::ConvertToRectF(rect), DX::ConvertToRectF(rect),
radius.x, radius.x,
radius.y radius.y
), ),
solid_color_brush_.get() default_brush_.get()
); );
} }
@ -280,14 +289,14 @@ namespace kiwano
void RenderTarget::DrawEllipse(Point const& center, Vec2 const& radius, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const void RenderTarget::DrawEllipse(Point const& center, Vec2 const& radius, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawEllipse( render_target_->DrawEllipse(
D2D1::Ellipse( D2D1::Ellipse(
@ -295,9 +304,9 @@ namespace kiwano
radius.x, radius.x,
radius.y radius.y
), ),
solid_color_brush_.get(), default_brush_.get(),
stroke_width, stroke_width,
d2d_res_->GetStrokeStyle(stroke) device_resources_->GetStrokeStyle(stroke)
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -309,21 +318,21 @@ namespace kiwano
void RenderTarget::FillEllipse(Point const& center, Vec2 const& radius, Color const& fill_color) const void RenderTarget::FillEllipse(Point const& center, Vec2 const& radius, Color const& fill_color) const
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_) if (!default_brush_ || !render_target_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillEllipse( render_target_->FillEllipse(
D2D1::Ellipse( D2D1::Ellipse(
DX::ConvertToPoint2F(center), DX::ConvertToPoint2F(center),
radius.x, radius.x,
radius.y radius.y
), ),
solid_color_brush_.get() default_brush_.get()
); );
} }
@ -375,7 +384,7 @@ namespace kiwano
layout.GetTextStyle().outline, layout.GetTextStyle().outline,
DX::ConvertToColorF(layout.GetTextStyle().outline_color), DX::ConvertToColorF(layout.GetTextStyle().outline_color),
layout.GetTextStyle().outline_width, layout.GetTextStyle().outline_width,
d2d_res_->GetStrokeStyle(layout.GetTextStyle().outline_stroke) device_resources_->GetStrokeStyle(layout.GetTextStyle().outline_stroke)
); );
} }
@ -447,14 +456,19 @@ namespace kiwano
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
void RenderTarget::PushLayer(LayerArea const& layer) void RenderTarget::PushLayer(LayerArea& layer)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!render_target_ || !solid_color_brush_) if (!render_target_ || !default_brush_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (!layer.IsValid())
{
CreateLayer(layer);
}
if (SUCCEEDED(hr) && layer.IsValid()) if (SUCCEEDED(hr) && layer.IsValid())
{ {
render_target_->PushLayer( render_target_->PushLayer(
@ -462,7 +476,7 @@ namespace kiwano
DX::ConvertToRectF(layer.GetAreaRect()), DX::ConvertToRectF(layer.GetAreaRect()),
layer.GetMaskGeometry().GetGeometry().get(), layer.GetMaskGeometry().GetGeometry().get(),
antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED, antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED,
D2D1::Matrix3x2F::Identity(), DX::ConvertToMatrix3x2F(layer.GetMaskTransform()),
layer.GetOpacity(), layer.GetOpacity(),
nullptr, nullptr,
D2D1_LAYER_OPTIONS_NONE D2D1_LAYER_OPTIONS_NONE
@ -521,6 +535,11 @@ namespace kiwano
return opacity_; return opacity_;
} }
Matrix3x2 RenderTarget::GetGlobalTransform() const
{
return global_matrix_;
}
void RenderTarget::SetTransform(const Matrix3x2& matrix) void RenderTarget::SetTransform(const Matrix3x2& matrix)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -531,16 +550,22 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
render_target_->SetTransform(DX::ConvertToMatrix3x2F(&matrix)); Matrix3x2 result = matrix * global_matrix_;
render_target_->SetTransform(DX::ConvertToMatrix3x2F(&result));
} }
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
void RenderTarget::SetGlobalTransform(const Matrix3x2& matrix)
{
global_matrix_ = matrix;
}
void RenderTarget::SetOpacity(Float32 opacity) void RenderTarget::SetOpacity(Float32 opacity)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!solid_color_brush_) if (!default_brush_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
@ -550,7 +575,7 @@ namespace kiwano
if (opacity_ != opacity) if (opacity_ != opacity)
{ {
opacity_ = opacity; opacity_ = opacity;
solid_color_brush_->SetOpacity(opacity); default_brush_->SetOpacity(opacity);
} }
} }
@ -611,6 +636,13 @@ namespace kiwano
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
bool RenderTarget::CheckVisibility(Rect const& bounds, Matrix3x2 const& transform)
{
return Rect{ Point{}, reinterpret_cast<const Size&>(render_target_->GetSize()) }.Intersects(
Matrix3x2(transform * global_matrix_).Transform(bounds)
);
}
void RenderTarget::SetCollectingStatus(bool collecting) void RenderTarget::SetCollectingStatus(bool collecting)
{ {
collecting_status_ = collecting; collecting_status_ = collecting;
@ -633,28 +665,29 @@ namespace kiwano
{ {
} }
void ImageRenderTarget::GetOutput(Image& output) const Image ImageRenderTarget::GetOutput() const
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt;
if (render_target_) if (render_target_)
{ {
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt;
hr = render_target_->QueryInterface<ID2D1BitmapRenderTarget>(&bitmap_rt); hr = render_target_->QueryInterface<ID2D1BitmapRenderTarget>(&bitmap_rt);
}
ComPtr<ID2D1Bitmap> bitmap; if (SUCCEEDED(hr))
if (SUCCEEDED(hr)) {
{ ComPtr<ID2D1Bitmap> bitmap;
hr = bitmap_rt->GetBitmap(&bitmap); hr = bitmap_rt->GetBitmap(&bitmap);
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
output.SetBitmap(bitmap); return Image(bitmap);
}
}
} }
ThrowIfFailed(hr); ThrowIfFailed(hr);
return Image();
} }
} }

View File

@ -33,6 +33,8 @@ namespace kiwano
: public noncopyable : public noncopyable
{ {
public: public:
bool IsValid() const;
void BeginDraw(); void BeginDraw();
void EndDraw(); void EndDraw();
@ -125,7 +127,7 @@ namespace kiwano
void PopClipRect(); void PopClipRect();
void PushLayer( void PushLayer(
LayerArea const& layer LayerArea& layer
); );
void PopLayer(); void PopLayer();
@ -138,6 +140,8 @@ namespace kiwano
Float32 GetOpacity() const; Float32 GetOpacity() const;
Matrix3x2 GetGlobalTransform() const;
void SetOpacity( void SetOpacity(
Float32 opacity Float32 opacity
); );
@ -146,6 +150,10 @@ namespace kiwano
const Matrix3x2& matrix const Matrix3x2& matrix
); );
void SetGlobalTransform(
const Matrix3x2& matrix
);
// ÉèÖÿ¹¾â³Ýģʽ // ÉèÖÿ¹¾â³Ýģʽ
void SetAntialiasMode( void SetAntialiasMode(
bool enabled bool enabled
@ -156,6 +164,11 @@ namespace kiwano
TextAntialias mode TextAntialias mode
); );
bool CheckVisibility(
Rect const& bounds,
Matrix3x2 const& transform
);
public: public:
struct Status struct Status
{ {
@ -170,17 +183,19 @@ namespace kiwano
inline Status const& GetStatus() const { return status_; } inline Status const& GetStatus() const { return status_; }
inline ComPtr<ID2D1RenderTarget> GetRenderTarget() const { return render_target_; } inline ComPtr<ID2D1RenderTarget> GetRenderTarget() const { KGE_ASSERT(render_target_); return render_target_; }
inline ComPtr<ITextRenderer> GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_; }
public: public:
RenderTarget(); RenderTarget();
HRESULT InitDeviceResources( HRESULT CreateDeviceResources(
ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2D1RenderTarget> rt,
ComPtr<ID2DDeviceResources> dev_res ComPtr<ID2DDeviceResources> dev_res
); );
bool IsValid() const; void DiscardDeviceResources();
protected: protected:
Float32 opacity_; Float32 opacity_;
@ -188,10 +203,12 @@ namespace kiwano
mutable bool collecting_status_; mutable bool collecting_status_;
mutable Status status_; mutable Status status_;
TextAntialias text_antialias_; TextAntialias text_antialias_;
ComPtr<ID2D1RenderTarget> render_target_;
ComPtr<ITextRenderer> text_renderer_; ComPtr<ITextRenderer> text_renderer_;
ComPtr<ID2D1SolidColorBrush> solid_color_brush_; ComPtr<ID2D1RenderTarget> render_target_;
ComPtr<ID2DDeviceResources> d2d_res_; ComPtr<ID2D1SolidColorBrush> default_brush_;
ComPtr<ID2D1Brush> current_brush_;
ComPtr<ID2DDeviceResources> device_resources_;
Matrix3x2 global_matrix_;
}; };
@ -202,6 +219,6 @@ namespace kiwano
public: public:
ImageRenderTarget(); ImageRenderTarget();
void GetOutput(Image& output) const; Image GetOutput() const;
}; };
} }

View File

@ -29,6 +29,7 @@ namespace kiwano
: hwnd_(nullptr) : hwnd_(nullptr)
, vsync_(true) , vsync_(true)
, clear_color_(Color::Black) , clear_color_(Color::Black)
, resolution_mode_(ResolutionMode::Fixed)
{ {
} }
@ -41,7 +42,7 @@ namespace kiwano
KGE_LOG(L"Creating device resources"); KGE_LOG(L"Creating device resources");
hwnd_ = Window::GetInstance()->GetHandle(); hwnd_ = Window::GetInstance()->GetHandle();
output_size_ = Window::GetInstance()->GetSize(); resolution_ = output_size_ = Window::GetInstance()->GetSize();
d2d_res_ = nullptr; d2d_res_ = nullptr;
d3d_res_ = nullptr; d3d_res_ = nullptr;
@ -126,6 +127,8 @@ namespace kiwano
{ {
KGE_LOG(L"Destroying device resources"); KGE_LOG(L"Destroying device resources");
RenderTarget::DiscardDeviceResources();
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get()); d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get());
res_font_file_loader_.reset(); res_font_file_loader_.reset();
@ -133,7 +136,6 @@ namespace kiwano
res_font_collection_loader_.reset(); res_font_collection_loader_.reset();
drawing_state_block_.reset(); drawing_state_block_.reset();
solid_color_brush_.reset();
d2d_res_.reset(); d2d_res_.reset();
d3d_res_.reset(); d3d_res_.reset();
} }
@ -158,6 +160,12 @@ namespace kiwano
hr = d3d_res_->ClearRenderTarget(clear_color_); hr = d3d_res_->ClearRenderTarget(clear_color_);
} }
if (SUCCEEDED(hr))
{
SetTransform(Matrix3x2{});
PushClipRect(Rect{ Point{}, resolution_ });
}
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
@ -170,8 +178,11 @@ namespace kiwano
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
PopClipRect();
EndDraw(); EndDraw();
render_target_->RestoreDrawingState(drawing_state_block_.get()); render_target_->RestoreDrawingState(drawing_state_block_.get());
@ -200,7 +211,7 @@ namespace kiwano
UInt32 width = LOWORD(lparam); UInt32 width = LOWORD(lparam);
UInt32 height = HIWORD(lparam); UInt32 height = HIWORD(lparam);
Resize(width, height); ResizeTarget(width, height);
break; break;
} }
} }
@ -208,7 +219,9 @@ namespace kiwano
HRESULT Renderer::CreateDeviceResources() HRESULT Renderer::CreateDeviceResources()
{ {
HRESULT hr = InitDeviceResources( KGE_ASSERT(d2d_res_);
HRESULT hr = RenderTarget::CreateDeviceResources(
d2d_res_->GetDeviceContext(), d2d_res_->GetDeviceContext(),
d2d_res_ d2d_res_
); );
@ -656,7 +669,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = render_target.InitDeviceResources(output, d2d_res_); hr = render_target.CreateDeviceResources(output, d2d_res_);
} }
ThrowIfFailed(hr); ThrowIfFailed(hr);
@ -667,7 +680,30 @@ namespace kiwano
vsync_ = enabled; vsync_ = enabled;
} }
void Renderer::Resize(UInt32 width, UInt32 height) void Renderer::SetResolution(Size const& resolution)
{
if (resolution_ != resolution)
{
resolution_ = resolution;
UpdateResolution();
}
}
void Renderer::SetResolutionMode(ResolutionMode mode)
{
if (resolution_mode_ != mode)
{
resolution_mode_ = mode;
UpdateResolution();
}
}
void Renderer::SetClearColor(const Color& color)
{
clear_color_ = color;
}
void Renderer::ResizeTarget(UInt32 width, UInt32 height)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!d3d_res_) if (!d3d_res_)
@ -682,19 +718,58 @@ namespace kiwano
hr = d3d_res_->SetLogicalSize(output_size_); hr = d3d_res_->SetLogicalSize(output_size_);
} }
if (SUCCEEDED(hr))
{
UpdateResolution();
}
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
void Renderer::SetClearColor(const Color& color) void Renderer::UpdateResolution()
{ {
clear_color_ = color; switch (resolution_mode_)
} {
case ResolutionMode::Fixed:
{
SetGlobalTransform(Matrix3x2{});
break;
}
bool Renderer::CheckVisibility(Size const& content_size, Matrix3x2 const& transform) case ResolutionMode::Center:
{ {
return Rect{ Point{}, output_size_ }.Intersects( Float32 left = math::Ceil((output_size_.x - resolution_.x) / 2);
transform.Transform(Rect{ Point{}, content_size }) Float32 top = math::Ceil((output_size_.y - resolution_.y) / 2);
); SetGlobalTransform(Matrix3x2::Translation(Vec2{ left, top }));
break;
}
case ResolutionMode::Stretch:
{
Float32 scalex = Float32(Int32((output_size_.x / resolution_.x) * 100 + 0.5f)) / 100;
Float32 scaley = Float32(Int32((output_size_.y / resolution_.y) * 100 + 0.5f)) / 100;
SetGlobalTransform(Matrix3x2::Scaling(Vec2{ scalex, scaley }));
break;
}
case ResolutionMode::Adaptive:
{
Float32 scalex = Float32(Int32((output_size_.x / resolution_.x) * 100 + 0.5f)) / 100;
Float32 scaley = Float32(Int32((output_size_.y / resolution_.y) * 100 + 0.5f)) / 100;
if (scalex > scaley)
{
Float32 left = math::Ceil((output_size_.x - resolution_.x * scaley) / 2);
SetGlobalTransform(Matrix3x2::SRT(Vec2{ left, 0 }, Vec2{ scaley, scaley }, 0));
}
else
{
Float32 top = math::Ceil((output_size_.y - resolution_.y * scalex) / 2);
SetGlobalTransform(Matrix3x2::SRT(Vec2{ 0, top }, Vec2{ scalex, scalex }, 0));
}
break;
}
}
} }
} }

View File

@ -131,14 +131,12 @@ namespace kiwano
ImageRenderTarget& render_target ImageRenderTarget& render_target
); );
void Resize( void SetResolution(
UInt32 width, Size const& resolution
UInt32 height
); );
bool CheckVisibility( void SetResolutionMode(
Size const& content_size, ResolutionMode mode
Matrix3x2 const& transform
); );
public: public:
@ -157,14 +155,14 @@ namespace kiwano
inline Size const& GetOutputSize() const { return output_size_; } inline Size const& GetOutputSize() const { return output_size_; }
inline Size const& GetResolution() const { return resolution_; }
inline Color const& GetClearColor() const { return clear_color_; }
inline ID2DDeviceResources* GetD2DDeviceResources() const { KGE_ASSERT(d2d_res_); return d2d_res_.get(); } inline ID2DDeviceResources* GetD2DDeviceResources() const { KGE_ASSERT(d2d_res_); return d2d_res_.get(); }
inline ID3DDeviceResources* GetD3DDeviceResources() const { KGE_ASSERT(d3d_res_); return d3d_res_.get(); } inline ID3DDeviceResources* GetD3DDeviceResources() const { KGE_ASSERT(d3d_res_); return d3d_res_.get(); }
inline ITextRenderer* GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_.get(); }
inline ID2D1SolidColorBrush* GetSolidColorBrush() const { KGE_ASSERT(solid_color_brush_); return solid_color_brush_.get(); }
private: private:
Renderer(); Renderer();
@ -174,11 +172,17 @@ namespace kiwano
HRESULT HandleDeviceLost(); HRESULT HandleDeviceLost();
void ResizeTarget(UInt32 width, UInt32 height);
void UpdateResolution();
private: private:
bool vsync_; bool vsync_;
HWND hwnd_; HWND hwnd_;
Size output_size_; Color clear_color_;
Color clear_color_; Size output_size_;
Size resolution_;
ResolutionMode resolution_mode_;
ComPtr<ID2DDeviceResources> d2d_res_; ComPtr<ID2DDeviceResources> d2d_res_;
ComPtr<ID3DDeviceResources> d3d_res_; ComPtr<ID3DDeviceResources> d3d_res_;

View File

@ -101,16 +101,31 @@ namespace kiwano
} }
// //
// SizeF // RectF
// //
inline D2D1_RECT_F ConvertToRectF(Rect const& rect) inline D2D1_RECT_F const& ConvertToRectF(Rect const& rect)
{ {
return D2D1_RECT_F{ rect.origin.x, rect.origin.y, rect.origin.x + rect.size.x, rect.origin.y + rect.size.y }; return reinterpret_cast<D2D1_RECT_F const&>(rect);
}
inline D2D1_RECT_F& ConvertToRectF(Rect& rect)
{
return reinterpret_cast<D2D1_RECT_F&>(rect);
}
inline const D2D1_RECT_F* ConvertToRectF(const Rect* rect)
{
return reinterpret_cast<const D2D1_RECT_F*>(rect);
}
inline D2D1_RECT_F* ConvertToRectF(Rect* rect)
{
return reinterpret_cast<D2D1_RECT_F*>(rect);
} }
// //
// SizeF // ColorF
// //
inline D2D1_COLOR_F const& ConvertToColorF(Color const& color) inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
{ {
@ -133,7 +148,7 @@ namespace kiwano
} }
// //
// SizeF // MatrixF
// //
inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix) inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix)

View File

@ -948,7 +948,7 @@ namespace kiwano
if (fileOffset <= resourceSize_ && if (fileOffset <= resourceSize_ &&
fragmentSize <= resourceSize_ - fileOffset) fragmentSize <= resourceSize_ - fileOffset)
{ {
*fragmentStart = static_cast<BYTE const*>(resourcePtr_) + static_cast<UInt32>(fileOffset); *fragmentStart = static_cast<Byte const*>(resourcePtr_) + static_cast<UInt32>(fileOffset);
*fragmentContext = NULL; *fragmentContext = NULL;
return S_OK; return S_OK;
} }

View File

@ -119,7 +119,7 @@ namespace kiwano
{ {
ifs.open(file_path.c_str()); ifs.open(file_path.c_str());
std::wstringstream ss; StringStream ss;
ss << ifs.rdbuf(); ss << ifs.rdbuf();
if (tinyxml2::XML_SUCCESS != doc.Parse(ss.str().c_str())) if (tinyxml2::XML_SUCCESS != doc.Parse(ss.str().c_str()))
@ -248,7 +248,7 @@ namespace kiwano
FramePtr ptr = new (std::nothrow) Frame(raw->GetImage()); FramePtr ptr = new (std::nothrow) Frame(raw->GetImage());
if (ptr) if (ptr)
{ {
ptr->SetCropRect(Rect{ j * width, i * height, width, height }); ptr->SetCropRect(Rect{ j * width, i * height, (j + 1) * width, (i + 1) * height });
image_arr.push_back(ptr); image_arr.push_back(ptr);
} }
} }