2010-07-09 19:21:04 +00:00
|
|
|
#include "renderer.hpp"
|
|
|
|
|
2013-01-14 01:32:45 +00:00
|
|
|
#include <SDL.h>
|
|
|
|
|
2013-10-30 13:04:33 +00:00
|
|
|
#include <OgreRoot.h>
|
|
|
|
#include <OgreRenderWindow.h>
|
|
|
|
#include <OgreTextureManager.h>
|
|
|
|
#include <OgreTexture.h>
|
|
|
|
#include <OgreHardwarePixelBuffer.h>
|
2014-01-09 19:56:24 +00:00
|
|
|
#include <OgreCamera.h>
|
2014-02-19 17:40:29 +00:00
|
|
|
#include <OgreViewport.h>
|
2012-07-27 21:53:50 +00:00
|
|
|
|
2013-07-29 00:32:08 +00:00
|
|
|
#include <extern/sdl4ogre/sdlwindowhelper.hpp>
|
|
|
|
|
2013-12-26 14:57:54 +00:00
|
|
|
#include <components/ogreinit/ogreinit.hpp>
|
|
|
|
|
2014-05-19 18:56:40 +00:00
|
|
|
#include <boost/filesystem/path.hpp>
|
|
|
|
#include <boost/filesystem/fstream.hpp>
|
|
|
|
|
2012-07-17 07:44:24 +00:00
|
|
|
#include <cassert>
|
2012-05-30 21:18:59 +00:00
|
|
|
#include <stdexcept>
|
2010-07-09 19:21:04 +00:00
|
|
|
|
|
|
|
using namespace Ogre;
|
2010-07-10 11:41:43 +00:00
|
|
|
using namespace OEngine::Render;
|
2010-07-09 19:21:04 +00:00
|
|
|
|
2013-06-16 12:25:13 +00:00
|
|
|
|
2010-07-09 19:21:04 +00:00
|
|
|
void OgreRenderer::cleanup()
|
|
|
|
{
|
2014-01-01 21:19:02 +00:00
|
|
|
if (mWindow)
|
|
|
|
Ogre::Root::getSingleton().destroyRenderTarget(mWindow);
|
2013-12-26 14:57:54 +00:00
|
|
|
mWindow = NULL;
|
|
|
|
|
|
|
|
delete mOgreInit;
|
|
|
|
mOgreInit = NULL;
|
|
|
|
|
2013-06-12 12:58:07 +00:00
|
|
|
// If we don't do this, the desktop resolution is not restored on exit
|
|
|
|
SDL_SetWindowFullscreen(mSDLWindow, 0);
|
|
|
|
|
2013-01-14 01:32:45 +00:00
|
|
|
SDL_DestroyWindow(mSDLWindow);
|
|
|
|
mSDLWindow = NULL;
|
2012-09-17 09:57:29 +00:00
|
|
|
}
|
|
|
|
|
2012-02-18 17:25:02 +00:00
|
|
|
void OgreRenderer::update(float dt)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-09-11 02:28:14 +00:00
|
|
|
void OgreRenderer::screenshot(const std::string &file, const std::string& imageFormat)
|
2010-07-09 19:21:04 +00:00
|
|
|
{
|
2014-05-22 12:35:57 +00:00
|
|
|
/* Since Ogre uses narrow character interfaces, it does not support
|
|
|
|
Unicode paths on Windows. Therefore we had to implement screenshot
|
|
|
|
saving manually.
|
|
|
|
*/
|
2014-05-19 18:56:40 +00:00
|
|
|
namespace bfs = boost::filesystem;
|
2014-05-20 04:14:29 +00:00
|
|
|
bfs::ofstream out(bfs::path(file), std::ios::binary);
|
2014-05-19 18:56:40 +00:00
|
|
|
|
|
|
|
Ogre::Image image;
|
|
|
|
|
|
|
|
Ogre::PixelFormat pf = mWindow->suggestPixelFormat();
|
|
|
|
int w = mWindow->getWidth();
|
|
|
|
int h = mWindow->getHeight();
|
|
|
|
|
|
|
|
image.loadDynamicImage(
|
|
|
|
OGRE_ALLOC_T(Ogre::uchar, w * h * Ogre::PixelUtil::getNumElemBytes(pf), Ogre::MEMCATEGORY_GENERAL),
|
|
|
|
w, h, 1, pf, true
|
|
|
|
);
|
|
|
|
mWindow->copyContentsToMemory(image.getPixelBox());
|
|
|
|
|
2014-09-11 02:28:14 +00:00
|
|
|
Ogre::DataStreamPtr stream = image.encode(imageFormat);
|
2014-05-19 18:56:40 +00:00
|
|
|
Ogre::MemoryDataStream *mem = dynamic_cast<Ogre::MemoryDataStream *>(stream.get());
|
|
|
|
if (mem != 0) { // likely
|
|
|
|
const char *ptr = reinterpret_cast<char *>(mem->getCurrentPtr());
|
|
|
|
out.write(ptr, mem->size());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
char buf[4096];
|
|
|
|
size_t size = stream->size();
|
|
|
|
while (size > 0) {
|
|
|
|
size_t chunk = (size > sizeof(buf)) ? sizeof(buf) : size;
|
|
|
|
stream->read(buf, chunk);
|
|
|
|
out.write(buf, chunk);
|
|
|
|
size -= chunk;
|
|
|
|
}
|
|
|
|
}
|
2010-07-09 19:21:04 +00:00
|
|
|
}
|
|
|
|
|
2012-05-22 01:36:03 +00:00
|
|
|
void OgreRenderer::configure(const std::string &logPath,
|
|
|
|
const std::string& renderSystem,
|
2013-10-30 13:04:33 +00:00
|
|
|
const std::string& rttMode
|
|
|
|
)
|
2010-07-09 19:21:04 +00:00
|
|
|
{
|
2013-12-26 14:57:54 +00:00
|
|
|
mOgreInit = new OgreInit::OgreInit();
|
|
|
|
mRoot = mOgreInit->init(logPath + "/ogre.log");
|
2012-07-20 14:44:03 +00:00
|
|
|
|
2012-05-22 01:36:03 +00:00
|
|
|
RenderSystem* rs = mRoot->getRenderSystemByName(renderSystem);
|
|
|
|
if (rs == 0)
|
|
|
|
throw std::runtime_error ("RenderSystem with name " + renderSystem + " not found, make sure the plugins are loaded");
|
|
|
|
mRoot->setRenderSystem(rs);
|
2012-09-19 17:34:02 +00:00
|
|
|
|
|
|
|
if (rs->getName().find("OpenGL") != std::string::npos)
|
|
|
|
rs->setConfigOption ("RTT Preferred Mode", rttMode);
|
2011-01-04 00:03:05 +00:00
|
|
|
}
|
|
|
|
|
2012-05-22 01:36:03 +00:00
|
|
|
void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings)
|
2011-01-04 00:03:05 +00:00
|
|
|
{
|
2012-05-22 01:36:03 +00:00
|
|
|
assert(mRoot);
|
|
|
|
mRoot->initialise(false);
|
2011-01-04 00:03:05 +00:00
|
|
|
|
2012-05-22 01:36:03 +00:00
|
|
|
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"));
|
|
|
|
|
2013-07-29 10:38:57 +00:00
|
|
|
int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(settings.screen),
|
|
|
|
pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(settings.screen);
|
2013-07-01 02:08:26 +00:00
|
|
|
|
|
|
|
if(settings.fullscreen)
|
|
|
|
{
|
2013-07-29 10:38:57 +00:00
|
|
|
pos_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(settings.screen);
|
|
|
|
pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(settings.screen);
|
2013-07-01 02:08:26 +00:00
|
|
|
}
|
2013-07-01 01:56:33 +00:00
|
|
|
|
2013-07-29 10:38:57 +00:00
|
|
|
|
2013-01-14 01:32:45 +00:00
|
|
|
// Create an application window with the following settings:
|
2013-01-14 03:38:46 +00:00
|
|
|
mSDLWindow = SDL_CreateWindow(
|
2013-07-29 10:38:57 +00:00
|
|
|
"OpenMW", // window title
|
|
|
|
pos_x, // initial x position
|
|
|
|
pos_y, // initial y position
|
|
|
|
settings.window_x, // width, in pixels
|
|
|
|
settings.window_y, // height, in pixels
|
2013-06-15 13:33:47 +00:00
|
|
|
SDL_WINDOW_SHOWN
|
2014-12-22 01:16:30 +00:00
|
|
|
| SDL_WINDOW_RESIZABLE
|
|
|
|
| (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0)
|
|
|
|
| (settings.borderless ? SDL_WINDOW_BORDERLESS : 0)
|
2013-01-14 01:32:45 +00:00
|
|
|
);
|
|
|
|
|
2013-07-29 00:32:08 +00:00
|
|
|
SFO::SDLWindowHelper helper(mSDLWindow, settings.window_x, settings.window_y, title, settings.fullscreen, params);
|
2013-06-12 14:15:04 +00:00
|
|
|
if (settings.icon != "")
|
2013-07-29 00:32:08 +00:00
|
|
|
helper.setWindowIcon(settings.icon);
|
|
|
|
mWindow = helper.getWindow();
|
|
|
|
|
2013-06-12 14:15:04 +00:00
|
|
|
|
2012-05-22 23:32:36 +00:00
|
|
|
// create the semi-transparent black background texture used by the GUI.
|
2012-09-13 17:03:31 +00:00
|
|
|
// has to be created in code with TU_DYNAMIC_WRITE_ONLY param
|
2012-08-02 12:57:35 +00:00
|
|
|
// so that it can be modified at runtime.
|
2012-06-26 17:10:47 +00:00
|
|
|
Ogre::TextureManager::getSingleton().createManual(
|
2012-05-22 23:32:36 +00:00
|
|
|
"transparent.png",
|
|
|
|
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
|
|
Ogre::TEX_TYPE_2D,
|
|
|
|
1, 1,
|
|
|
|
0,
|
|
|
|
Ogre::PF_A8R8G8B8,
|
2013-01-05 04:26:33 +00:00
|
|
|
Ogre::TU_WRITE_ONLY);
|
2010-07-09 19:21:04 +00:00
|
|
|
|
2012-05-22 01:36:03 +00:00
|
|
|
mScene = mRoot->createSceneManager(ST_GENERIC);
|
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
mCamera = mScene->createCamera("cam");
|
2012-05-22 01:36:03 +00:00
|
|
|
|
|
|
|
// Create one viewport, entire window
|
|
|
|
mView = mWindow->addViewport(mCamera);
|
|
|
|
// Alter the camera aspect ratio to match the viewport
|
|
|
|
mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight()));
|
2013-08-27 13:48:13 +00:00
|
|
|
}
|
2012-05-22 01:36:03 +00:00
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
void OgreRenderer::adjustCamera(float fov, float nearClip)
|
|
|
|
{
|
|
|
|
mCamera->setNearClipDistance(nearClip);
|
|
|
|
mCamera->setFOVy(Degree(fov));
|
2010-07-09 19:21:04 +00:00
|
|
|
}
|
2012-05-27 19:39:18 +00:00
|
|
|
|
2012-05-28 07:19:25 +00:00
|
|
|
void OgreRenderer::adjustViewport()
|
2012-05-27 19:39:18 +00:00
|
|
|
{
|
|
|
|
// Alter the camera aspect ratio to match the viewport
|
2013-01-14 01:32:45 +00:00
|
|
|
if(mCamera != NULL)
|
|
|
|
{
|
|
|
|
mView->setDimensions(0, 0, 1, 1);
|
|
|
|
mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight()));
|
|
|
|
}
|
2012-05-27 19:39:18 +00:00
|
|
|
}
|
|
|
|
|
2012-05-29 02:54:54 +00:00
|
|
|
void OgreRenderer::setFov(float fov)
|
|
|
|
{
|
|
|
|
mCamera->setFOVy(Degree(fov));
|
|
|
|
}
|
2013-06-12 14:15:04 +00:00
|
|
|
|
2013-07-29 00:32:08 +00:00
|
|
|
void OgreRenderer::windowResized(int x, int y)
|
2013-06-12 14:15:04 +00:00
|
|
|
{
|
2014-03-29 14:49:48 +00:00
|
|
|
if (mWindowListener) {
|
2014-03-27 19:39:56 +00:00
|
|
|
mWindowListener->windowResized(x,y);
|
2014-03-29 14:49:48 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
mWindowWidth = x;
|
|
|
|
mWindowHeight = y;
|
|
|
|
mOutstandingResize = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OgreRenderer::setWindowListener(WindowSizeListener* listener)
|
|
|
|
{
|
|
|
|
mWindowListener = listener;
|
|
|
|
if (mOutstandingResize) {
|
|
|
|
windowResized(mWindowWidth, mWindowHeight);
|
|
|
|
mOutstandingResize = false;
|
|
|
|
}
|
2013-06-12 14:15:04 +00:00
|
|
|
}
|