Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreD3D7RenderWindow.cpp

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002 This source file is a part of OGRE
00003 (Object-oriented Graphics Rendering Engine)
00004 
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This library is free software; you can redistribute it and/or modify it
00011 under the terms of the GNU Lesser General Public License (LGPL) as 
00012 published by the Free Software Foundation; either version 2.1 of the 
00013 License, or (at your option) any later version.
00014 
00015 This library is distributed in the hope that it will be useful, but 
00016 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00017 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00018 License for more details.
00019 
00020 You should have received a copy of the GNU Lesser General Public License 
00021 along with this library; if not, write to the Free Software Foundation, 
00022 Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA or go to
00023 http://www.gnu.org/copyleft/lesser.txt
00024 -------------------------------------------------------------------------*/
00025 #include "OgreD3D7RenderWindow.h"
00026 
00027 #include "OgreLogManager.h"
00028 #include "OgreViewport.h"
00029 #include "OgreException.h"
00030 #include "OgreRoot.h"
00031 #include "OgreRenderSystem.h"
00032 #include "OgreD3D7TextureManager.h"
00033 #include "OgreBitwise.h"
00034 #include "OgreImageCodec.h"
00035 
00036 namespace Ogre {
00037 
00038 
00039     // Window procedure callback
00040     // This is a static member, so applies to all windows but we store the 
00041     // D3D7RenderWindow instance in the window data GetWindowLong/SetWindowLong.
00042     LRESULT D3D7RenderWindow::WndProc( 
00043         HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
00044     {
00045         LPCREATESTRUCT lpcs;
00046         D3D7RenderWindow* win;
00047 
00048         // look up window instance
00049         if (uMsg != WM_CREATE)
00050         {
00051             // Get window pointer
00052             win = (D3D7RenderWindow*)GetWindowLong(hWnd, 0);
00053         }
00054 
00055         switch( uMsg )
00056         {
00057             case WM_ACTIVATE:
00058                 if( LOWORD( wParam ) == WA_INACTIVE )
00059                     win->mActive = false;
00060                 else
00061                     win->mActive = true;
00062                 break;
00063 
00064             case WM_CREATE:
00065                 // Log the new window
00066                 // Get CREATESTRUCT
00067                 lpcs = (LPCREATESTRUCT)lParam;
00068                 win = (D3D7RenderWindow*)(lpcs->lpCreateParams);
00069                 // Store pointer in window user data area
00070                 SetWindowLong(hWnd, 0, (long)win);
00071                 win->mActive = true;
00072 
00073                 return 0;
00074 
00075             case WM_KEYDOWN:
00076                 // TEMPORARY CODE
00077                 // TODO - queue up keydown / keyup events with
00078                 //  window name and timestamp to be processed
00079                 //  by main loop
00080 
00081                 // ESCAPE closes window
00082                 //if (wParam == VK_ESCAPE)
00083                 //{
00084                 //    win->mClosed = true;
00085                 //    return 0L;
00086                 //}
00087                 break;
00088 
00089             case WM_PAINT:
00090                 // If we get WM_PAINT messages, it usually means our window was
00091                 // covered up, so we need to refresh it by re-showing the contents
00092                 // of the current frame.
00093                 if (win->mActive && win->mReady)
00094                     win->update();
00095                 break;
00096 
00097             case WM_MOVE:
00098                 // Move messages need to be tracked to update the screen rects
00099                 // used for blitting the backbuffer to the primary.
00100                 if(win->mActive && win->mReady)
00101                     win->windowMovedOrResized();
00102                 break;
00103 
00104             case WM_ENTERSIZEMOVE:
00105                 // Prevent rendering while moving / sizing
00106                 win->mReady = false;
00107                 break;
00108 
00109             case WM_EXITSIZEMOVE:
00110                 win->windowMovedOrResized();
00111                 win->mReady = true;
00112                 break;
00113 
00114             case WM_SIZE:
00115                 // Check to see if we are losing or gaining our window. Set the
00116                 // active flag to match.
00117                 if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
00118                     win->mActive = false;
00119                 else
00120                 {
00121                     win->mActive = true;
00122                     if (win->mReady)
00123                         win->windowMovedOrResized();
00124                 }
00125 
00126                 break;
00127 
00128             case WM_GETMINMAXINFO:
00129                 // Prevent the window from going smaller than some minimum size
00130                 ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
00131                 ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
00132                 break;
00133 
00134             case WM_CLOSE:
00135                 DestroyWindow( win->mHWnd );
00136                 win->mClosed = true;
00137                 return 0;
00138 
00139             /*
00140             case WM_DESTROY:
00141                 g_DIMSystem->CleanupRenderer();
00142                 PostQuitMessage(0);
00143                 return 0L;
00144             */
00145         }
00146 
00147 
00148 
00149         return DefWindowProc( hWnd, uMsg, wParam, lParam );
00150     }
00151 
00152     // -------------------------------------------
00153     // D3D7RenderWindow Implementation
00154     // -------------------------------------------
00155     D3D7RenderWindow::D3D7RenderWindow()
00156     {
00157         mIsUsingDirectDraw = false;
00158         mIsFullScreen = false;
00159         mlpDDDriver = 0;
00160         mHWnd = 0;
00161         mActive = false;
00162         mReady = false;
00163         mClosed = false;
00164     }
00165 
00166     D3D7RenderWindow::~D3D7RenderWindow()
00167     {
00168     }
00169 
00170 
00171 
00172 
00173     void D3D7RenderWindow::create(const String& name, unsigned int width, unsigned int height, unsigned int colourDepth,
00174             bool fullScreen, int left, int top, bool depthBuffer, void* miscParam, ...)
00175     {
00176 
00177         HWND parentHWnd;
00178         HINSTANCE hInst;
00179         DDDriver* drv;
00180         long tempPtr;
00181 
00182 
00183         // Get variable-length params
00184         // miscParam[0] = HINSTANCE
00185         // miscParam[1] = DDDriver
00186         // miscParam[2] = parent HWND
00187         va_list marker;
00188         va_start(marker, depthBuffer);
00189 
00190         tempPtr = va_arg(marker, long);
00191         hInst = *(HINSTANCE*)tempPtr;
00192 
00193         tempPtr = va_arg(marker, long);
00194         drv = (DDDriver*)tempPtr;
00195 
00196         tempPtr = va_arg(marker, long);
00197         D3D7RenderWindow* parentRW = (D3D7RenderWindow*)tempPtr;
00198         if (parentRW == 0)
00199         {
00200             parentHWnd = 0;
00201         }
00202         else
00203         {
00204             parentHWnd = parentRW->getWindowHandle();
00205         }
00206 
00207         va_end(marker);
00208 
00209         // Destroy current window if any
00210         if (mHWnd)
00211         {
00212             destroy();
00213         }
00214 
00215         // TODO: deal with child windows
00216         mParentHWnd = parentHWnd;
00217 
00218 
00219         // Register the window class
00220         // NB Allow 4 bytes of window data for D3D7RenderWindow pointer
00221         WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, WndProc, 0, 4, hInst,
00222                               LoadIcon( NULL, IDI_APPLICATION ),
00223                               LoadCursor(NULL, IDC_ARROW),
00224                               (HBRUSH)GetStockObject(BLACK_BRUSH), NULL,
00225                               TEXT(name.c_str()) };
00226         RegisterClass( &wndClass );
00227 
00228         // Create our main window
00229         // Pass pointer to self
00230         HWND hWnd = CreateWindow( TEXT(name.c_str()),
00231                                   TEXT(name.c_str()),
00232                                   WS_OVERLAPPEDWINDOW, left, top,
00233                                   width, height, 0L, 0L, hInst, this );
00234         ShowWindow( hWnd, SW_SHOWNORMAL );
00235         UpdateWindow( hWnd );
00236 
00237         mHWnd = hWnd;
00238 
00239         // Store info
00240         mName = name;
00241         mWidth = width;
00242         mHeight = height;
00243         mIsDepthBuffered = depthBuffer;
00244         mIsFullScreen = fullScreen;
00245 
00246         if (fullScreen)
00247         {
00248             mColourDepth = colourDepth;
00249             mLeft = 0;
00250             mTop = 0;
00251         }
00252         else
00253         {
00254             // Get colour depth from display
00255             HDC hdc = GetDC( mHWnd );
00256             mColourDepth = GetDeviceCaps( hdc, BITSPIXEL );
00257             ReleaseDC( mHWnd, hdc );
00258             mTop = top;
00259             mLeft = left;
00260 
00261             // Record the dimensions of the blit location
00262             GetClientRect( mHWnd, &rcBlitDest );
00263             ClientToScreen( mHWnd, (POINT*)&rcBlitDest.left );
00264             ClientToScreen( mHWnd, (POINT*)&rcBlitDest.right );
00265         }
00266 
00267         LogManager::getSingleton().logMessage( 
00268             LML_NORMAL, 
00269             "Created Win32 Rendering Window '%s': %i x %i @ %ibpp", 
00270             mName.c_str(), mWidth, mHeight, mColourDepth );
00271 
00272         // Set up DirectDraw if appropriate
00273         // NB devices & surfaces set up for root window only
00274         if (drv && mParentHWnd == NULL)
00275         {
00276             // DD Driver object passed
00277             mlpDDDriver = drv;
00278             mIsUsingDirectDraw = true;
00279 
00280             createDDSurfaces();
00281             // Get best device based on render bit depth
00282             D3DDevice* dev = mlpDDDriver->get3DDeviceList()->getBest(mColourDepth);
00283 
00284             // create D3D device for this window
00285             mlpD3DDevice = dev->createDevice(mlpDDSBack);
00286             createDepthBuffer();
00287         }
00288         else
00289             mIsUsingDirectDraw = false;
00290 
00291         mReady = true;
00292     }
00293 
00294     void D3D7RenderWindow::destroy(void)
00295     {
00296         if (mIsUsingDirectDraw)
00297             releaseDDSurfaces();
00298 
00299         DestroyWindow(mHWnd);
00300 
00301     }
00302 
00303     bool D3D7RenderWindow::isActive(void) const
00304     {
00305         return mActive;
00306     }
00307 
00308     bool D3D7RenderWindow::isClosed(void) const
00309     {
00310         return mClosed;
00311     }
00312 
00313     void D3D7RenderWindow::reposition(int left, int top)
00314     {
00315 
00316     }
00317 
00318     void D3D7RenderWindow::resize(unsigned int width, unsigned int height)
00319     {
00320         mWidth = width;
00321         mHeight = height;
00322 
00323         // Notify viewports of resize
00324         ViewportList::iterator it = mViewportList.begin();
00325         while (it != mViewportList.end())
00326             (*it++).second->_updateDimensions();
00327 
00328         // TODO - resize window
00329 
00330     }
00331 
00332     void D3D7RenderWindow::swapBuffers(bool waitForVSync)
00333     {
00334         HRESULT hr;
00335         DWORD flags;
00336         if (mIsUsingDirectDraw)
00337         {
00338             if (mIsFullScreen)
00339             {
00340                 // Use flipping chain
00341                 if (waitForVSync)
00342                 {
00343                     flags = DDFLIP_WAIT;
00344                 }
00345                 else
00346                 {
00347                     flags = DDFLIP_WAIT | DDFLIP_NOVSYNC;
00348                 }
00349 
00350                 hr = mlpDDSFront->Flip(NULL,flags);
00351             }
00352             else
00353             {
00354                 // Ordinary Blit
00355                 RECT srcRect;
00356                 srcRect.left = 0;
00357                 srcRect.top = 0;
00358                 srcRect.right = rcBlitDest.right - rcBlitDest.left;
00359                 srcRect.bottom = rcBlitDest.bottom - rcBlitDest.top;
00360                 hr = mlpDDSFront->Blt(&rcBlitDest,mlpDDSBack,&srcRect,DDBLT_WAIT,NULL);
00361             }
00362 
00363             if (hr == DDERR_SURFACELOST)
00364             {
00365                 // Restore surfaces
00366                 restoreDDSurfaces();
00367             }
00368             else if (FAILED(hr))
00369             {
00370                  Except( 
00371                      hr,
00372                      "Error flipping surfaces", 
00373                      "D3D7RenderWindow::swapBuffers" );
00374             }
00375         }
00376 
00377     }
00378 
00379     HWND D3D7RenderWindow::getWindowHandle(void) const
00380     {
00381         return mHWnd;
00382     }
00383 
00384     HWND D3D7RenderWindow::getParentWindowHandle(void) const
00385     {
00386         return mParentHWnd;
00387     }
00388 
00389     bool D3D7RenderWindow::isUsingDirectDraw(void) const
00390     {
00391         return mIsUsingDirectDraw;
00392     }
00393 
00394     // -------------------------------------------------------
00395     //   DirectDraw specific methods
00396     // -------------------------------------------------------
00397     DDDriver* D3D7RenderWindow::getDirectDrawDriver(void)
00398     {
00399         return mlpDDDriver;
00400     }
00401 
00402     LPDIRECTDRAWSURFACE7 D3D7RenderWindow::getDDFrontBuffer(void)
00403     {
00404         return mlpDDSFront;
00405 
00406     }
00407 
00408     LPDIRECTDRAWSURFACE7 D3D7RenderWindow::getDDBackBuffer(void)
00409     {
00410         return mlpDDSBack;
00411     }
00412     LPDIRECT3DDEVICE7 D3D7RenderWindow::getD3DDevice(void)
00413     {
00414         return mlpD3DDevice;
00415     }
00416 
00417     void D3D7RenderWindow::createDDSurfaces(void)
00418     {
00419         // Use DirectDraw wrapper object to create surfaces
00420         if( !mlpDDDriver )
00421         {
00422             Except(
00423             Exception::ERR_INVALIDPARAMS, 
00424             "Cannot create surfaces because of no valid DirectDraw object",
00425             "D3D7RenderWindow::createDDSurfaces" );
00426         }
00427 
00428         if( mIsFullScreen )
00429         {
00430             mlpDDDriver->createWindowSurfaces(
00431                 mHWnd, 
00432                 mWidth, mHeight, mColourDepth,
00433                 true, &mlpDDSFront, &mlpDDSBack);
00434         }
00435         else
00436         {
00437             // Windowed mode - need to use client rect for surface dimensions
00438             // I.e. we need to ignore menu bars, borders, title bar etc
00439             RECT rcClient;
00440             unsigned int cWidth, cHeight;
00441 
00442             GetClientRect( mHWnd, &rcClient );
00443             ClientToScreen( mHWnd, (POINT*)&rcClient.left );
00444             ClientToScreen( mHWnd, (POINT*)&rcClient.right );
00445 
00446             cWidth  = rcClient.right - rcClient.left;
00447             cHeight = rcClient.bottom - rcClient.top;
00448 
00449             // Create surfaces (AND clipper)
00450             mlpDDDriver->createWindowSurfaces(
00451                 mHWnd, 
00452                 cWidth, cHeight, 0,
00453                 false, &mlpDDSFront, &mlpDDSBack);
00454 
00455             // Update own dimensions since target width / height is this
00456             mWidth = cWidth;
00457             mHeight = cHeight;
00458         }
00459     }
00460 
00461     void D3D7RenderWindow::createDepthBuffer(void)
00462     {
00463         // Get best device based on render bit depth
00464         D3DDevice* dev = mlpDDDriver->get3DDeviceList()->getBest(mColourDepth);
00465         if (mIsDepthBuffered && dev->NeedsZBuffer())
00466         {
00467             // Create Z buffer
00468             dev->createDepthBuffer(mlpDDSBack);
00469             // Don't set z buffer params here, leave to material
00470         }
00471     }
00472 
00473     void D3D7RenderWindow::releaseDDSurfaces(void)
00474     {
00475         // Release Z-buffer
00476         HRESULT hr;
00477         DDSCAPS2 ddscaps;
00478 
00479         ZeroMemory(&ddscaps, sizeof(DDSCAPS2));
00480         ddscaps.dwCaps = DDSCAPS_ZBUFFER;
00481 
00482         LPDIRECTDRAWSURFACE7 zBufSurface;
00483 
00484         hr = mlpDDSBack->GetAttachedSurface( &ddscaps, &zBufSurface );
00485 
00486         // Release twice as this method has increased
00487         zBufSurface->Release();
00488         zBufSurface->Release();
00489 
00490         // Release std buffers
00491         mlpDDSBack->Release();
00492         mlpDDSFront->Release();
00493 
00494         mlpDDSBack = mlpDDSFront = 0;
00495     }
00496 
00497     void D3D7RenderWindow::restoreDDSurfaces(void)
00498     {
00499         HRESULT hr;
00500 
00501         if( mlpDDSFront->IsLost() )
00502         {
00503             hr = mlpDDSFront->Restore();
00504 
00505             if( FAILED( hr ) )
00506                 Except( 
00507                     Exception::ERR_INTERNAL_ERROR, 
00508                     "Error restoring lost primary surface.", 
00509                     "D3D7RenderWindow - restoreDDSurfaces" );
00510         }
00511 
00512         if( mlpDDSBack->IsLost() )
00513         {
00514             hr = mlpDDSBack->Restore();
00515 
00516             if( FAILED( hr ) )
00517                 Except( 
00518                     Exception::ERR_INTERNAL_ERROR, 
00519                     "Error restoring lost back buffer surface.", 
00520                     "D3D7RenderWindow - restoreDDSurfaces" );
00521         }
00522     }
00523 
00524     void D3D7RenderWindow::windowMovedOrResized(void)
00525     {
00526         // If windowed mode, check window size & position
00527         RECT rcCheck;
00528 
00529         if( mIsFullScreen )
00530             return; // Nothing to check
00531 
00532         GetClientRect( mHWnd, &rcCheck );
00533         ClientToScreen( mHWnd, (POINT*)&rcCheck.left );
00534         ClientToScreen( mHWnd, (POINT*)&rcCheck.right );
00535 
00536         // Has the window resized? If so, we need to recreate surfaces
00537         if( ( rcCheck.right - rcCheck.left != 
00538                 rcBlitDest.right - rcBlitDest.left ) ||
00539             ( rcCheck.bottom - rcCheck.top !=
00540                 rcBlitDest.bottom - rcBlitDest.top ) )
00541         {
00542             // The window has changed size - DD surfaces must be recreated
00543             releaseDDSurfaces();
00544             createDDSurfaces();
00545             createDepthBuffer();
00546 
00547             // Update Viewport Sizes
00548             
00549             for( 
00550                 ViewportList::iterator it = mViewportList.begin();
00551                 it != mViewportList.end(); 
00552                 ++it )
00553             {
00554                 it->second->_updateDimensions();
00555             }
00556 
00557             rcBlitDest = rcCheck;
00558         }
00559         else if( 
00560             rcCheck.left != rcBlitDest.left ||
00561             rcCheck.top  != rcBlitDest.top )
00562         {
00563             // Window has only moved
00564             // Just alter the blit location
00565             rcBlitDest = rcCheck;
00566         }
00567     }
00568 
00569     //-----------------------------------------------------------------------
00570     void D3D7RenderWindow::getCustomAttribute( const String& name, void* pData )
00571     {
00572         // Valid attributes and their equivalent native functions:
00573         // D3DDEVICE            : getD3DDeviceDriver
00574         // DDBACKBUFFER         : getDDBackBuffer
00575         // DDFRONTBUFFER        : getDDFrontBuffer
00576         // HWND                 : getWindowHandle
00577 
00578         if( name == "D3DDEVICE" )
00579         {
00580             LPDIRECT3DDEVICE7 *pDev = (LPDIRECT3DDEVICE7*)pData;
00581 
00582             *pDev = getD3DDevice();
00583             return;
00584         }
00585         else if( name == "DDBACKBUFFER" )
00586         {
00587             LPDIRECTDRAWSURFACE7 *pSurf = (LPDIRECTDRAWSURFACE7*)pData;
00588 
00589             *pSurf = getDDBackBuffer();
00590             return;
00591         }
00592         else if( name == "DDFRONTBUFFER" )
00593         {
00594             LPDIRECTDRAWSURFACE7 *pSurf = (LPDIRECTDRAWSURFACE7*)pData;
00595 
00596             *pSurf = getDDFrontBuffer();
00597             return;
00598         }
00599         else if( name == "HWND" )
00600         {
00601             HWND *pHwnd = (HWND*)pData;
00602 
00603             *pHwnd = getWindowHandle();
00604             return;
00605         }
00606         else if( name == "isTexture" )
00607         {
00608             bool *b = reinterpret_cast< bool * >( pData );
00609             *b = false;
00610 
00611             return;
00612         }
00613     }
00614 
00615 
00616     void D3D7RenderWindow::writeContentsToFile(const String& filename)
00617     {
00618          HRESULT hr;
00619          LPDIRECTDRAWSURFACE7 pTempSurf;
00620          DDSURFACEDESC2 desc;
00621          RECT srcRect;
00622  
00623          // Cannot lock surface direct, so create temp surface and blit
00624          memset(&desc, 0, sizeof (DDSURFACEDESC2));
00625          desc.dwSize = sizeof(DDSURFACEDESC2);
00626          if (FAILED(hr = mlpDDSBack->GetSurfaceDesc(&desc)))
00627          {
00628              Except(hr, "Error getting description of back buffer!", 
00629                  "D3D7RenderWindow::writeContentsToFile");
00630          }
00631 
00632          desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
00633          desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
00634 
00635          if (FAILED(hr = mlpDDDriver->directDraw()->CreateSurface(&desc, &pTempSurf, NULL)))
00636          {
00637              Except(hr, "Error creating temporary surface!", 
00638                  "D3D7RenderWindow::writeContentsToFile");
00639          }
00640 
00641          if (mIsFullScreen)
00642          {
00643             pTempSurf->Blt(NULL, mlpDDSFront, NULL, NULL, NULL);
00644          }
00645          else
00646          {
00647             GetWindowRect(mHWnd, &srcRect);
00648             srcRect.left += GetSystemMetrics(SM_CXSIZEFRAME);
00649             srcRect.top += GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
00650             srcRect.right = srcRect.left + desc.dwWidth;
00651             srcRect.bottom = srcRect.top + desc.dwHeight;
00652 
00653             pTempSurf->Blt(NULL, mlpDDSFront, &srcRect, NULL, NULL);
00654          }
00655 
00656          if (FAILED(hr = pTempSurf->Lock(NULL, &desc,  
00657              DDLOCK_WAIT | DDLOCK_READONLY, NULL)))
00658          {
00659              Except(hr, "Cannot lock surface!", 
00660                  "D3D7RenderWindow::writeContentsToFile");
00661          }
00662  
00663  
00664          ImageCodec::ImageData imgData;
00665          imgData.width = desc.dwWidth;
00666          imgData.height = desc.dwHeight;
00667          imgData.format = PF_R8G8B8;
00668  
00669          // Allocate contiguous buffer (surfaces aren't necessarily contiguous)
00670          uchar* pBuffer = new uchar[desc.dwWidth * desc.dwHeight * 3];
00671  
00672          uint x, y;
00673          uchar *pData, *pDest;
00674  
00675          pData = (uchar*)desc.lpSurface;
00676          pDest = pBuffer;
00677          for (y = 0; y < desc.dwHeight; ++y)
00678          {
00679              uchar *pRow = pData;
00680  
00681              for (x = 0; x < desc.dwWidth; ++x)
00682              {
00683                  if (desc.ddpfPixelFormat.dwRGBBitCount == 16)
00684                  {
00685                      WORD val;
00686  
00687                      val = *((WORD*)pRow);
00688                      pRow += 2;
00689 
00690                      *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0xF800, (BYTE)0xFF);
00691                      *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x07E0, (BYTE)0xFF);
00692                      *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x001F, (BYTE)0xFF);
00693                  }
00694                  else
00695                  {
00696                      // Actual format is BRGA for some reason
00697                      *pDest++ = pRow[2]; // R
00698                      *pDest++ = pRow[1]; // G
00699                      *pDest++ = pRow[0]; // B
00700 
00701                      pRow += 3; // skip alpha / dummy
00702 
00703                      if (desc.ddpfPixelFormat.dwRGBBitCount == 32)
00704                      {
00705                          ++pRow; // Skip alpha
00706                      }
00707                  }
00708  
00709                  
00710              }
00711              // increase by one line
00712              pData += desc.lPitch;
00713  
00714          }
00715  
00716  
00717          // Wrap buffer in a chunk
00718          DataChunk chunk(pBuffer, desc.dwWidth * desc.dwHeight * 3);
00719  
00720          // Get codec 
00721          size_t pos = filename.find_last_of(".");
00722          String extension;
00723         if( pos == String::npos )
00724              Except(
00725             Exception::ERR_INVALIDPARAMS, 
00726             "Unable to determine image type for '" + filename + "' - invalid extension.",
00727              "D3D8RenderWindow::writeContentsToFile" );
00728  
00729          while( pos != filename.length() - 1 )
00730              extension += filename[++pos];
00731  
00732          // Get the codec
00733          Codec * pCodec = Codec::getCodec(extension);
00734  
00735          // Write out
00736          pCodec->codeToFile(chunk, filename, &imgData);
00737  
00738          delete [] pBuffer;
00739          pTempSurf->Release();
00740  
00741      }
00742 
00743 }
00744 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:19 2004