forked from mirror/openmw-tes3mp
Refactored video player (now a MyGUI widget)
This commit is contained in:
parent
2e4ef93b28
commit
5906d795c0
19 changed files with 242 additions and 203 deletions
|
@ -33,7 +33,7 @@ add_openmw_dir (mwgui
|
|||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
|
||||
recharge mode
|
||||
recharge mode videowidget
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
|
|
@ -456,7 +456,7 @@ void OMW::Engine::go()
|
|||
// TODO: there are other intro videos, too. They need to be imported from Morrowind.ini.
|
||||
// Unfortunately those must play BEFORE any loading is done, which will currently not work.
|
||||
// The videoplayer is created by World, so all content files must be loaded first...
|
||||
MWBase::Environment::get().getWorld()->playVideo("mw_logo.bik", true);
|
||||
MWBase::Environment::get().getWindowManager()->playVideo("mw_logo.bik", true);
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,10 @@ namespace MWBase
|
|||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/// @note This method will block until the video finishes playing
|
||||
/// (and will continually update the window while doing so)
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
|
||||
|
||||
virtual void setNewGame(bool newgame) = 0;
|
||||
|
||||
virtual void pushGuiMode (MWGui::GuiMode mode) = 0;
|
||||
|
|
|
@ -420,8 +420,6 @@ namespace MWBase
|
|||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
|
||||
|
||||
/// \todo this does not belong here
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
|
||||
virtual void stopVideo() = 0;
|
||||
virtual void frameStarted (float dt, bool paused) = 0;
|
||||
virtual void screenshot (Ogre::Image& image, int w, int h) = 0;
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace MWGui
|
|||
else if (name == "options")
|
||||
MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings);
|
||||
else if (name == "credits")
|
||||
MWBase::Environment::get().getWorld()->playVideo("mw_credits.bik", true);
|
||||
MWBase::Environment::get().getWindowManager()->playVideo("mw_credits.bik", true);
|
||||
else if (name == "exitgame")
|
||||
{
|
||||
if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame)
|
||||
|
|
|
@ -47,9 +47,7 @@ namespace MWGui
|
|||
GM_Loading,
|
||||
GM_LoadingWallpaper,
|
||||
|
||||
GM_QuickKeysMenu,
|
||||
|
||||
GM_Video
|
||||
GM_QuickKeysMenu
|
||||
};
|
||||
|
||||
// Windows shown in inventory mode
|
||||
|
|
45
apps/openmw/mwgui/videowidget.cpp
Normal file
45
apps/openmw/mwgui/videowidget.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "videowidget.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
VideoWidget::VideoWidget()
|
||||
: mAllowSkipping(true)
|
||||
{
|
||||
eventKeyButtonPressed += MyGUI::newDelegate(this, &VideoWidget::onKeyPressed);
|
||||
|
||||
setNeedKeyFocus(true);
|
||||
}
|
||||
|
||||
void VideoWidget::playVideo(const std::string &video, bool allowSkipping)
|
||||
{
|
||||
mAllowSkipping = allowSkipping;
|
||||
|
||||
mPlayer.playVideo(video);
|
||||
|
||||
setImageTexture(mPlayer.getTextureName());
|
||||
}
|
||||
|
||||
int VideoWidget::getVideoWidth()
|
||||
{
|
||||
return mPlayer.getVideoWidth();
|
||||
}
|
||||
|
||||
int VideoWidget::getVideoHeight()
|
||||
{
|
||||
return mPlayer.getVideoHeight();
|
||||
}
|
||||
|
||||
void VideoWidget::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
||||
{
|
||||
if (_key == MyGUI::KeyCode::Escape && mAllowSkipping)
|
||||
mPlayer.stopVideo();
|
||||
}
|
||||
|
||||
bool VideoWidget::update()
|
||||
{
|
||||
mPlayer.update();
|
||||
return mPlayer.isPlaying();
|
||||
}
|
||||
|
||||
}
|
39
apps/openmw/mwgui/videowidget.hpp
Normal file
39
apps/openmw/mwgui/videowidget.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef OPENMW_MWGUI_VIDEOWIDGET_H
|
||||
#define OPENMW_MWGUI_VIDEOWIDGET_H
|
||||
|
||||
#include <MyGUI_ImageBox.h>
|
||||
|
||||
#include "../mwrender/videoplayer.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
/**
|
||||
* Widget that plays a video. Can be skipped by pressing Esc.
|
||||
*/
|
||||
class VideoWidget : public MyGUI::ImageBox
|
||||
{
|
||||
public:
|
||||
MYGUI_RTTI_DERIVED(VideoWidget)
|
||||
|
||||
VideoWidget();
|
||||
|
||||
void playVideo (const std::string& video, bool allowSkipping);
|
||||
|
||||
int getVideoWidth();
|
||||
int getVideoHeight();
|
||||
|
||||
/// @return Is the video still playing?
|
||||
bool update();
|
||||
|
||||
private:
|
||||
bool mAllowSkipping;
|
||||
|
||||
MWRender::VideoPlayer mPlayer;
|
||||
|
||||
void onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include <iterator>
|
||||
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
|
||||
#include "MyGUI_UString.h"
|
||||
#include "MyGUI_IPointer.h"
|
||||
|
@ -59,6 +60,7 @@
|
|||
#include "bookpage.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "fontloader.hpp"
|
||||
#include "videowidget.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -104,6 +106,8 @@ namespace MWGui
|
|||
, mRecharge(NULL)
|
||||
, mRepair(NULL)
|
||||
, mCompanionWindow(NULL)
|
||||
, mVideoBackground(NULL)
|
||||
, mVideoWidget(NULL)
|
||||
, mTranslationDataStorage (translationDataStorage)
|
||||
, mCharGen(NULL)
|
||||
, mInputBlocker(NULL)
|
||||
|
@ -155,6 +159,7 @@ namespace MWGui
|
|||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollView>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollBar>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<VideoWidget>("Widget");
|
||||
BookPage::registerMyGUIComponents ();
|
||||
ItemView::registerComponents();
|
||||
|
||||
|
@ -186,6 +191,13 @@ namespace MWGui
|
|||
|
||||
// hide mygui's pointer
|
||||
MyGUI::PointerManager::getInstance().setVisible(false);
|
||||
|
||||
mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>("ImageBox", 0,0,1,1,
|
||||
MyGUI::Align::Default, "Overlay");
|
||||
mVideoBackground->setImageTexture("black.png");
|
||||
mVideoBackground->setVisible(false);
|
||||
|
||||
mVideoWidget = mVideoBackground->createWidgetReal<VideoWidget>("ImageBox", 0,0,1,1, MyGUI::Align::Default);
|
||||
}
|
||||
|
||||
void WindowManager::initUI()
|
||||
|
@ -391,6 +403,7 @@ namespace MWGui
|
|||
mCompanionWindow->setVisible(false);
|
||||
mInventoryWindow->setTrading(false);
|
||||
mRecharge->setVisible(false);
|
||||
mVideoBackground->setVisible(false);
|
||||
|
||||
mHud->setVisible(mHudEnabled);
|
||||
|
||||
|
@ -539,10 +552,6 @@ namespace MWGui
|
|||
|
||||
setCursorVisible(false);
|
||||
break;
|
||||
case GM_Video:
|
||||
setCursorVisible(false);
|
||||
mHud->setVisible(false);
|
||||
break;
|
||||
default:
|
||||
// Unsupported mode, switch back to game
|
||||
break;
|
||||
|
@ -894,6 +903,7 @@ namespace MWGui
|
|||
|
||||
void WindowManager::windowResized(int x, int y)
|
||||
{
|
||||
sizeVideo(x, y);
|
||||
mGuiManager->windowResized();
|
||||
mLoadingScreen->onResChange (x,y);
|
||||
if (!mHud)
|
||||
|
@ -1401,4 +1411,57 @@ namespace MWGui
|
|||
mMap->readRecord(reader, type);
|
||||
}
|
||||
|
||||
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
|
||||
{
|
||||
mVideoWidget->playVideo("video\\" + name, allowSkipping);
|
||||
|
||||
// Turn off all rendering except for the GUI
|
||||
mRendering->getScene()->clearSpecialCaseRenderQueues();
|
||||
// SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work?
|
||||
for(int i = 0;i < Ogre::RENDER_QUEUE_MAX;++i)
|
||||
{
|
||||
if(i > 0 && i < 96)
|
||||
mRendering->getScene()->addSpecialCaseRenderQueue(i);
|
||||
}
|
||||
mRendering->getScene()->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
|
||||
MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
sizeVideo(screenSize.width, screenSize.height);
|
||||
|
||||
setKeyFocusWidget(mVideoWidget);
|
||||
|
||||
mVideoBackground->setVisible(true);
|
||||
|
||||
bool cursorWasVisible = mCursorVisible;
|
||||
setCursorVisible(false);
|
||||
|
||||
while (mVideoWidget->update())
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->update(0, false);
|
||||
|
||||
mRendering->getWindow()->update();
|
||||
}
|
||||
|
||||
setCursorVisible(cursorWasVisible);
|
||||
|
||||
// Restore normal rendering
|
||||
mRendering->getScene()->clearSpecialCaseRenderQueues();
|
||||
mRendering->getScene()->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
|
||||
mVideoBackground->setVisible(false);
|
||||
}
|
||||
|
||||
void WindowManager::sizeVideo(int screenWidth, int screenHeight)
|
||||
{
|
||||
// Use black bars to correct aspect ratio
|
||||
mVideoBackground->setSize(screenWidth, screenHeight);
|
||||
|
||||
double imageaspect = static_cast<double>(mVideoWidget->getVideoWidth())/mVideoWidget->getVideoHeight();
|
||||
|
||||
int leftPadding = std::max(0.0, (screenWidth - screenHeight * imageaspect) / 2);
|
||||
int topPadding = std::max(0.0, (screenHeight - screenWidth / imageaspect) / 2);
|
||||
|
||||
mVideoWidget->setCoord(leftPadding, topPadding,
|
||||
screenWidth - leftPadding*2, screenHeight - topPadding*2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace MyGUI
|
|||
class Widget;
|
||||
class Window;
|
||||
class UString;
|
||||
class ImageBox;
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
|
@ -80,6 +81,7 @@ namespace MWGui
|
|||
class SoulgemDialog;
|
||||
class Recharge;
|
||||
class CompanionWindow;
|
||||
class VideoWidget;
|
||||
|
||||
class WindowManager : public MWBase::WindowManager
|
||||
{
|
||||
|
@ -98,6 +100,10 @@ namespace MWGui
|
|||
|
||||
virtual Loading::Listener* getLoadingScreen();
|
||||
|
||||
/// @note This method will block until the video finishes playing
|
||||
/// (and will continually update the window while doing so)
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping);
|
||||
|
||||
/**
|
||||
* Should be called each frame to update windows/gui elements.
|
||||
* This could mean updating sizes of gui elements or opening
|
||||
|
@ -332,6 +338,8 @@ namespace MWGui
|
|||
Repair* mRepair;
|
||||
Recharge* mRecharge;
|
||||
CompanionWindow* mCompanionWindow;
|
||||
MyGUI::ImageBox* mVideoBackground;
|
||||
VideoWidget* mVideoWidget;
|
||||
|
||||
Translation::Storage& mTranslationDataStorage;
|
||||
Cursor* mSoftwareCursor;
|
||||
|
@ -390,6 +398,8 @@ namespace MWGui
|
|||
|
||||
void onCursorChange(const std::string& name);
|
||||
void onKeyFocusChanged(MyGUI::Widget* widget);
|
||||
|
||||
void sizeVideo(int screenWidth, int screenHeight);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -626,9 +626,7 @@ namespace MWInput
|
|||
if (MyGUI::InputManager::getInstance ().isModalAny())
|
||||
return;
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video)
|
||||
MWBase::Environment::get().getWorld ()->stopVideo ();
|
||||
else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "water.hpp"
|
||||
#include "npcanimation.hpp"
|
||||
#include "globalmap.hpp"
|
||||
#include "videoplayer.hpp"
|
||||
#include "terrainstorage.hpp"
|
||||
#include "effectmanager.hpp"
|
||||
|
||||
|
@ -171,9 +170,6 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
|
|||
|
||||
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
|
||||
|
||||
mVideoPlayer = new VideoPlayer(mRendering.getScene (), mRendering.getWindow());
|
||||
mVideoPlayer->setResolution (Settings::Manager::getInt ("resolution x", "Video"), Settings::Manager::getInt ("resolution y", "Video"));
|
||||
|
||||
mSun = 0;
|
||||
|
||||
mDebugging = new Debugging(mRootNode, engine);
|
||||
|
@ -197,7 +193,6 @@ RenderingManager::~RenderingManager ()
|
|||
delete mLocalMap;
|
||||
delete mOcclusionQuery;
|
||||
delete mWater;
|
||||
delete mVideoPlayer;
|
||||
delete mActors;
|
||||
delete mObjects;
|
||||
delete mEffectManager;
|
||||
|
@ -333,8 +328,6 @@ void RenderingManager::rebuildPtr(const MWWorld::Ptr &ptr)
|
|||
|
||||
void RenderingManager::update (float duration, bool paused)
|
||||
{
|
||||
mVideoPlayer->update ();
|
||||
|
||||
if (MWBase::Environment::get().getStateManager()->getState()==
|
||||
MWBase::StateManager::State_NoGame)
|
||||
return;
|
||||
|
@ -884,8 +877,6 @@ void RenderingManager::windowResized(int x, int y)
|
|||
Settings::Manager::setInt("resolution y", "Video", y);
|
||||
mRendering.adjustViewport();
|
||||
|
||||
mVideoPlayer->setResolution (x, y);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->windowResized(x,y);
|
||||
}
|
||||
|
||||
|
@ -1001,16 +992,6 @@ void RenderingManager::screenshot(Image &image, int w, int h)
|
|||
mRendering.getCamera()->setAspectRatio(oldAspect);
|
||||
}
|
||||
|
||||
void RenderingManager::playVideo(const std::string& name, bool allowSkipping)
|
||||
{
|
||||
mVideoPlayer->playVideo ("video/" + name, allowSkipping);
|
||||
}
|
||||
|
||||
void RenderingManager::stopVideo()
|
||||
{
|
||||
mVideoPlayer->stopVideo ();
|
||||
}
|
||||
|
||||
void RenderingManager::addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale, float force)
|
||||
{
|
||||
mWater->addEmitter (ptr, scale, force);
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace MWRender
|
|||
class LocalMap;
|
||||
class Water;
|
||||
class GlobalMap;
|
||||
class VideoPlayer;
|
||||
class Animation;
|
||||
class EffectManager;
|
||||
|
||||
|
@ -209,8 +208,6 @@ public:
|
|||
|
||||
Animation* getAnimation(const MWWorld::Ptr &ptr);
|
||||
|
||||
void playVideo(const std::string& name, bool allowSkipping);
|
||||
void stopVideo();
|
||||
void frameStarted(float dt, bool paused);
|
||||
void screenshot(Ogre::Image& image, int w, int h);
|
||||
|
||||
|
@ -271,8 +268,6 @@ private:
|
|||
MWRender::LocalMap* mLocalMap;
|
||||
|
||||
MWRender::Shadows* mShadows;
|
||||
|
||||
VideoPlayer* mVideoPlayer;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwsound/sound_decoder.hpp"
|
||||
|
@ -126,7 +125,7 @@ struct VideoState {
|
|||
|
||||
int stream_open(int stream_index, AVFormatContext *pFormatCtx);
|
||||
|
||||
bool update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height);
|
||||
bool update();
|
||||
|
||||
static void video_thread_loop(VideoState *is);
|
||||
static void decode_thread_loop(VideoState *is);
|
||||
|
@ -163,6 +162,7 @@ struct VideoState {
|
|||
static int OgreResource_Write(void *user_data, uint8_t *buf, int buf_size);
|
||||
static int64_t OgreResource_Seek(void *user_data, int64_t offset, int whence);
|
||||
|
||||
Ogre::TexturePtr mTexture;
|
||||
|
||||
Ogre::DataStreamPtr stream;
|
||||
AVFormatContext* format_ctx;
|
||||
|
@ -599,22 +599,17 @@ void VideoState::video_display()
|
|||
|
||||
if((*this->video_st)->codec->width != 0 && (*this->video_st)->codec->height != 0)
|
||||
{
|
||||
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("VideoTexture");
|
||||
if(texture.isNull() || static_cast<int>(texture->getWidth()) != (*this->video_st)->codec->width
|
||||
|| static_cast<int>(texture->getHeight()) != (*this->video_st)->codec->height)
|
||||
|
||||
if(static_cast<int>(mTexture->getWidth()) != (*this->video_st)->codec->width ||
|
||||
static_cast<int>(mTexture->getHeight()) != (*this->video_st)->codec->height)
|
||||
{
|
||||
Ogre::TextureManager::getSingleton ().remove ("VideoTexture");
|
||||
texture = Ogre::TextureManager::getSingleton().createManual(
|
||||
"VideoTexture",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Ogre::TEX_TYPE_2D,
|
||||
(*this->video_st)->codec->width, (*this->video_st)->codec->height,
|
||||
0,
|
||||
Ogre::PF_BYTE_RGBA,
|
||||
Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
|
||||
mTexture->unload();
|
||||
mTexture->setWidth((*this->video_st)->codec->width);
|
||||
mTexture->setHeight((*this->video_st)->codec->height);
|
||||
mTexture->createInternalResources();
|
||||
}
|
||||
Ogre::PixelBox pb((*this->video_st)->codec->width, (*this->video_st)->codec->height, 1, Ogre::PF_BYTE_RGBA, &vp->data[0]);
|
||||
Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer();
|
||||
Ogre::HardwarePixelBufferSharedPtr buffer = mTexture->getBuffer();
|
||||
buffer->blitFromMemory(pb);
|
||||
this->display_ready = true;
|
||||
}
|
||||
|
@ -851,7 +846,7 @@ void VideoState::decode_thread_loop(VideoState *self)
|
|||
}
|
||||
|
||||
|
||||
bool VideoState::update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height)
|
||||
bool VideoState::update()
|
||||
{
|
||||
if(this->quit)
|
||||
return false;
|
||||
|
@ -860,21 +855,6 @@ bool VideoState::update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int scr
|
|||
{
|
||||
this->refresh = false;
|
||||
this->video_refresh_timer();
|
||||
// Would be nice not to do this all the time...
|
||||
if(this->display_ready)
|
||||
mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("VideoTexture");
|
||||
|
||||
// Correct aspect ratio by adding black bars
|
||||
double videoaspect = av_q2d((*this->video_st)->codec->sample_aspect_ratio);
|
||||
if(videoaspect == 0.0)
|
||||
videoaspect = 1.0;
|
||||
videoaspect *= static_cast<double>((*this->video_st)->codec->width) / (*this->video_st)->codec->height;
|
||||
|
||||
double screenaspect = static_cast<double>(screen_width) / screen_height;
|
||||
double aspect_correction = videoaspect / screenaspect;
|
||||
|
||||
rect->setCorners(std::max(-1.0, -1.0 * aspect_correction), std::min( 1.0, 1.0 / aspect_correction),
|
||||
std::min( 1.0, 1.0 * aspect_correction), std::max(-1.0, -1.0 / aspect_correction));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1001,8 +981,29 @@ void VideoState::init(const std::string& resourceName)
|
|||
if(audio_index >= 0)
|
||||
this->stream_open(audio_index, this->format_ctx);
|
||||
if(video_index >= 0)
|
||||
{
|
||||
this->stream_open(video_index, this->format_ctx);
|
||||
|
||||
int width = (*this->video_st)->codec->width;
|
||||
int height = (*this->video_st)->codec->height;
|
||||
static int i = 0;
|
||||
this->mTexture = Ogre::TextureManager::getSingleton().createManual(
|
||||
"OpenMW/VideoTexture" + Ogre::StringConverter::toString(++i),
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Ogre::TEX_TYPE_2D,
|
||||
width, height, // TEST
|
||||
0,
|
||||
Ogre::PF_BYTE_RGBA,
|
||||
Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
|
||||
|
||||
// initialize to (0,0,0,0)
|
||||
std::vector<Ogre::uint32> buffer;
|
||||
buffer.resize(width * height, 0);
|
||||
Ogre::PixelBox pb(width, height, 1, Ogre::PF_BYTE_RGBA, &buffer[0]);
|
||||
this->mTexture->getBuffer()->blitFromMemory(pb);
|
||||
}
|
||||
|
||||
|
||||
this->parse_thread = boost::thread(decode_thread_loop, this);
|
||||
}
|
||||
|
||||
|
@ -1073,111 +1074,26 @@ public:
|
|||
#endif // defined OPENMW_USE_FFMPEG
|
||||
|
||||
|
||||
VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* window)
|
||||
VideoPlayer::VideoPlayer()
|
||||
: mState(NULL)
|
||||
, mSceneMgr(sceneMgr)
|
||||
, mRectangle(NULL)
|
||||
, mNode(NULL)
|
||||
, mAllowSkipping(false)
|
||||
, mWindow(window)
|
||||
, mWidth(0)
|
||||
, mHeight(0)
|
||||
{
|
||||
mVideoMaterial = Ogre::MaterialManager::getSingleton().getByName("VideoMaterial", "General");
|
||||
if (mVideoMaterial.isNull ())
|
||||
{
|
||||
mVideoMaterial = Ogre::MaterialManager::getSingleton().create("VideoMaterial", "General");
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->createTextureUnitState();
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
|
||||
}
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("black.png");
|
||||
|
||||
Ogre::MaterialPtr blackMaterial = Ogre::MaterialManager::getSingleton().getByName("BlackBarsMaterial", "General");
|
||||
if (blackMaterial.isNull ())
|
||||
{
|
||||
blackMaterial = Ogre::MaterialManager::getSingleton().create("BlackBarsMaterial", "General");
|
||||
blackMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
||||
blackMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
|
||||
blackMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||
blackMaterial->getTechnique(0)->getPass(0)->createTextureUnitState()->setTextureName("black.png");
|
||||
}
|
||||
|
||||
mRectangle = new Ogre::Rectangle2D(true);
|
||||
mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0);
|
||||
mRectangle->setMaterial("VideoMaterial");
|
||||
mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY+2);
|
||||
mBackgroundRectangle = new Ogre::Rectangle2D(true);
|
||||
mBackgroundRectangle->setCorners(-1.0, 1.0, 1.0, -1.0);
|
||||
mBackgroundRectangle->setMaterial("BlackBarsMaterial");
|
||||
mBackgroundRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY+1);
|
||||
|
||||
// Use infinite AAB to always stay visible
|
||||
Ogre::AxisAlignedBox aabInf;
|
||||
aabInf.setInfinite();
|
||||
mRectangle->setBoundingBox(aabInf);
|
||||
mBackgroundRectangle->setBoundingBox(aabInf);
|
||||
|
||||
// Attach background to the scene
|
||||
mNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||
mNode->attachObject(mRectangle);
|
||||
mBackgroundNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||
mBackgroundNode->attachObject(mBackgroundRectangle);
|
||||
|
||||
mRectangle->setVisible(false);
|
||||
mRectangle->setVisibilityFlags(RV_Overlay);
|
||||
mBackgroundRectangle->setVisible(false);
|
||||
mBackgroundRectangle->setVisibilityFlags(RV_Overlay);
|
||||
}
|
||||
|
||||
VideoPlayer::~VideoPlayer()
|
||||
{
|
||||
if(mState)
|
||||
close();
|
||||
|
||||
mSceneMgr->destroySceneNode(mNode);
|
||||
mSceneMgr->destroySceneNode(mBackgroundNode);
|
||||
|
||||
delete mRectangle;
|
||||
delete mBackgroundRectangle;
|
||||
}
|
||||
|
||||
void VideoPlayer::playVideo(const std::string &resourceName, bool allowSkipping)
|
||||
void VideoPlayer::playVideo(const std::string &resourceName)
|
||||
{
|
||||
mAllowSkipping = allowSkipping;
|
||||
|
||||
if(mState)
|
||||
close();
|
||||
|
||||
mRectangle->setVisible(true);
|
||||
mBackgroundRectangle->setVisible(true);
|
||||
mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("black.png");
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Video);
|
||||
|
||||
// Turn off rendering except the GUI
|
||||
mSceneMgr->clearSpecialCaseRenderQueues();
|
||||
// SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work.
|
||||
for(int i = 0;i < Ogre::RENDER_QUEUE_MAX;++i)
|
||||
{
|
||||
if(i > 0 && i < 96)
|
||||
mSceneMgr->addSpecialCaseRenderQueue(i);
|
||||
}
|
||||
mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
|
||||
try {
|
||||
mState = new VideoState;
|
||||
mState->init(resourceName);
|
||||
|
||||
while (isPlaying())
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->update(0, false);
|
||||
update();
|
||||
mWindow->update();
|
||||
}
|
||||
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
std::cerr<< "Failed to play video: "<<e.what() <<std::endl;
|
||||
|
@ -1189,15 +1105,38 @@ void VideoPlayer::update ()
|
|||
{
|
||||
if(mState)
|
||||
{
|
||||
if(!mState->update(mVideoMaterial, mRectangle, mWidth, mHeight))
|
||||
if(!mState->update())
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
std::string VideoPlayer::getTextureName()
|
||||
{
|
||||
std::string name;
|
||||
if (mState)
|
||||
name = mState->mTexture->getName();
|
||||
return name;
|
||||
}
|
||||
|
||||
int VideoPlayer::getVideoWidth()
|
||||
{
|
||||
int width=0;
|
||||
if (mState)
|
||||
width = mState->mTexture->getWidth();
|
||||
return width;
|
||||
}
|
||||
|
||||
int VideoPlayer::getVideoHeight()
|
||||
{
|
||||
int height=0;
|
||||
if (mState)
|
||||
height = mState->mTexture->getHeight();
|
||||
return height;
|
||||
}
|
||||
|
||||
void VideoPlayer::stopVideo ()
|
||||
{
|
||||
if (mAllowSkipping)
|
||||
close();
|
||||
close();
|
||||
}
|
||||
|
||||
void VideoPlayer::close()
|
||||
|
@ -1211,13 +1150,6 @@ void VideoPlayer::close()
|
|||
}
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->resumeSounds();
|
||||
|
||||
mRectangle->setVisible(false);
|
||||
mBackgroundRectangle->setVisible(false);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Video);
|
||||
|
||||
mSceneMgr->clearSpecialCaseRenderQueues();
|
||||
mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
}
|
||||
|
||||
bool VideoPlayer::isPlaying ()
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
#ifndef VIDEOPLAYER_H
|
||||
#define VIDEOPLAYER_H
|
||||
|
||||
#include <OgreMaterial.h>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class SceneManager;
|
||||
class SceneNode;
|
||||
class Rectangle2D;
|
||||
class RenderWindow;
|
||||
}
|
||||
#include <string>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
struct VideoState;
|
||||
|
||||
/**
|
||||
* @brief Plays a video on an Ogre texture.
|
||||
*/
|
||||
class VideoPlayer
|
||||
{
|
||||
public:
|
||||
VideoPlayer(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* window);
|
||||
VideoPlayer();
|
||||
~VideoPlayer();
|
||||
|
||||
void playVideo (const std::string& resourceName, bool allowSkipping);
|
||||
void playVideo (const std::string& resourceName);
|
||||
|
||||
void update();
|
||||
|
||||
|
@ -30,22 +25,14 @@ namespace MWRender
|
|||
|
||||
bool isPlaying();
|
||||
|
||||
void setResolution (int w, int h) { mWidth = w; mHeight = h; }
|
||||
std::string getTextureName();
|
||||
int getVideoWidth();
|
||||
int getVideoHeight();
|
||||
|
||||
|
||||
private:
|
||||
VideoState* mState;
|
||||
|
||||
bool mAllowSkipping;
|
||||
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
Ogre::MaterialPtr mVideoMaterial;
|
||||
Ogre::Rectangle2D* mRectangle;
|
||||
Ogre::Rectangle2D* mBackgroundRectangle;
|
||||
Ogre::SceneNode* mNode;
|
||||
Ogre::SceneNode* mBackgroundNode;
|
||||
Ogre::RenderWindow* mWindow;
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace MWScript
|
|||
bool allowSkipping = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWBase::Environment::get().getWorld ()->playVideo (name, allowSkipping);
|
||||
MWBase::Environment::get().getWindowManager()->playVideo (name, allowSkipping);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1305,7 +1305,7 @@ namespace MWWorld
|
|||
{
|
||||
--mPlayIntro;
|
||||
if (mPlayIntro == 0)
|
||||
mRendering->playVideo(mFallback.getFallbackString("Movies_New_Game"), true);
|
||||
MWBase::Environment::get().getWindowManager()->playVideo(mFallback.getFallbackString("Movies_New_Game"), true);
|
||||
}
|
||||
|
||||
if (mGoToJail && !paused)
|
||||
|
@ -1776,16 +1776,6 @@ namespace MWWorld
|
|||
return mRendering->getAnimation(ptr);
|
||||
}
|
||||
|
||||
void World::playVideo (const std::string &name, bool allowSkipping)
|
||||
{
|
||||
mRendering->playVideo(name, allowSkipping);
|
||||
}
|
||||
|
||||
void World::stopVideo ()
|
||||
{
|
||||
mRendering->stopVideo();
|
||||
}
|
||||
|
||||
void World::frameStarted (float dt, bool paused)
|
||||
{
|
||||
mRendering->frameStarted(dt, paused);
|
||||
|
|
|
@ -523,8 +523,6 @@ namespace MWWorld
|
|||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr);
|
||||
|
||||
/// \todo this does not belong here
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping);
|
||||
virtual void stopVideo();
|
||||
virtual void frameStarted (float dt, bool paused);
|
||||
virtual void screenshot (Ogre::Image& image, int w, int h);
|
||||
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
<Layer name="Popup" overlapped="true" peek="true"/>
|
||||
<Layer name="DragAndDrop" overlapped="false" peek="false"/>
|
||||
<Layer name="LoadingScreen" overlapped="false" peek="true"/>
|
||||
<Layer name="Overlay" overlapped="false" peek="false"/>
|
||||
<Layer name="Pointer" overlapped="false" peek="false"/>
|
||||
</MyGUI>
|
||||
|
|
Loading…
Reference in a new issue