Restored window resizing

actorid
scrawl 12 years ago
parent f73008546f
commit 6164e5bae6

@ -237,6 +237,8 @@ namespace MWBase
virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
virtual void windowResized(int x, int y) = 0;
virtual void executeInConsole (const std::string& path) = 0;
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total) = 0;

@ -272,15 +272,12 @@ namespace MWGui
if (index == MyGUI::ITEM_NONE)
return;
/*
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
dialog->open("#{sNotifyMessage67}");
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept);
dialog->eventCancelClicked.clear();
dialog->eventCancelClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionCancel);
*/
onResolutionAccept();
}
void SettingsWindow::onResolutionAccept()
@ -293,9 +290,6 @@ namespace MWGui
Settings::Manager::setInt("resolution y", "Video", resY);
apply();
MWBase::Environment::get().getWindowManager()->
messageBox("New resolution will be applied after a restart", std::vector<std::string>());
}
void SettingsWindow::onResolutionCancel()
@ -364,8 +358,6 @@ namespace MWGui
{
Settings::Manager::setBool("fullscreen", "Video", newState);
apply();
MWBase::Environment::get().getWindowManager()->
messageBox("Fullscreen will be applied after a restart", std::vector<std::string>());
}
}
else if (_sender == mVSyncButton)

@ -877,49 +877,31 @@ namespace MWGui
setUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI"));
//bool changeRes = false;
bool windowRecreated = false;
for (Settings::CategorySettingVector::const_iterator it = changed.begin();
it != changed.end(); ++it)
{
/*if (it->first == "Video" && (
it->second == "resolution x"
|| it->second == "resolution y"))
{
changeRes = true;
}*/
if (it->first == "Video" && it->second == "vsync")
windowRecreated = true;
else if (it->first == "HUD" && it->second == "crosshair")
if (it->first == "HUD" && it->second == "crosshair")
mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD");
else if (it->first == "GUI" && it->second == "subtitles")
mSubtitlesEnabled = Settings::Manager::getBool ("subtitles", "GUI");
}
}
/*
if (changeRes)
{
int x = Settings::Manager::getInt("resolution x", "Video");
int y = Settings::Manager::getInt("resolution y", "Video");
mHud->onResChange(x, y);
mConsole->onResChange(x, y);
mMenu->onResChange(x, y);
mSettingsWindow->center();
mAlchemyWindow->center();
mScrollWindow->center();
mBookWindow->center();
mQuickKeysMenu->center();
mSpellBuyingWindow->center();
mLoadingScreen->onResChange (x,y);
mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
mInputBlocker->setSize(MyGUI::IntSize(x,y));
}
*/
if (windowRecreated)
{
mGuiManager->updateWindow (mRendering->getWindow ());
mLoadingScreen->updateWindow (mRendering->getWindow ());
}
void WindowManager::windowResized(int x, int y)
{
mHud->onResChange(x, y);
mConsole->onResChange(x, y);
mMenu->onResChange(x, y);
mSettingsWindow->center();
mAlchemyWindow->center();
mScrollWindow->center();
mBookWindow->center();
mQuickKeysMenu->center();
mSpellBuyingWindow->center();
mLoadingScreen->onResChange (x,y);
mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
mInputBlocker->setSize(MyGUI::IntSize(x,y));
mGuiManager->windowResized();
}
void WindowManager::pushGuiMode(GuiMode mode)

@ -225,6 +225,8 @@ namespace MWGui
virtual void processChangedSettings(const Settings::CategorySettingVector& changed);
virtual void windowResized(int x, int y);
virtual void executeInConsole (const std::string& path);
virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total);

@ -385,7 +385,7 @@ namespace MWInput
if (mControlSwitch["playerviewswitch"]) {
// work around preview mode toggle when pressing Alt+Tab
if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(KMOD_ALT)) {
if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) {
if (mPreviewPOVDelay <= 0.5 &&
(mPreviewPOVDelay += dt) > 0.5)
{
@ -434,13 +434,9 @@ namespace MWInput
void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{
bool changeRes = false;
for (Settings::CategorySettingVector::const_iterator it = changed.begin();
it != changed.end(); ++it)
{
if (it->first == "Video" && (it->second == "resolution x" || it->second == "resolution y"))
changeRes = true;
if (it->first == "Input" && it->second == "invert y axis")
mInvertY = Settings::Manager::getBool("invert y axis", "Input");
@ -451,9 +447,6 @@ namespace MWInput
mUISensitivity = Settings::Manager::getFloat("ui sensitivity", "Input");
}
if (changeRes)
adjustMouseRegion(Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video"));
}
bool InputManager::getControlSwitch (const std::string& sw)
@ -617,15 +610,18 @@ namespace MWInput
return true;
}
bool InputManager::windowFocusChange(bool have_focus)
void InputManager::windowFocusChange(bool have_focus)
{
return true;
}
bool InputManager::windowVisibilityChange(bool visible)
void InputManager::windowVisibilityChange(bool visible)
{
//TODO: Pause game?
return true;
}
void InputManager::windowResized(int x, int y)
{
mOgre.windowResized(x,y);
}
void InputManager::toggleMainMenu()

@ -94,8 +94,9 @@ namespace MWInput
virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
virtual bool mouseMoved( const SFO::MouseMotionEvent &arg );
virtual bool windowVisibilityChange( bool visible );
virtual bool windowFocusChange( bool have_focus );
virtual void windowVisibilityChange( bool visible );
virtual void windowFocusChange( bool have_focus );
virtual void windowResized (int x, int y);
virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue);

@ -16,6 +16,8 @@
#include <OgreControllerManager.h>
#include <OgreMeshManager.h>
#include <SDL_video.h>
#include <extern/shiny/Main/Factory.hpp>
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
@ -77,9 +79,9 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
}
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
mRendering.setWindowEventListener(this);
mRendering.getWindow()->addListener(this);
mRendering.setWindowListener(this);
mCompositors = new Compositors(mRendering.getViewport());
@ -186,7 +188,6 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
RenderingManager::~RenderingManager ()
{
mRendering.getWindow()->removeListener(this);
mRendering.removeWindowEventListener(this);
delete mPlayerAnimation;
delete mCamera;
@ -718,7 +719,7 @@ Compositors* RenderingManager::getCompositors()
void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings)
{
//bool changeRes = false;
bool changeRes = false;
bool rebuild = false; // rebuild static geometry (necessary after any material changes)
for (Settings::CategorySettingVector::const_iterator it=settings.begin();
it != settings.end(); ++it)
@ -732,11 +733,11 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior())
configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell());
}
/*else if (it->first == "Video" && (
else if (it->first == "Video" && (
it->second == "resolution x"
|| it->second == "resolution y"
|| it->second == "fullscreen"))
changeRes = true;*/
changeRes = true;
else if (it->second == "field of view" && it->first == "General")
mRendering.setFov(Settings::Manager::getFloat("field of view", "General"));
else if ((it->second == "texture filtering" && it->first == "General")
@ -790,24 +791,31 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
}
}
/*
if (changeRes)
{
unsigned int x = Settings::Manager::getInt("resolution x", "Video");
unsigned int y = Settings::Manager::getInt("resolution y", "Video");
bool fullscreen = Settings::Manager::getBool("fullscreen", "Video");
SDL_Window* window = mRendering.getSDLWindow();
SDL_SetWindowFullscreen(window, 0);
SDL_SetWindowFullscreen(mRendering.getSDLWindow(), 0);
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED)
SDL_RestoreWindow(window);
if (x != mRendering.getWindow()->getWidth() || y != mRendering.getWindow()->getHeight())
if (fullscreen)
{
SDL_SetWindowSize(mRendering.getSDLWindow(), x, y);
mRendering.getWindow()->resize(x, y);
SDL_DisplayMode mode;
SDL_GetWindowDisplayMode(window, &mode);
mode.w = x;
mode.h = y;
SDL_SetWindowDisplayMode(window, &mode);
SDL_SetWindowFullscreen(window, fullscreen);
}
SDL_SetWindowFullscreen(mRendering.getSDLWindow(), Settings::Manager::getBool("fullscreen", "Video") ? SDL_WINDOW_FULLSCREEN : 0);
//mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y);
else
SDL_SetWindowSize(window, x, y);
}
*/
mWater->processChangedSettings(settings);
@ -825,24 +833,14 @@ void RenderingManager::setMenuTransparency(float val)
tex->getBuffer()->unlock();
}
void RenderingManager::windowResized(Ogre::RenderWindow* rw)
void RenderingManager::windowResized(int x, int y)
{
Settings::Manager::setInt("resolution x", "Video", rw->getWidth());
Settings::Manager::setInt("resolution y", "Video", rw->getHeight());
mRendering.adjustViewport();
mCompositors->recreate();
mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight());
const Settings::CategorySettingVector& changed = Settings::Manager::apply();
MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
}
mVideoPlayer->setResolution (x, y);
void RenderingManager::windowClosed(Ogre::RenderWindow* rw)
{
Ogre::Root::getSingleton ().queueEndRendering ();
MWBase::Environment::get().getWindowManager()->windowResized(x,y);
}
void RenderingManager::applyCompositors()

@ -50,7 +50,7 @@ namespace MWRender
class VideoPlayer;
class Animation;
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener
class RenderingManager: private RenderingInterface, public Ogre::RenderTargetListener, public OEngine::Render::WindowSizeListener
{
private:
virtual MWRender::Objects& getObjects();
@ -204,8 +204,7 @@ public:
void frameStarted(float dt);
protected:
virtual void windowResized(Ogre::RenderWindow* rw);
virtual void windowClosed(Ogre::RenderWindow* rw);
virtual void windowResized(int x, int y);
private:
sh::Factory* mFactory;

@ -551,7 +551,6 @@ void WeatherManager::stopSounds(bool stopAll)
Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const
{
const MWBase::World *world = MWBase::Environment::get().getWorld();
std::vector<char> probability;
RegionModMap::const_iterator iter = mRegionMods.find(Misc::StringUtils::lowerCase(region->mId));
@ -581,7 +580,7 @@ Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const
int chance = (rand() % 100) + 1; // 1..100
int sum = 0;
int i = 0;
unsigned int i = 0;
for (; i < probability.size(); ++i)
{
sum += probability[i];

@ -5,6 +5,7 @@ set(SDL4OGRE_LIBRARY "sdl4ogre")
set(SDL4OGRE_SOURCE_FILES
sdlinputwrapper.cpp
sdlcursormanager.cpp
sdlwindowhelper.cpp
)
set(SDL4OGRE_HEADER_FILES

@ -65,10 +65,12 @@ public:
virtual ~WindowListener() {}
/** @remarks The window's visibility changed */
virtual bool windowVisibilityChange( bool visible ) = 0;
virtual void windowVisibilityChange( bool visible ) {};
/** @remarks The window got / lost input focus */
virtual bool windowFocusChange( bool have_focus ) = 0;
virtual void windowFocusChange( bool have_focus ) {}
virtual void windowResized (int x, int y) {}
};
}

@ -4,13 +4,6 @@
#include <OgrePlatform.h>
#include <OgreRoot.h>
/*
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xos.h>
#endif
*/
namespace SFO
{
@ -19,7 +12,6 @@ namespace SFO
InputWrapper::InputWrapper(SDL_Window* window, Ogre::RenderWindow* ogreWindow) :
mSDLWindow(window),
mOgreWindow(ogreWindow),
mOwnWindow(false),
mWarpCompensate(false),
mMouseRelative(false),
mGrabPointer(false),
@ -27,14 +19,18 @@ namespace SFO
mMouseZ(0),
mMouseY(0),
mMouseX(0),
mMouseInWindow(true)
mMouseInWindow(true),
mJoyListener(NULL),
mKeyboardListener(NULL),
mMouseListener(NULL),
mWindowListener(NULL)
{
_setupOISKeys();
}
InputWrapper::~InputWrapper()
{
if(mSDLWindow != NULL && mOwnWindow)
if(mSDLWindow != NULL)
SDL_DestroyWindow(mSDLWindow);
mSDLWindow = NULL;
}
@ -76,6 +72,25 @@ namespace SFO
case SDL_TEXTINPUT:
mKeyboardListener->textInput(evt.text);
break;
case SDL_JOYAXISMOTION:
if (mJoyListener)
mJoyListener->axisMoved(evt.jaxis, evt.jaxis.axis);
break;
case SDL_JOYBUTTONDOWN:
if (mJoyListener)
mJoyListener->buttonPressed(evt.jbutton, evt.jbutton.button);
break;
case SDL_JOYBUTTONUP:
if (mJoyListener)
mJoyListener->buttonReleased(evt.jbutton, evt.jbutton.button);
break;
case SDL_JOYDEVICEADDED:
//SDL_JoystickOpen(evt.jdevice.which);
//std::cout << "Detected a new joystick: " << SDL_JoystickNameForIndex(evt.jdevice.which) << std::endl;
break;
case SDL_JOYDEVICEREMOVED:
//std::cout << "A joystick has been removed" << std::endl;
break;
case SDL_WINDOWEVENT:
handleWindowEvent(evt);
break;
@ -100,25 +115,62 @@ namespace SFO
SDL_SetWindowGrab(mSDLWindow, SDL_FALSE);
SDL_SetRelativeMouseMode(SDL_FALSE);
break;
case SDL_WINDOWEVENT_RESIZED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
int w,h;
SDL_GetWindowSize(mSDLWindow, &w, &h);
// TODO: Fix Ogre to handle this more consistently
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
mOgreWindow->windowMovedOrResized();
#else
mOgreWindow->resize(w, h);
#endif
if (mWindowListener)
mWindowListener->windowResized(evt.window.data1, evt.window.data2);
case SDL_WINDOWEVENT_RESIZED:
// TODO: Fix Ogre to handle this more consistently
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
mOgreWindow->windowMovedOrResized();
#else
mOgreWindow->resize(evt.window.data1, evt.window.data2);
#endif
if (mWindowListener)
mWindowListener->windowResized(evt.window.data1, evt.window.data2);
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
if (mWindowListener)
mWindowListener->windowFocusChange(true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
if (mWindowListener)
mWindowListener->windowFocusChange(false);
break;
case SDL_WINDOWEVENT_CLOSE:
break;
case SDL_WINDOWEVENT_SHOWN:
mOgreWindow->setVisible(true);
if (mWindowListener)
mWindowListener->windowVisibilityChange(true);
break;
case SDL_WINDOWEVENT_HIDDEN:
mOgreWindow->setVisible(false);
if (mWindowListener)
mWindowListener->windowVisibilityChange(false);
break;
}
}
bool InputWrapper::isModifierHeld(int mod)
bool InputWrapper::isModifierHeld(SDL_Keymod mod)
{
return SDL_GetModState() & mod;
}
bool InputWrapper::isKeyDown(SDL_Scancode key)
{
return SDL_GetKeyboardState(NULL)[key];
}
/// \brief Moves the mouse to the specified point within the viewport
void InputWrapper::warpMouse(int x, int y)
{

@ -22,9 +22,11 @@ namespace SFO
void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; }
void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; }
void setWindowEventCallback(WindowListener* listen) { mWindowListener = listen; }
void setJoyEventCallback(JoyListener* listen) { mJoyListener = listen; }
void capture();
bool isModifierHeld(int mod);
bool isModifierHeld(SDL_Keymod mod);
bool isKeyDown(SDL_Scancode key);
void setMouseRelative(bool relative);
bool getMouseRelative() { return mMouseRelative; }
@ -47,6 +49,7 @@ namespace SFO
SFO::MouseListener* mMouseListener;
SFO::KeyListener* mKeyboardListener;
SFO::WindowListener* mWindowListener;
SFO::JoyListener* mJoyListener;
typedef boost::unordered_map<SDL_Keycode, OIS::KeyCode> KeyMap;
KeyMap mKeyMap;
@ -66,7 +69,6 @@ namespace SFO
SDL_Window* mSDLWindow;
Ogre::RenderWindow* mOgreWindow;
bool mOwnWindow;
};
}

@ -0,0 +1,115 @@
#include "sdlwindowhelper.hpp"
#include <OgreStringConverter.h>
#include <OgreRoot.h>
#include <SDL_syswm.h>
#include <SDL_endian.h>
namespace SFO
{
SDLWindowHelper::SDLWindowHelper (SDL_Window* window, int w, int h,
const std::string& title, bool fullscreen, Ogre::NameValuePairList params)
: mSDLWindow(window)
{
//get the native whnd
struct SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(mSDLWindow, &wmInfo) == -1)
throw std::runtime_error("Couldn't get WM Info!");
Ogre::String winHandle;
switch (wmInfo.subsystem)
{
#ifdef WIN32
case SDL_SYSWM_WINDOWS:
// Windows code
winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.win.window);
break;
#elif __MACOSX__
case SDL_SYSWM_COCOA:
//required to make OGRE play nice with our window
params.insert(std::make_pair("macAPI", "cocoa"));
params.insert(std::make_pair("macAPICocoaUseNSView", "true"));
winHandle = Ogre::StringConverter::toString(WindowContentViewHandle(wmInfo));
break;
#else
case SDL_SYSWM_X11:
winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.window);
break;
#endif
default:
throw std::runtime_error("Unexpected WM!");
break;
}
/// \todo externalWindowHandle is deprecated according to the source code. Figure out a way to get parentWindowHandle
/// to work properly. On Linux/X11 it causes an occasional GLXBadDrawable error.
params.insert(std::make_pair("externalWindowHandle", winHandle));
mWindow = Ogre::Root::getSingleton().createRenderWindow(title, w, h, fullscreen, &params);
}
void SDLWindowHelper::setWindowIcon(const std::string &name)
{
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().load(name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
if (texture.isNull())
{
std::stringstream error;
error << "Window icon not found: " << name;
throw std::runtime_error(error.str());
}
Ogre::Image image;
texture->convertToImage(image);
SDL_Surface* surface = SDL_CreateRGBSurface(0,texture->getWidth(),texture->getHeight(),32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF);
//copy the Ogre texture to an SDL surface
for(size_t x = 0; x < texture->getWidth(); ++x)
{
for(size_t y = 0; y < texture->getHeight(); ++y)
{
Ogre::ColourValue clr = image.getColourAt(x, y, 0);
//set the pixel on the SDL surface to the same value as the Ogre texture's
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
Uint32 pixel = SDL_MapRGBA(surface->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255);
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
}
SDL_SetWindowIcon(mSDLWindow, surface);
SDL_FreeSurface(surface);
}
}

@ -0,0 +1,31 @@
#ifndef SDL4OGRE_SDLWINDOWHELPER_H
#define SDL4OGRE_SDLWINDOWHELPER_H
#include <OgreRenderWindow.h>
namespace Ogre
{
class RenderWindow;
}
struct SDL_Window;
namespace SFO
{
/// @brief Creates an Ogre window from an SDL window and allows setting an Ogre texture as window icon
class SDLWindowHelper
{
public:
SDLWindowHelper (SDL_Window* window, int w, int h, const std::string& title, bool fullscreen, Ogre::NameValuePairList params);
void setWindowIcon(const std::string& name);
Ogre::RenderWindow* getWindow() { return mWindow; }
private:
Ogre::RenderWindow* mWindow;
SDL_Window* mSDLWindow;
};
}
#endif

@ -612,6 +612,11 @@ void MyGUIManager::updateWindow (Ogre::RenderWindow *wnd)
}
}
void MyGUIManager::windowResized()
{
mRenderManager->setActiveViewport(0);
}
void MyGUIManager::shutdown()
{
mGui->shutdown ();

@ -43,6 +43,8 @@ namespace GUI
void updateWindow (Ogre::RenderWindow* wnd);
void windowResized();
void setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string(""));
void shutdown();

@ -3,7 +3,6 @@
#include "particles.hpp"
#include <SDL.h>
#include <SDL_syswm.h>
#include "OgreRoot.h"
#include "OgreRenderWindow.h"
@ -19,6 +18,8 @@
#include <components/files/ogreplugin.hpp>
#include <extern/sdl4ogre/sdlwindowhelper.hpp>
#include <cassert>
#include <cstdlib>
#include <stdexcept>
@ -54,9 +55,6 @@ void OgreRenderer::cleanup()
delete mRoot;
mRoot = NULL;
if (mWindowIconSurface)
SDL_FreeSurface(mWindowIconSurface);
// If we don't do this, the desktop resolution is not restored on exit
SDL_SetWindowFullscreen(mSDLWindow, 0);
@ -237,25 +235,6 @@ void OgreRenderer::configure(const std::string &logPath,
rs->setConfigOption ("RTT Preferred Mode", rttMode);
}
void OgreRenderer::recreateWindow(const std::string &title, const WindowSettings &settings)
{
Ogre::ColourValue viewportBG = mView->getBackgroundColour();
mRoot->destroyRenderTarget(mWindow);
NameValuePairList params;
params.insert(std::make_pair("title", title));
params.insert(std::make_pair("FSAA", settings.fsaa));
params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false"));
mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, &params);
// Create one viewport, entire window
mView = mWindow->addViewport(mCamera);
mView->setBackgroundColour(viewportBG);
adjustViewport();
}
void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings)
{
assert(mRoot);
@ -286,55 +265,14 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings&
settings.window_x, // width, in pixels
settings.window_y, // height, in pixels
SDL_WINDOW_SHOWN
| (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0)
| (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0) | SDL_WINDOW_RESIZABLE
);
//get the native whnd
struct SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if(SDL_FALSE == SDL_GetWindowWMInfo(mSDLWindow, &wmInfo))
throw std::runtime_error("Couldn't get WM Info!");
Ogre::String winHandle;
switch(wmInfo.subsystem)
{
#ifdef WIN32
case SDL_SYSWM_WINDOWS:
// Windows code
winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.win.window);
break;
#elif __MACOSX__
case SDL_SYSWM_COCOA:
//required to make OGRE play nice with our window
params.insert(std::make_pair("macAPI", "cocoa"));
params.insert(std::make_pair("macAPICocoaUseNSView", "true"));
winHandle = Ogre::StringConverter::toString(WindowContentViewHandle(wmInfo));
break;
#else
case SDL_SYSWM_X11:
winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.window);
break;
#endif
default:
throw std::runtime_error("Unexpected WM!");
break;
}
/// \todo externalWindowHandle is deprecated according to the source code. Figure out a way to get parentWindowHandle
/// to work properly. On Linux/X11 it causes an occasional GLXBadDrawable error.
params.insert(std::make_pair("externalWindowHandle", winHandle));
mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, &params);
// Set the window icon
SFO::SDLWindowHelper helper(mSDLWindow, settings.window_x, settings.window_y, title, settings.fullscreen, params);
if (settings.icon != "")
{
mWindowIconSurface = ogreTextureToSDLSurface(settings.icon);
SDL_SetWindowIcon(mSDLWindow, mWindowIconSurface);
}
helper.setWindowIcon(settings.icon);
mWindow = helper.getWindow();
// create the semi-transparent black background texture used by the GUI.
// has to be created in code with TU_DYNAMIC_WRITE_ONLY param
@ -380,73 +318,12 @@ void OgreRenderer::adjustViewport()
}
}
void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener)
{
Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener);
}
void OgreRenderer::removeWindowEventListener(Ogre::WindowEventListener* listener)
{
Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener);
}
void OgreRenderer::setFov(float fov)
{
mCamera->setFOVy(Degree(fov));
}
SDL_Surface* OgreRenderer::ogreTextureToSDLSurface(const std::string& name)
void OgreRenderer::windowResized(int x, int y)
{
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().load(name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
if (texture.isNull())
{
std::stringstream error;
error << "Window icon not found: " << name;
throw std::runtime_error(error.str());
}
Ogre::Image image;
texture->convertToImage(image);
SDL_Surface* surface = SDL_CreateRGBSurface(0,texture->getWidth(),texture->getHeight(),32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF);
//copy the Ogre texture to an SDL surface
for(size_t x = 0; x < texture->getWidth(); ++x)
{
for(size_t y = 0; y < texture->getHeight(); ++y)
{
Ogre::ColourValue clr = image.getColourAt(x, y, 0);
//set the pixel on the SDL surface to the same value as the Ogre texture's
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
Uint32 pixel = SDL_MapRGBA(surface->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255);
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
}
return surface;
mWindowListener->windowResized(x,y);
}

@ -74,6 +74,12 @@ namespace OEngine
class Fader;
class WindowSizeListener
{
public:
virtual void windowResized (int x, int y) = 0;
};
class OgreRenderer
{
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
@ -83,7 +89,6 @@ namespace OEngine
#endif
Ogre::RenderWindow *mWindow;
SDL_Window *mSDLWindow;
SDL_Surface *mWindowIconSurface;
Ogre::SceneManager *mScene;
Ogre::Camera *mCamera;
Ogre::Viewport *mView;
@ -107,7 +112,7 @@ namespace OEngine
std::vector<Ogre::ParticleAffectorFactory*> mAffectorFactories;
bool logging;
SDL_Surface* ogreTextureToSDLSurface(const std::string& name);
WindowSizeListener* mWindowListener;
public:
OgreRenderer()
@ -117,7 +122,7 @@ namespace OEngine
, mScene(NULL)
, mCamera(NULL)
, mView(NULL)
, mWindowIconSurface(NULL)
, mWindowListener(NULL)
#ifdef ENABLE_PLUGIN_CgProgramManager
, mCgPlugin(NULL)
#endif
@ -140,9 +145,6 @@ namespace OEngine
~OgreRenderer() { cleanup(); }
void setWindowEventListener(Ogre::WindowEventListener* listener);
void removeWindowEventListener(Ogre::WindowEventListener* listener);
/** Configure the renderer. This will load configuration files and
set up the Root and logging classes. */
void configure(
@ -154,8 +156,6 @@ namespace OEngine
/// Create a window with the given title
void createWindow(const std::string &title, const WindowSettings& settings);
void recreateWindow (const std::string &title, const WindowSettings& settings);
/// Set up the scene manager, camera and viewport
void createScene(const std::string& camName="Camera",// Camera name
float fov=55, // Field of view angle
@ -181,6 +181,8 @@ namespace OEngine
float getFPS();
void windowResized(int x, int y);
/// Get the Root
Ogre::Root *getRoot() { return mRoot; }
@ -202,6 +204,8 @@ namespace OEngine
/// Viewport
Ogre::Viewport *getViewport() { return mView; }
void setWindowListener(WindowSizeListener* listener) { mWindowListener = listener; }
void adjustViewport();
};
}

Loading…
Cancel
Save