Skip to content

Commit b4e3bb8

Browse files
authored
Merge pull request #104 from BAKAOLC/feat/video-texture
feat: 添加视频纹理支持及相关功能
2 parents affde76 + 69d13bd commit b4e3bb8

30 files changed

Lines changed: 2778 additions & 5 deletions

LuaSTG/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ set(LUASTG_ENGINE_SOURCES
144144
LuaSTG/LuaBinding/modern/SwapChain.cpp
145145
LuaSTG/LuaBinding/modern/Texture2D.hpp
146146
LuaSTG/LuaBinding/modern/Texture2D.cpp
147+
LuaSTG/LuaBinding/modern/Video.hpp
148+
LuaSTG/LuaBinding/modern/Video.cpp
149+
LuaSTG/LuaBinding/VideoBindingHelpers.hpp
150+
LuaSTG/LuaBinding/VideoBindingHelpers.cpp
147151
LuaSTG/LuaBinding/modern/RenderTarget.hpp
148152
LuaSTG/LuaBinding/modern/RenderTarget.cpp
149153
LuaSTG/LuaBinding/modern/DepthStencilBuffer.hpp

LuaSTG/LuaSTG/GameResource/Implement/ResourceTextureImpl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace luastg
2121
core::IRenderTarget* GetRenderTarget() { return m_rt.get(); }
2222
core::IDepthStencilBuffer* GetDepthStencilBuffer() { return m_ds.get(); }
2323
bool IsRenderTarget() { return m_is_rendertarget; }
24+
bool IsVideoTexture() { return m_texture && m_texture->isVideoTexture(); }
2425
bool HasDepthStencilBuffer() { return m_enable_depthbuffer; }
2526
public:
2627
// 纹理容器
@@ -47,6 +48,7 @@ namespace luastg
4748
core::IRenderTarget* GetRenderTarget() override { return m_rt.get(); }
4849
core::IDepthStencilBuffer* GetDepthStencilBuffer() override { return m_ds.get(); }
4950
bool IsRenderTarget() override { return true; }
51+
bool IsVideoTexture() override { return false; }
5052
bool HasDepthStencilBuffer() override { return !!m_ds; }
5153

5254
// RenderTargetStackResourceTextureImpl

LuaSTG/LuaSTG/GameResource/ResourceDebug.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,21 @@ namespace luastg
8181
};
8282
auto draw_texture = [](IResourceTexture* p_res, bool show_info, float scale) -> void
8383
{
84-
auto const size = p_res->GetTexture()->getSize();
84+
auto* p_tex = p_res->GetTexture();
85+
auto const size = p_tex->getSize();
8586
if (show_info)
8687
{
8788
ImGui::Text("Size: %u x %u", size.x, size.y);
88-
ImGui::Text("RenderTarget: %s", p_res->IsRenderTarget() ? "Yes" : "Not");
89-
ImGui::Text("Dynamic: %s", p_res->IsRenderTarget() ? "Yes" : "Not");
90-
unsigned long long mem_usage = size.x * size.y * 4;
89+
char const* type_str = p_tex->isVideoTexture() ? "Video" : (p_res->IsRenderTarget() ? "RenderTarget" : "Texture");
90+
ImGui::Text("Type: %s", type_str);
91+
ImGui::Text("Dynamic: %s", p_tex->isDynamic() ? "Yes" : "Not");
92+
unsigned long long display_mem = (unsigned long long)size.x * size.y * 4;
93+
unsigned long long mem_usage = display_mem;
9194
ImGui::Text("Adapter Memory Usage (Approximate): %s", bytes_count_to_string(mem_usage).c_str());
9295
}
9396
ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, 1.0);
9497
ImGui::Image(
95-
reinterpret_cast<size_t>(p_res->GetTexture()->getNativeView()),
98+
reinterpret_cast<size_t>(p_tex->getNativeView()),
9699
ImVec2(scale * (float)size.x, scale * (float)size.y),
97100
ImVec2(0.0f, 0.0f),
98101
ImVec2(1.0f, 1.0f));

LuaSTG/LuaSTG/GameResource/ResourceManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include "core/SmartReference.hpp"
3+
#include "core/VideoDecoder.hpp"
34
#include "GameResource/ResourceTexture.hpp"
45
#include "GameResource/ResourceSprite.hpp"
56
#include "GameResource/ResourceAnimation.hpp"
@@ -98,6 +99,8 @@ namespace luastg
9899
// 纹理
99100
bool LoadTexture(const char* name, const char* path, bool mipmaps = true) noexcept;
100101
bool CreateTexture(const char* name, int width, int height) noexcept;
102+
// 视频纹理(options 为 nullptr 时使用默认选项)
103+
bool LoadVideo(const char* name, const char* path, core::VideoOpenOptions const* options = nullptr) noexcept;
101104
// 渲染目标
102105
bool CreateRenderTarget(const char* name, int width = 0, int height = 0, bool depth_buffer = false) noexcept;
103106
// 图片精灵

LuaSTG/LuaSTG/GameResource/ResourcePool.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "GameResource/Implement/ResourcePostEffectShaderImpl.hpp"
1010
#include "GameResource/Implement/ResourceModelImpl.hpp"
1111
#include "core/FileSystem.hpp"
12+
#include "core/AudioEngine.hpp"
1213
#include "AppFrame.h"
1314
#include "lua/plus.hpp"
1415

@@ -227,6 +228,47 @@ namespace luastg
227228
return true;
228229
}
229230

231+
bool ResourcePool::LoadVideo(const char* name, const char* path, core::VideoOpenOptions const* options) noexcept
232+
{
233+
if (m_TexturePool.find(std::string_view(name)) != m_TexturePool.end())
234+
{
235+
if (ResourceMgr::GetResourceLoadingLog())
236+
{
237+
spdlog::warn("[luastg] LoadVideo: 纹理 '{}' 已存在,加载操作已取消", name);
238+
}
239+
return true;
240+
}
241+
242+
core::SmartReference<core::ITexture2D> p_texture;
243+
bool ok = options
244+
? LAPP.getGraphicsDevice()->createVideoTexture(path, *options, p_texture.put())
245+
: LAPP.getGraphicsDevice()->createVideoTexture(path, p_texture.put());
246+
if (!ok)
247+
{
248+
spdlog::error("[luastg] 从 '{}' 创建视频纹理 '{}' 失败", path, name);
249+
return false;
250+
}
251+
252+
try
253+
{
254+
core::SmartReference<IResourceTexture> tRes;
255+
tRes.attach(new ResourceTextureImpl(name, p_texture.get()));
256+
m_TexturePool.emplace(name, tRes);
257+
}
258+
catch (std::exception const& e)
259+
{
260+
spdlog::error("[luastg] LoadVideo: 创建视频纹理 '{}' 失败 ({})", name, e.what());
261+
return false;
262+
}
263+
264+
if (ResourceMgr::GetResourceLoadingLog())
265+
{
266+
spdlog::info("[luastg] LoadVideo: 已从 '{}' 加载视频 '{}' ({})", path, name, getResourcePoolTypeName());
267+
}
268+
269+
return true;
270+
}
271+
230272
bool ResourcePool::CreateTexture(const char* name, int width, int height) noexcept
231273
{
232274
if (m_TexturePool.find(std::string_view(name)) != m_TexturePool.end())

LuaSTG/LuaSTG/GameResource/ResourceTexture.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace luastg
1212
virtual core::IRenderTarget* GetRenderTarget() = 0;
1313
virtual core::IDepthStencilBuffer* GetDepthStencilBuffer() = 0;
1414
virtual bool IsRenderTarget() = 0;
15+
virtual bool IsVideoTexture() = 0;
1516
virtual bool HasDepthStencilBuffer() = 0;
1617
};
1718
};

LuaSTG/LuaSTG/LuaBinding/LW_ResourceMgr.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "LuaBinding/LuaWrapper.hpp"
2+
#include "LuaBinding/VideoBindingHelpers.hpp"
23
#include "lua/plus.hpp"
34
#include "AppFrame.h"
5+
#include "d3d11/VideoTexture.hpp"
6+
#include "core/VideoDecoder.hpp"
47

58
void luastg::binding::ResourceManager::Register(lua_State* L) noexcept
69
{
@@ -52,6 +55,25 @@ void luastg::binding::ResourceManager::Register(lua_State* L) noexcept
5255
return luaL_error(L, "can't load texture from file '%s'.", path);
5356
return 0;
5457
}
58+
static int LoadVideo(lua_State* L) noexcept
59+
{
60+
lua::stack_t const ctx(L);
61+
const char* name = luaL_checkstring(L, 1);
62+
const char* path = luaL_checkstring(L, 2);
63+
64+
ResourcePool* pActivedPool = LRES.GetActivedPool();
65+
if (!pActivedPool)
66+
return luaL_error(L, "can't load resource at this time.");
67+
68+
core::VideoOpenOptions opt;
69+
bool const has_options = ctx.index_of_top() >= 3 && ctx.is_table(3);
70+
if (has_options)
71+
video::parseVideoOptions(L, 3, opt);
72+
73+
if (!pActivedPool->LoadVideo(name, path, has_options ? &opt : nullptr))
74+
return luaL_error(L, "can't load video from file '%s'.", path);
75+
return 0;
76+
}
5577
static int LoadSprite(lua_State* L) noexcept
5678
{
5779
const char* name = luaL_checkstring(L, 1);
@@ -414,6 +436,14 @@ void luastg::binding::ResourceManager::Register(lua_State* L) noexcept
414436
lua_pushboolean(L, p->IsRenderTarget());
415437
return 1;
416438
}
439+
static int IsVideoTexture(lua_State* L) noexcept
440+
{
441+
core::SmartReference<IResourceTexture> p = LRES.FindTexture(luaL_checkstring(L, 1));
442+
if (!p)
443+
return luaL_error(L, "texture '%s' not found.", luaL_checkstring(L, 1));
444+
lua_pushboolean(L, p->IsVideoTexture());
445+
return 1;
446+
}
417447
static int SetTexturePreMulAlphaState(lua_State* L) noexcept
418448
{
419449
core::SmartReference<IResourceTexture> p = LRES.FindTexture(luaL_checkstring(L, 1));
@@ -696,13 +726,106 @@ void luastg::binding::ResourceManager::Register(lua_State* L) noexcept
696726
LRES.CacheTTFFontString(luaL_checkstring(L, 1), str, len);
697727
return 0;
698728
}
729+
730+
// Video control functions
731+
732+
static int VideoSeek(lua_State* L) noexcept {
733+
lua::stack_t const ctx(L);
734+
const char* name = luaL_checkstring(L, 1);
735+
double time = luaL_checknumber(L, 2);
736+
auto decoder = video::getDecoderFromResourceName(name);
737+
if (!decoder)
738+
return luaL_error(L, "video texture '%s' not found or is not a video texture.", name);
739+
bool ok = decoder->seek(time);
740+
ctx.push_value(ok);
741+
return 1;
742+
}
743+
744+
static int VideoSetLooping(lua_State* L) noexcept {
745+
lua::stack_t const ctx(L);
746+
const char* name = luaL_checkstring(L, 1);
747+
bool loop = ctx.get_value<bool>(2);
748+
auto decoder = video::getDecoderFromResourceName(name);
749+
if (!decoder)
750+
return luaL_error(L, "video texture '%s' not found.", name);
751+
decoder->setLooping(loop);
752+
return 0;
753+
}
754+
755+
static int VideoSetLoopRange(lua_State* L) noexcept {
756+
const char* name = luaL_checkstring(L, 1);
757+
auto decoder = video::getDecoderFromResourceName(name);
758+
if (!decoder)
759+
return luaL_error(L, "video texture '%s' not found.", name);
760+
double loop_end = luaL_checknumber(L, 2);
761+
double loop_duration = luaL_checknumber(L, 3);
762+
decoder->setLoopRange(loop_end, loop_duration);
763+
return 0;
764+
}
765+
766+
static int VideoUpdate(lua_State* L) noexcept {
767+
lua::stack_t const ctx(L);
768+
const char* name = luaL_checkstring(L, 1);
769+
double time = luaL_checknumber(L, 2);
770+
auto decoder = video::getDecoderFromResourceName(name);
771+
if (!decoder)
772+
return luaL_error(L, "video texture '%s' not found or is not a video texture.", name);
773+
bool ok = decoder->updateToTime(time);
774+
ctx.push_value(ok);
775+
return 1;
776+
}
777+
778+
static int VideoGetInfo(lua_State* L) noexcept {
779+
const char* name = luaL_checkstring(L, 1);
780+
auto decoder = video::getDecoderFromResourceName(name);
781+
if (!decoder)
782+
return luaL_error(L, "video texture '%s' not found.", name);
783+
video::pushVideoInfoToLua(L, decoder);
784+
return 1;
785+
}
786+
787+
static int VideoGetVideoStreams(lua_State* L) noexcept {
788+
const char* name = luaL_checkstring(L, 1);
789+
auto decoder = video::getDecoderFromResourceName(name);
790+
if (!decoder)
791+
return luaL_error(L, "video texture '%s' not found.", name);
792+
video::pushVideoStreamsToLua(L, decoder);
793+
return 1;
794+
}
795+
796+
static int VideoGetAudioStreams(lua_State* L) noexcept {
797+
const char* name = luaL_checkstring(L, 1);
798+
auto decoder = video::getDecoderFromResourceName(name);
799+
if (!decoder)
800+
return luaL_error(L, "video texture '%s' not found.", name);
801+
video::pushAudioStreamsToLua(L, decoder);
802+
return 1;
803+
}
804+
805+
static int VideoReopen(lua_State* L) noexcept {
806+
lua::stack_t const ctx(L);
807+
const char* name = luaL_checkstring(L, 1);
808+
auto decoder = video::getDecoderFromResourceName(name);
809+
if (!decoder)
810+
return luaL_error(L, "video texture '%s' not found or is not a video texture.", name);
811+
core::VideoOpenOptions opt = decoder->getLastOpenOptions();
812+
if (ctx.index_of_top() >= 2 && ctx.is_table(2))
813+
video::parseVideoOptions(L, 2, opt);
814+
if (!decoder->reopen(opt)) {
815+
ctx.push_value(false);
816+
return 1;
817+
}
818+
ctx.push_value(true);
819+
return 1;
820+
}
699821
};
700822

701823
luaL_Reg const lib[] = {
702824
{ "SetResLoadInfo", &Wrapper::SetResLoadInfo },
703825
{ "SetResourceStatus", &Wrapper::SetResourceStatus },
704826
{ "GetResourceStatus", &Wrapper::GetResourceStatus },
705827
{ "LoadTexture", &Wrapper::LoadTexture },
828+
{ "LoadVideo", &Wrapper::LoadVideo },
706829
{ "LoadImage", &Wrapper::LoadSprite },
707830
{ "CopyImage", &Wrapper::CopySprite },
708831
{ "LoadAnimation", &Wrapper::LoadAnimation },
@@ -716,6 +839,7 @@ void luastg::binding::ResourceManager::Register(lua_State* L) noexcept
716839
{ "LoadModel", &Wrapper::LoadModel },
717840
{ "CreateRenderTarget", &Wrapper::CreateRenderTarget },
718841
{ "IsRenderTarget", &Wrapper::IsRenderTarget },
842+
{ "IsVideoTexture", &Wrapper::IsVideoTexture },
719843
{ "SetTexturePreMulAlphaState", &Wrapper::SetTexturePreMulAlphaState },
720844
{ "SetTextureSamplerState", &Wrapper::SetTextureSamplerState },
721845
{ "GetTextureSize", &Wrapper::GetTextureSize },
@@ -737,6 +861,17 @@ void luastg::binding::ResourceManager::Register(lua_State* L) noexcept
737861
{ "SetFontState", &Wrapper::SetFontState },
738862

739863
{ "CacheTTFString", &Wrapper::CacheTTFString },
864+
865+
// Video control functions
866+
{ "VideoSeek", &Wrapper::VideoSeek },
867+
{ "VideoSetLooping", &Wrapper::VideoSetLooping },
868+
{ "VideoSetLoopRange", &Wrapper::VideoSetLoopRange },
869+
{ "VideoUpdate", &Wrapper::VideoUpdate },
870+
{ "VideoGetInfo", &Wrapper::VideoGetInfo },
871+
{ "VideoGetVideoStreams", &Wrapper::VideoGetVideoStreams },
872+
{ "VideoGetAudioStreams", &Wrapper::VideoGetAudioStreams },
873+
{ "VideoReopen", &Wrapper::VideoReopen },
874+
740875
{ NULL, NULL },
741876
};
742877

LuaSTG/LuaSTG/LuaBinding/LuaWrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "LuaBinding/modern/Window.hpp"
88
#include "LuaBinding/modern/SwapChain.hpp"
99
#include "LuaBinding/modern/Texture2D.hpp"
10+
#include "LuaBinding/modern/Video.hpp"
1011
#include "LuaBinding/modern/RenderTarget.hpp"
1112
#include "LuaBinding/modern/DepthStencilBuffer.hpp"
1213
#include "LuaBinding/modern/Mesh.hpp"
@@ -82,6 +83,7 @@ namespace luastg::binding
8283
Window_Windows11Extension::registerClass(L);
8384
SwapChain::registerClass(L);
8485
Texture2D::registerClass(L);
86+
Video::registerClass(L);
8587
RenderTarget::registerClass(L);
8688
DepthStencilBuffer::registerClass(L);
8789
Mesh::registerClass(L);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "VideoBindingHelpers.hpp"
2+
#include "AppFrame.h"
3+
4+
namespace luastg::binding::video {
5+
core::IVideoDecoder* getDecoderFromResourceName(const char* name) noexcept {
6+
auto texture = LRES.FindTexture(name);
7+
if (!texture) {
8+
return nullptr;
9+
}
10+
11+
auto texture2d = texture->GetTexture();
12+
if (!texture2d) {
13+
return nullptr;
14+
}
15+
16+
return getDecoderFromTexture(texture2d);
17+
}
18+
}

0 commit comments

Comments
 (0)