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

OgreD3D9RenderWindow.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
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 program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreD3D9RenderWindow.h"
00026 #include "OgreLogManager.h"
00027 #include "OgreViewport.h"
00028 #include "OgreException.h"
00029 #include "OgreRenderSystem.h"
00030 #include "OgreBitwise.h"
00031 #include "OgreImageCodec.h"
00032 
00033 #include "OgreNoMemoryMacros.h"
00034 #include <d3d9.h>
00035 #include "OgreMemoryMacros.h"
00036 #include "OgreRoot.h"
00037 
00038 namespace Ogre
00039 {
00040     // Window procedure callback
00041     // This is a static member, so applies to all windows but we store the
00042     // D3D9RenderWindow instance in the window data GetWindowLog/SetWindowLog
00043     LRESULT D3D9RenderWindow::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
00044     {
00045         LPCREATESTRUCT lpcs;
00046         D3D9RenderWindow* win;
00047 
00048         // look up window instance
00049         if( WM_CREATE != uMsg )
00050             // Get window pointer
00051             win = (D3D9RenderWindow*)GetWindowLong( hWnd, 0 );
00052 
00053         switch( uMsg )
00054         {
00055         case WM_ACTIVATE:
00056             if( WA_INACTIVE == LOWORD( wParam ) )
00057                 win->mActive = false;
00058             else
00059                 win->mActive = true;
00060             break;
00061 
00062         case WM_CREATE:
00063             // Log the new window
00064             // Get CREATESTRUCT
00065             lpcs = (LPCREATESTRUCT)lParam;
00066             win = (D3D9RenderWindow*)(lpcs->lpCreateParams);
00067             // Store pointer in window user data area
00068             SetWindowLong( hWnd, 0, (long)win );
00069             win->mActive = true;
00070 
00071             return 0;
00072             break;
00073 
00074         case WM_KEYDOWN:
00075             // TEMPORARY CODE
00076             // TODO - queue up keydown / keyup events with
00077             //  window name and timestamp to be processed
00078             //  by main loop
00079 
00080             // ESCAPE closes window
00081             /*
00082             if (wParam == VK_ESCAPE)
00083             {
00084             win->mClosed = true;
00085             return 0L;
00086             }
00087             */
00088             break;
00089 
00090         case WM_PAINT:
00091             // If we get WM_PAINT messges, it usually means our window was
00092             // comvered up, so we need to refresh it by re-showing the contents
00093             // of the current frame.
00094             if( win->mActive && win->mReady )
00095                 win->update();
00096             break;
00097 
00098         case WM_MOVE:
00099             // Move messages need to be tracked to update the screen rects
00100             // used for blitting the backbuffer to the primary
00101             // *** This doesn't need to be used to Direct3D9 ***
00102             break;
00103 
00104         case WM_ENTERSIZEMOVE:
00105             // Previent 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             break;
00126 
00127         case WM_GETMINMAXINFO:
00128             // Prevent the window from going smaller than some minimu size
00129             ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
00130             ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
00131             break;
00132 
00133         case WM_CLOSE:
00134             DestroyWindow( win->mHWnd );
00135             win->mClosed = true;
00136             return 0;
00137         }
00138 
00139         return DefWindowProc( hWnd, uMsg, wParam, lParam );
00140     }
00141 
00142     D3D9RenderWindow::D3D9RenderWindow()
00143     {
00144         mIsFullScreen = false;
00145         mpD3DDriver= NULL;
00146         mpD3DDevice = NULL;
00147         mHWnd = 0;
00148         mActive = false;
00149         mReady = false;
00150         mClosed = false;
00151         mExternalHandle = NULL;
00152     }
00153 
00154     D3D9RenderWindow::~D3D9RenderWindow()
00155     {
00156         SAFE_RELEASE( mpRenderSurface );
00157         SAFE_RELEASE( mpRenderZBuffer );
00158         SAFE_RELEASE( mpD3DDevice );
00159     }
00160 
00161     bool D3D9RenderWindow::_checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen)
00162     {
00163         LPDIRECT3D9 pD3D = mpD3DDriver->getD3D();
00164 
00165         if (SUCCEEDED(pD3D->CheckDeviceMultiSampleType(
00166                 adapterNum, 
00167                 deviceType, format, 
00168                 fullScreen, type, outQuality)))
00169             return true;
00170         else
00171             return false;
00172     }
00173 
00174     void D3D9RenderWindow::create( const String& name, unsigned int width, unsigned int height, unsigned int colourDepth, 
00175         bool fullScreen, int left, int top, bool depthBuffer, void* miscParam, ... )
00176     {
00177         HWND parentHWnd;
00178         HINSTANCE hInst;
00179         D3D9Driver* driver;
00180         long tempPtr;
00181         
00182         D3DMULTISAMPLE_TYPE mFSAAType = D3DMULTISAMPLE_NONE;
00183         DWORD mFSAAQuality = 0;
00184         // Get variable-length params
00185         // miscParam[0] = HINSTANCE
00186         // miscParam[1] = D3D9Driver
00187         // miscParam[2] = parent HWND
00188         // miscParam[3] = multisample type
00189         // miscParam[4] = multisample quality
00190         // miscParam[5] = vsync
00191 
00192         va_list marker;
00193         va_start( marker, depthBuffer );
00194 
00195         tempPtr = va_arg( marker, long );
00196         hInst = *(HINSTANCE*)tempPtr;
00197 
00198         tempPtr = va_arg( marker, long );
00199         driver = (D3D9Driver*)tempPtr;
00200 
00201         tempPtr = va_arg( marker, long );
00202         D3D9RenderWindow* parentRW = (D3D9RenderWindow*)tempPtr;
00203         if( parentRW == NULL )
00204             parentHWnd = 0;
00205         else
00206             parentHWnd = parentRW->getWindowHandle();
00207 
00208         tempPtr = va_arg( marker, long );
00209         mFSAAType = (D3DMULTISAMPLE_TYPE)tempPtr;
00210 
00211         tempPtr = va_arg( marker, long );
00212         mFSAAQuality = (DWORD)tempPtr;
00213 
00214         tempPtr = va_arg( marker, long );
00215         bool vsync = tempPtr ? true : false;
00216 
00217         va_end( marker );
00218 
00219         // Destroy current window if any
00220         if( mHWnd )
00221             destroy();
00222 
00223         // track the parent window handle
00224         mParentHWnd = parentHWnd;
00225 
00226         if (!mExternalHandle)
00227         {
00228             mWidth = width;
00229             mHeight = height;
00230             if (!fullScreen)
00231             {
00232                 if (!left && (unsigned)GetSystemMetrics(SM_CXSCREEN) > mWidth)
00233                     mLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (mWidth / 2);
00234                 else
00235                     mLeft = left;
00236                 if (!top && (unsigned)GetSystemMetrics(SM_CYSCREEN) > mHeight)
00237                     mTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (mHeight / 2);
00238                 else
00239                     mTop = top;
00240             }
00241             else
00242                 mTop = mLeft = 0;
00243 
00244             // Register the window class
00245             // NB allow 4 bytes of window data for D3D9RenderWindow pointer
00246             WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, WndProc, 0, 4, hInst,
00247                 LoadIcon( NULL, IDI_APPLICATION ),
00248                 LoadCursor( NULL, IDC_ARROW ),
00249                 (HBRUSH)GetStockObject( BLACK_BRUSH ), NULL,
00250                 TEXT(name.c_str()) };
00251             RegisterClass( &wndClass );
00252 
00253             // Create our main window
00254             // Pass pointer to self
00255             HWND hWnd = CreateWindow(TEXT(name.c_str()),
00256                                      TEXT(name.c_str()),
00257                                      WS_OVERLAPPEDWINDOW, mLeft, mTop,
00258                                      mWidth, mHeight, 0L, 0L, hInst, this);
00259             ShowWindow(hWnd, SW_SHOWNORMAL);
00260             UpdateWindow(hWnd);
00261 
00262             mHWnd = hWnd;
00263             // Store info
00264             mName = name;
00265             mIsDepthBuffered = depthBuffer;
00266             mIsFullScreen = fullScreen;
00267         }
00268         else
00269         {
00270             mHWnd = mExternalHandle;
00271             ShowWindow(mHWnd, SW_SHOWNORMAL);
00272             UpdateWindow(mHWnd);
00273             RECT rc;
00274             GetClientRect(mHWnd,&rc);
00275             mWidth = rc.right;
00276             mHeight = rc.bottom;
00277             mLeft = rc.left;
00278             mTop = rc.top;
00279             mName = name;
00280             mIsDepthBuffered = depthBuffer;
00281             mIsFullScreen = fullScreen;
00282         }
00283 
00284         // track colour depth
00285         mColourDepth = colourDepth;
00286 
00287         LogManager::getSingleton().logMessage(
00288             LML_NORMAL, "D3D9 : Created D3D9 Rendering Window '%s' : %ix%i, %ibpp",
00289             mName.c_str(), mWidth, mHeight, mColourDepth );
00290 
00291         if( driver && mParentHWnd == NULL )
00292         {
00293             mpD3DDriver = driver;
00294             HRESULT hr;
00295             LPDIRECT3D9 pD3D = mpD3DDriver->getD3D();
00296             D3DDEVTYPE devType = D3DDEVTYPE_HAL;
00297 
00298             ZeroMemory( &md3dpp, sizeof(D3DPRESENT_PARAMETERS) );
00299             md3dpp.Windowed                 = !fullScreen;
00300             md3dpp.SwapEffect               = D3DSWAPEFFECT_DISCARD;
00301             md3dpp.BackBufferCount          = 1;
00302             md3dpp.EnableAutoDepthStencil   = depthBuffer;
00303             md3dpp.hDeviceWindow            = mHWnd;
00304             md3dpp.BackBufferWidth          = mWidth;
00305             md3dpp.BackBufferHeight         = mHeight;
00306 
00307             if (vsync)
00308                 md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
00309             else
00310                 md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
00311 
00312             md3dpp.BackBufferFormat     = D3DFMT_R5G6B5;
00313             if( mColourDepth > 16 )
00314                 md3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
00315 
00316             if (mColourDepth > 16 )
00317             {
00318                 // Try to create a 32-bit depth, 8-bit stencil
00319                 if( FAILED( pD3D->CheckDeviceFormat(mpD3DDriver->getAdapterNumber(),
00320                     devType,  md3dpp.BackBufferFormat,  D3DUSAGE_DEPTHSTENCIL, 
00321                     D3DRTYPE_SURFACE, D3DFMT_D24S8 )))
00322                 {
00323                     // Bugger, no 8-bit hardware stencil, just try 32-bit zbuffer 
00324                     if( FAILED( pD3D->CheckDeviceFormat(mpD3DDriver->getAdapterNumber(),
00325                         devType,  md3dpp.BackBufferFormat,  D3DUSAGE_DEPTHSTENCIL, 
00326                         D3DRTYPE_SURFACE, D3DFMT_D32 )))
00327                     {
00328                         // Jeez, what a naff card. Fall back on 16-bit depth buffering
00329                         md3dpp.AutoDepthStencilFormat = D3DFMT_D16;
00330                     }
00331                     else
00332                         md3dpp.AutoDepthStencilFormat = D3DFMT_D32;
00333                 }
00334                 else
00335                 {
00336                     // Woohoo!
00337                     if( SUCCEEDED( pD3D->CheckDepthStencilMatch( mpD3DDriver->getAdapterNumber(), devType,
00338                         md3dpp.BackBufferFormat, md3dpp.BackBufferFormat, D3DFMT_D24S8 ) ) )
00339                     {
00340                         md3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; 
00341                     } 
00342                     else 
00343                         md3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; 
00344                 }
00345             }
00346             else
00347                 // 16-bit depth, software stencil
00348                 md3dpp.AutoDepthStencilFormat   = D3DFMT_D16;
00349 
00350             md3dpp.MultiSampleType = mFSAAType;
00351             md3dpp.MultiSampleQuality = (mFSAAQuality == 0) ? NULL : mFSAAQuality;
00352 
00353             hr = pD3D->CreateDevice( mpD3DDriver->getAdapterNumber(), devType, mHWnd,
00354                 D3DCREATE_HARDWARE_VERTEXPROCESSING, &md3dpp, &mpD3DDevice );
00355             if( SUCCEEDED( hr ) )
00356             {
00357                 mpD3DDevice->GetRenderTarget( 0, &mpRenderSurface );
00358                 mpD3DDevice->GetDepthStencilSurface( &mpRenderZBuffer );
00359             }
00360             else
00361             {
00362                 hr = pD3D->CreateDevice( mpD3DDriver->getAdapterNumber(), devType, mHWnd,
00363                     D3DCREATE_MIXED_VERTEXPROCESSING, &md3dpp, &mpD3DDevice );
00364                 if( SUCCEEDED( hr ) )
00365                 {
00366                     mpD3DDevice->GetRenderTarget( 0, &mpRenderSurface );
00367                     mpD3DDevice->GetDepthStencilSurface( &mpRenderZBuffer );
00368                 }
00369                 else
00370                 {
00371                     hr = pD3D->CreateDevice( mpD3DDriver->getAdapterNumber(), devType, mHWnd,
00372                         D3DCREATE_SOFTWARE_VERTEXPROCESSING, &md3dpp, &mpD3DDevice );
00373                     if( SUCCEEDED( hr ) )
00374                     {
00375                         mpD3DDevice->GetRenderTarget( 0, &mpRenderSurface );
00376                         mpD3DDevice->GetDepthStencilSurface( &mpRenderZBuffer );
00377                     }
00378                 }
00379             }
00380 
00381             // TODO: make this a bit better e.g. go from pure vertex processing to software
00382             if( FAILED( hr ) )
00383             {
00384                 destroy();
00385                 Except( hr, "Failed to create Direct3D9 Device: " + 
00386                     Root::getSingleton().getErrorDescription(hr), 
00387                     "D3D9RenderWindow::create" );
00388             }
00389         }
00390         else
00391             mpD3DDevice = NULL;
00392 
00393         mReady = true;
00394     }
00395 
00396     void D3D9RenderWindow::destroy()
00397     {
00398         SAFE_RELEASE( mpRenderSurface );
00399         SAFE_RELEASE( mpRenderZBuffer );
00400         SAFE_RELEASE( mpD3DDevice );
00401         SAFE_RELEASE(mpRenderSurface);
00402         SAFE_RELEASE(mpRenderZBuffer);
00403         DestroyWindow( mHWnd );
00404     }
00405 
00406     void D3D9RenderWindow::resize( unsigned int width, unsigned int height )
00407     {
00408         mWidth = width;
00409         mHeight = height;
00410 
00411         // Notify viewports of resize
00412         ViewportList::iterator it = mViewportList.begin();
00413         while( it != mViewportList.end() )
00414             (*it++).second->_updateDimensions();
00415         // TODO - resize window
00416     }
00417 
00418     void D3D9RenderWindow::swapBuffers( bool waitForVSync )
00419     {
00420         if( mpD3DDevice )
00421         {
00422             HRESULT hr = mpD3DDevice->Present( NULL, NULL, 0, NULL );
00423             if( D3DERR_DEVICELOST == hr )
00424                 // TODO: Restore surfaces
00425                 // restoreD3DSurfaces();
00426                 Except( hr, "Device lost and not restored", "D3D9RenderWindow::swapBuffers" );
00427             else if( FAILED(hr) )
00428                 Except( hr, "Error Presenting surfaces", "D3D9RenderWindow::swapBuffers" );
00429         }
00430     }
00431 
00432     void D3D9RenderWindow::getCustomAttribute( const String& name, void* pData )
00433     {
00434         // Valid attributes and their equvalent native functions:
00435         // D3DDEVICE            : getD3DDevice
00436         // HWND                 : getWindowHandle
00437 
00438         if( name == "D3DDEVICE" )
00439         {
00440             LPDIRECT3DDEVICE9 *pDev = (LPDIRECT3DDEVICE9*)pData;
00441             *pDev = getD3DDevice();
00442             return;
00443         }
00444         else if( name == "HWND" )
00445         {
00446             HWND *pHwnd = (HWND*)pData;
00447             *pHwnd = getWindowHandle();
00448             return;
00449         }
00450         else if( name == "isTexture" )
00451         {
00452             bool *b = reinterpret_cast< bool * >( pData );
00453             *b = false;
00454 
00455             return;
00456         }
00457         else if( name == "D3DZBUFFER" )
00458         {
00459             LPDIRECT3DSURFACE9 *pSurf = (LPDIRECT3DSURFACE9*)pData;
00460             *pSurf = mpRenderZBuffer;
00461             return;
00462         }
00463         else if( name == "DDBACKBUFFER" )
00464         {
00465             LPDIRECT3DSURFACE9 *pSurf = (LPDIRECT3DSURFACE9*)pData;
00466             *pSurf = mpRenderSurface;
00467             return;
00468         }
00469         else if( name == "DDFRONTBUFFER" )
00470         {
00471             LPDIRECT3DSURFACE9 *pSurf = (LPDIRECT3DSURFACE9*)pData;
00472             *pSurf = mpRenderSurface;
00473             return;
00474         }
00475     }
00476 
00477     void D3D9RenderWindow::WindowMovedOrResized()
00478     {
00479         // TODO
00480     }
00481 
00482     void D3D9RenderWindow::writeContentsToFile(const String& filename)
00483     {
00484         HRESULT hr;
00485         LPDIRECT3DSURFACE9 pSurf=NULL, pTempSurf=NULL;
00486         D3DSURFACE_DESC desc;
00487         D3DDISPLAYMODE dm;
00488 
00489         // get display dimensions
00490         // this will be the dimensions of the front buffer
00491         if (FAILED(hr = mpD3DDevice->GetDisplayMode(0, &dm)))
00492             Except(hr, "Can't get display mode!", "D3D9RenderWindow::writeContentsToFile");
00493 
00494         desc.Width = dm.Width;
00495         desc.Height = dm.Height;
00496         desc.Format = D3DFMT_A8R8G8B8;
00497         if (FAILED(hr = mpD3DDevice->CreateOffscreenPlainSurface(
00498                         desc.Width, 
00499                         desc.Height, 
00500                         desc.Format, 
00501                         D3DPOOL_SYSTEMMEM, 
00502                         &pTempSurf, 
00503                         NULL)))
00504         {
00505             Except(hr, "Cannot create offscreen buffer 1!", "D3D9RenderWindow::writeContentsToFile");
00506         }
00507 
00508         if (FAILED(hr = mpD3DDevice->GetFrontBufferData(0, pTempSurf)))
00509         {
00510             SAFE_RELEASE(pTempSurf);
00511             Except(hr, "Can't get front buffer!", "D3D9RenderWindow::writeContentsToFile");
00512         }
00513 
00514         if (!mIsFullScreen)
00515         {
00516             POINT pt={0, 0};
00517             RECT srcRect;
00518             GetWindowRect(mHWnd, &srcRect);
00519 
00520             desc.Width = srcRect.right - srcRect.left;
00521             desc.Height = srcRect.bottom - srcRect.top;
00522             desc.Format = D3DFMT_A8R8G8B8;         // this is what we get from the screen, so stick with it
00523 
00524             // NB we can't lock the back buffer direct because it's no created that way
00525             // and to do so hits performance, so copy to another surface
00526             // Must be the same format as the source surface
00527             if (FAILED(hr = mpD3DDevice->CreateOffscreenPlainSurface(
00528                             desc.Width, 
00529                             desc.Height, 
00530                             desc.Format, 
00531                             D3DPOOL_DEFAULT, 
00532                             &pSurf,
00533                             NULL)))
00534             {
00535                 SAFE_RELEASE(pSurf);
00536                 Except(hr, "Cannot create offscreen buffer 2!", "D3D9RenderWindow::writeContentsToFile");
00537             }
00538 
00539             // Copy
00540             if (FAILED(hr = mpD3DDevice->UpdateSurface(pTempSurf, &srcRect, pSurf, &pt)))
00541             {
00542                 SAFE_RELEASE(pTempSurf);
00543                 SAFE_RELEASE(pSurf);
00544                 Except(hr, "Cannot update surface!", "D3D9RenderWindow::writeContentsToFile");
00545             }
00546 
00547             SAFE_RELEASE(pTempSurf);
00548             pTempSurf = pSurf;
00549             pSurf = NULL;
00550         }
00551 
00552         D3DLOCKED_RECT lockedRect;
00553         if (FAILED(hr = pTempSurf->LockRect(&lockedRect, NULL, 
00554             D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)))
00555         {
00556             Except(hr, "can't lock rect!", "D3D9RenderWindow::writeContentsToFile");
00557         } 
00558 
00559         ImageCodec::ImageData imgData;
00560         imgData.width = desc.Width;
00561         imgData.height = desc.Height;
00562         imgData.format = PF_R8G8B8;
00563 
00564         // Allocate contiguous buffer (surfaces aren't necessarily contiguous)
00565         uchar* pBuffer = new uchar[desc.Width * desc.Height * 3];
00566 
00567         uint x, y;
00568         uchar *pData, *pDest;
00569 
00570         pData = (uchar*)lockedRect.pBits;
00571         pDest = pBuffer;
00572         for (y = 0; y < desc.Height; ++y)
00573         {
00574             uchar *pRow = pData;
00575 
00576             for (x = 0; x < desc.Width; ++x)
00577             {
00578                 switch(desc.Format)
00579                 {
00580                 case D3DFMT_R5G6B5:
00581                     WORD val;
00582 
00583                     val = *((WORD*)pRow);
00584                     pRow += 2;
00585 
00586                     *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0xF800, (BYTE)0xFF);
00587                     *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x07E0, (BYTE)0xFF);
00588                     *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x001F, (BYTE)0xFF);
00589                     break;
00590                 case D3DFMT_A8R8G8B8:
00591                 case D3DFMT_X8R8G8B8:
00592                     // Actual format is BRGA for some reason
00593                     *pDest++ = pRow[2]; // R
00594                     *pDest++ = pRow[1]; // G
00595                     *pDest++ = pRow[0]; // B
00596                     pRow += 4; // skip alpha / dummy
00597                     break;
00598                 case D3DFMT_R8G8B8:
00599                     // Actual format is BRGA for some reason
00600                     *pDest++ = pRow[2]; // R
00601                     *pDest++ = pRow[1]; // G
00602                     *pDest++ = pRow[0]; // B
00603                     pRow += 3; 
00604                     break;
00605                 }
00606 
00607 
00608             }
00609             // increase by one line
00610             pData += lockedRect.Pitch;
00611         }
00612 
00613         // Wrap buffer in a chunk
00614         DataChunk chunk(pBuffer, desc.Width * desc.Height * 3);
00615 
00616         // Get codec 
00617         size_t pos = filename.find_last_of(".");
00618         String extension;
00619         if( pos == String::npos )
00620             Except(
00621             Exception::ERR_INVALIDPARAMS, 
00622             "Unable to determine image type for '" + filename + "' - invalid extension.",
00623             "D3D9RenderWindow::writeContentsToFile" );
00624 
00625         while( pos != filename.length() - 1 )
00626             extension += filename[++pos];
00627 
00628         // Get the codec
00629         Codec * pCodec = Codec::getCodec(extension);
00630 
00631         // Write out
00632         pCodec->codeToFile(chunk, filename, &imgData);
00633 
00634         delete [] pBuffer;
00635 
00636         SAFE_RELEASE(pTempSurf);
00637         SAFE_RELEASE(pSurf);
00638     }
00639 }

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