| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- /*
- -----------------------------------------------------------------------------
- This source file is part of OGRE
- (Object-oriented Graphics Rendering Engine)
- For the latest info, see http://www.ogre3d.org/
- Copyright (c) 2000-2011 Torus Knot Software Ltd
- 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 "CmSDLWindow.h"
- #include "CmRenderSystem.h"
- #include "CmException.h"
- #include "CmStringConverter.h"
- #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
- # include <windows.h>
- # include <wingdi.h>
- # include <GL/gl.h>
- # define GL_GLEXT_PROTOTYPES
- # include "glprocs.h"
- # include <GL/glu.h>
- #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
- # include <GL/gl.h>
- # include <GL/glu.h>
- #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
- # include <OpenGL/gl.h>
- # define GL_EXT_texture_env_combine 1
- # include <OpenGL/glext.h>
- # include <OpenGL/glu.h>
- #endif
- namespace CamelotEngine {
- SDLWindow::SDLWindow() :
- mScreen(NULL), mActive(false), mClosed(false)
- {
- }
- SDLWindow::~SDLWindow()
- {
- // according to http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode
- // never free the surface returned from SDL_SetVideoMode
- /*if (mScreen != NULL)
- SDL_FreeSurface(mScreen);*/
- }
- void SDLWindow::create(const String& name, unsigned int width, unsigned int height,
- bool fullScreen, const NameValuePairList *miscParams)
- {
- int colourDepth = 32;
- String title = name;
- if(miscParams)
- {
- // Parse miscellenous parameters
- NameValuePairList::const_iterator opt;
- // Bit depth
- opt = miscParams->find("colourDepth");
- if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it...
- colourDepth = StringConverter::parseUnsignedInt(opt->second);
- // Full screen antialiasing
- opt = miscParams->find("FSAA");
- if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it...
- {
- size_t fsaa_x_samples = StringConverter::parseUnsignedInt(opt->second);
- if(fsaa_x_samples>1) {
- // If FSAA is enabled in the parameters, enable the MULTISAMPLEBUFFERS
- // and set the number of samples before the render window is created.
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,fsaa_x_samples);
- }
- }
- // Window title
- opt = miscParams->find("title");
- if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it...
- title = opt->second;
- }
-
- LogManager::getSingleton().logMessage("SDLWindow::create", LML_TRIVIAL);
- SDL_Surface* screen;
- int flags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE;
-
- SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
- // request good stencil size if 32-bit colour
- if (colourDepth == 32)
- {
- SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8);
- }
-
- if (fullScreen)
- flags |= SDL_FULLSCREEN;
- LogManager::getSingleton().logMessage("Create window", LML_TRIVIAL);
- screen = SDL_SetVideoMode(width, height, colourDepth, flags);
- if (!screen)
- {
- LogManager::getSingleton().logMessage(LML_CRITICAL,
- String("Could not make screen: ") + SDL_GetError());
- exit(1);
- }
- LogManager::getSingleton().logMessage("screen is valid", LML_TRIVIAL);
- mScreen = screen;
- mName = name;
- mWidth = width;
- mHeight = height;
- mActive = true;
- if (!fullScreen)
- SDL_WM_SetCaption(title.c_str(), 0);
- glXGetVideoSyncSGI = (int (*)(unsigned int *))SDL_GL_GetProcAddress("glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (int (*)(int, int, unsigned int *))SDL_GL_GetProcAddress("glXWaitVideoSyncSGI");
- }
- void SDLWindow::destroy(void)
- {
- // according to http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode
- // never free the surface returned from SDL_SetVideoMode
- //SDL_FreeSurface(mScreen);
- mScreen = NULL;
- mActive = false;
- Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() );
- }
- bool SDLWindow::isActive() const
- {
- return mActive;
- }
- bool SDLWindow::isClosed() const
- {
- return mClosed;
- }
- void SDLWindow::reposition(int left, int top)
- {
- // XXX FIXME
- }
- void SDLWindow::resize(unsigned int width, unsigned int height)
- {
- SDL_Surface* screen;
- int flags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE;
-
- LogManager::getSingleton().logMessage("Updating window", LML_TRIVIAL);
- screen = SDL_SetVideoMode(width, height, mScreen->format->BitsPerPixel, flags);
- if (!screen)
- {
- LogManager::getSingleton().logMessage(LML_CRITICAL,
- String("Could not make screen: ") + SDL_GetError());
- exit(1);
- }
- LogManager::getSingleton().logMessage("screen is valid", LML_TRIVIAL);
- mScreen = screen;
- mWidth = width;
- mHeight = height;
- for (ViewportList::iterator it = mViewportList.begin();
- it != mViewportList.end(); ++it)
- {
- (*it).second->_updateDimensions();
- }
- }
- void SDLWindow::swapBuffers(bool waitForVSync)
- {
- if ( waitForVSync && glXGetVideoSyncSGI && glXWaitVideoSyncSGI )
- {
- unsigned int retraceCount;
- glXGetVideoSyncSGI( &retraceCount );
- glXWaitVideoSyncSGI( 2, ( retraceCount + 1 ) & 1, &retraceCount);
- }
- SDL_GL_SwapBuffers();
- // XXX More?
- }
- void SDLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer)
- {
- if ((dst.left < 0) || (dst.right > mWidth) ||
- (dst.top < 0) || (dst.bottom > mHeight) ||
- (dst.front != 0) || (dst.back != 1))
- {
- OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
- "Invalid box.",
- "SDLWindow::copyContentsToMemory" );
- }
-
- if (buffer == FB_AUTO)
- {
- buffer = mIsFullScreen? FB_FRONT : FB_BACK;
- }
-
- GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format);
- GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format);
-
- if ((format == GL_NONE) || (type == 0))
- {
- OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
- "Unsupported format.",
- "SDLWindow::copyContentsToMemory" );
- }
-
- glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
- glReadPixels((GLint)dst.left, (GLint)dst.top,
- (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
- format, type, dst.data);
-
- //vertical flip
- {
- size_t rowSpan = dst.getWidth() * PixelUtil::getNumElemBytes(dst.format);
- size_t height = dst.getHeight();
- uchar *tmpData = new uchar[rowSpan * height];
- uchar *srcRow = (uchar *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;
-
- while (tmpRow >= tmpData)
- {
- memcpy(tmpRow, srcRow, rowSpan);
- srcRow += rowSpan;
- tmpRow -= rowSpan;
- }
- memcpy(dst.data, tmpData, rowSpan * height);
-
- delete [] tmpData;
- }
- }
- }
|