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

# OgreD3D7Device.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 "OgreD3D7RenderSystem.h"
    00026 #include "OgreD3D7Device.h"
    00027 #include "OgreDDDriver.h"
    00028 #include "OgreDDVideoMode.h"
    00029 #include "OgreLight.h"
    00030 #include "OgreCamera.h"
    00031 #include "OgreLogManager.h"
    00032 #include "OgreException.h"
    00033
    00034 namespace Ogre {
    00035
    00036     static HRESULT CALLBACK EnumZBuffersCallback(DDPIXELFORMAT* pddpf,
    00037             VOID* pFormats)
    00038     {
    00039         // Add to list of formats
    00040         std::vector<DDPIXELFORMAT> *vec;
    00041         vec = (std::vector<DDPIXELFORMAT>*)pFormats;
    00042
    00043         if (pddpf->dwFlags & DDPF_ZBUFFER)
    00044             vec->push_back(*pddpf);
    00045         return D3DENUMRET_OK;
    00046
    00047     }
    00048
    00049
    00050
    00051
    00052     D3DDevice D3DDevice::operator=(const D3DDevice &orig)
    00053     {
    00054
    00055
    00056         mDeviceName = orig.mDeviceName;
    00057         mDeviceDescription = orig.mDeviceDescription;
    00058         mD3DDeviceDesc = orig.mD3DDeviceDesc;
    00059         mIsHardwareAccelerated = orig.mIsHardwareAccelerated;
    00060         mNeedsZBuffer = orig.mNeedsZBuffer;
    00061
    00062
    00063         return *this;
    00064
    00065     }
    00066
    00067     // Default constructor
    00068     D3DDevice::D3DDevice()
    00069     {
    00070         // Init pointers
    00071         lpD3D = NULL;
    00072
    00073     }
    00074
    00075     // Copy Constructor
    00076     D3DDevice::D3DDevice(const D3DDevice &ob)
    00077     {
    00078         lpD3D = ob.lpD3D;
    00079         mViewport = ob.mViewport;
    00080         mDeviceDescription = ob.mDeviceDescription;
    00081         mDeviceName = ob.mDeviceName;
    00082         mD3DDeviceDesc = ob.mD3DDeviceDesc;
    00083         mIsHardwareAccelerated = ob.mIsHardwareAccelerated;
    00084         mNeedsZBuffer = ob.mNeedsZBuffer;
    00085
    00086     }
    00087
    00088     // Enum constructor
    00089     D3DDevice::D3DDevice(LPDIRECT3D7 lpDirect3D, LPSTR lpDeviceDesc, LPSTR lpDeviceName,
    00090                     LPD3DDEVICEDESC7 lpD3DDeviceDesc)
    00091     {
    00092         // Init pointers
    00093         lpD3D = NULL;
    00094
    00095         // Copy pointer to Direct3D7 interface
    00096         lpD3D = lpDirect3D;
    00097
    00098         // Copy Name and Description
    00099         mDeviceDescription = lpDeviceDesc;
    00100         mDeviceName = lpDeviceName;
    00101
    00102         // Is this a hardware or emulation device?
    00103         mIsHardwareAccelerated = ( 0 != (lpD3DDeviceDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) );
    00104
    00105
    00106         // Copy device description
    00107         // No need to differentiate between SW and HW anymore
    00108         memcpy(&mD3DDeviceDesc, lpD3DDeviceDesc, sizeof(D3DDEVICEDESC7));
    00109
    00110         char msg[255];
    00111         sprintf(msg, "Detected Direct3D Device %s.", lpDeviceDesc);
    00112         LogManager::getSingleton().logMessage(msg);
    00113         logCaps();
    00114
    00115         // Do we need a Z Buffer?
    00116         mNeedsZBuffer = !(mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR);
    00117         if (mNeedsZBuffer)
    00118             sprintf(msg, "This device needs a Z-Buffer");
    00119         else
    00120             sprintf(msg, "This device does not need a Z-Buffer");
    00121
    00122         LogManager::getSingleton().logMessage(msg);
    00123
    00124
    00125
    00126
    00127
    00128     }
    00129
    00130     D3DDevice::~D3DDevice()
    00131     {
    00132     }
    00133
    00134     LPDIRECT3DDEVICE7 D3DDevice::createDevice(LPDIRECTDRAWSURFACE7 renderTarget)
    00135     {
    00136         LPDIRECT3DDEVICE7 dev;
    00137         HRESULT hr;
    00138
    00139         hr = lpD3D->CreateDevice(mD3DDeviceDesc.deviceGUID, renderTarget, &dev);
    00140         if(FAILED(hr))
    00141             throw Exception(hr, "Error creating new D3D device.",
    00142             "D3DDevice::createDevice");
    00143
    00144         return dev;
    00145
    00146     }
    00147
    00148     LPDIRECT3D7 D3DDevice::getID3D(void)
    00149     {
    00150         return lpD3D;
    00151     }
    00152
    00153
    00154     bool D3DDevice::HardwareAccelerated(void) const
    00155     {
    00156         return mIsHardwareAccelerated;
    00157     }
    00158
    00159     void D3DDevice::logCaps(void) const
    00160     {
    00161         // Sends capabilities of this driver to the log
    00162         char msg[255];
    00163
    00164         LogManager::getSingleton().logMessage("Direct3D Device Capabilities:");
    00165
    00166         sprintf(msg, "  Hardware Accelerated: %i", HardwareAccelerated());
    00167         LogManager::getSingleton().logMessage(msg);
    00168
    00169         sprintf(msg, "  Mipmapping: %i", CanMipMap());
    00170         LogManager::getSingleton().logMessage(msg);
    00171
    00172         sprintf(msg, "  Bilinear Filtering: %i", CanBilinearFilter());
    00173         LogManager::getSingleton().logMessage(msg);
    00174
    00175         sprintf(msg, "  Trilinear Filtering: %i", CanTrilinearFilter());
    00176         LogManager::getSingleton().logMessage(msg);
    00177
    00178         sprintf(msg, "  Hardware Transform & Light: %i", CanHWTransformAndLight());
    00179         LogManager::getSingleton().logMessage(msg);
    00180
    00181         sprintf(msg, "  Max rendering colour depth: %i", RenderBitDepth());
    00182         LogManager::getSingleton().logMessage(msg);
    00183
    00184         sprintf(msg, "  Max single-pass texture layers: %i", MaxSinglePassTextureLayers());
    00185         LogManager::getSingleton().logMessage(msg);
    00186
    00187         sprintf(msg, "  Pixel fog supported: %i", ( mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE ) );
    00188         LogManager::getSingleton().logMessage(msg);
    00189
    00190         sprintf(msg, "  Vertex fog supported: %i", ( mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGVERTEX) );
    00191         LogManager::getSingleton().logMessage(msg);
    00192
    00193
    00194
    00195     }
    00196
    00197
    00198     void D3DDevice::Cleanup(void)
    00199     {
    00200         // Release DirectX Objects
    00201
    00202         lpD3D = NULL;
    00203     }
    00204
    00205
    00206     void D3DDevice::createViewport(void)
    00207     {
    00208         /*
    00209         HRESULT hr;
    00210         char msg[255];
    00211         sprintf(msg, "Creating Direct3D Viewport For %s.", mDeviceDescription.c_str());
    00212         LogManager::getSingleton().logMessage(msg);
    00213
    00214         // Create the viewport (D3D interface)
    00215         // No need to create from device anymore
    00216
    00217         // Set size (based on render target surface)
    00218         setViewportSize();
    00219
    00220         // Set current viewport for device
    00221         hr = lpD3DDevice->SetViewport(&mViewport);
    00222         if FAILED(hr)
    00223             throw Exception(hr, "Error setting current viewport for device", "D3DDevice - setActive");
    00224
    00225         LogManager::getSingleton().logMessage("Viewport Created OK");
    00226
    00227         // Set up initial camera position
    00228         //mCamera = new CCamera(this);
    00229         //mCamera->setLocation(0.0f,0.0f,-10.0f);
    00230         //mCamera->setTarget(0.0f,0.0f,0.0f);
    00231
    00232         */
    00233     }
    00234
    00235     void D3DDevice::setViewportSize(void)
    00236     {
    00237
    00238         /*
    00239         DDSURFACEDESC2 renderDesc;
    00240         HRESULT hr;
    00241         // Get surface desc of render target
    00242         renderDesc.dwSize = sizeof(DDSURFACEDESC2);
    00243         hr = lpRenderTarget->GetSurfaceDesc(&renderDesc);
    00244
    00245
    00246         if FAILED(hr)
    00247             throw Exception(hr, "Error getting render target surface description", "D3DDevice - setActive");
    00248
    00249         // Set viewport to match the surface
    00250         mViewport.dwX            = 0;
    00251         mViewport.dwY            = 0;
    00252         mViewport.dwWidth      = renderDesc.dwWidth;
    00253         mViewport.dwHeight     = renderDesc.dwHeight;
    00254         mViewport.dvMinZ       = 0.0f;
    00255         mViewport.dvMaxZ       = 1.0f;
    00256
    00257
    00258
    00259         // Set the parameters for the new viewport.
    00260
    00261         // Store viewport sizes
    00262         rcViewportRect.x1 = 0;
    00263         rcViewportRect.x2 = renderDesc.dwWidth;
    00264         rcViewportRect.y1 = 0;
    00265         rcViewportRect.y2 = renderDesc.dwHeight;
    00266         */
    00267     }
    00268
    00269     void D3DDevice::setViewMatrix(D3DMATRIX *mat)
    00270     {
    00271         /*
    00272         HRESULT hr;
    00273
    00274         hr = lpD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, mat);
    00275
    00276         if (FAILED(hr))
    00277             throw Exception(hr, "Error setting view matrix.",
    00278                 "D3DDevice - setViewMatrix");
    00279         */
    00280      }
    00281
    00282     void D3DDevice::setProjectionMatrix(D3DMATRIX *mat)
    00283     {
    00284         /*
    00285         HRESULT hr;
    00286         hr = lpD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, mat);
    00287
    00288         if (FAILED(hr))
    00289             throw Exception(hr, "Error setting projection matrix.",
    00290                 "D3DDevice - setProjectionMatrix");
    00291         */
    00292     }
    00293
    00294     void D3DDevice::setWorldMatrix(D3DMATRIX *mat)
    00295     {
    00296         /*
    00297         HRESULT hr;
    00298         hr = lpD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, mat);
    00299
    00300         if (FAILED(hr))
    00301             throw Exception(hr, "Error setting world matrix.",
    00302                 "D3DDevice - setWorldMatrix");
    00303         */
    00304     }
    00305
    00306     void D3DDevice::beginScene(void)
    00307     {
    00308         /*
    00309         HRESULT hr;
    00310
    00311         // Clear viewport
    00312         hr = lpD3DDevice->Clear(0, NULL,
    00313             D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0, 1L, 0L);
    00314         if (FAILED(hr))
    00315             throw Exception(hr, "Can't clear viewport.",
    00316                 "D3DDevice - beginScene");
    00317
    00318         // BEGIN
    00319
    00320         hr = lpD3DDevice->BeginScene();
    00321         if (FAILED(hr))
    00322             throw Exception(hr, "Can't begin scene.",
    00323                 "D3DDevice - beginScene");
    00324         */
    00325     }
    00326
    00327     void D3DDevice::endScene(void)
    00328     {
    00329         //lpD3DDevice->EndScene();
    00330     }
    00331
    00332
    00333     void D3DDevice::setAmbientLight(float r, float g, float b)
    00334     {
    00335
    00336         // Just set white for now
    00337         //HRESULT hr;
    00338         //hr = lpD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff );
    00339     }
    00340
    00341
    00342
    00343
    00344     String D3DDevice::DeviceName(void) const
    00345     {
    00346         return mDeviceName;
    00347     }
    00348
    00349     String D3DDevice::DeviceDescription(void) const
    00350     {
    00351         return mDeviceDescription;
    00352     }
    00353
    00354
    00355     void D3DDevice::createDepthBuffer(LPDIRECTDRAWSURFACE7 renderTarget)
    00356     {
    00357         DWORD bestDepth, bestStencil;
    00358         DDSURFACEDESC2 ddsd, src_ddsd;
    00359         LPDIRECTDRAW7 lpDD7;
    00360         LPDIRECTDRAWSURFACE7 lpZBuffer;
    00361         HRESULT hr;
    00362
    00363         LogManager::getSingleton().logMessage("Direct3D - Creating Z-Buffer");
    00364
    00365         // First check we NEED a depth buffer - e.g. PowerVR doesn't need one
    00366         if (mNeedsZBuffer)
    00367         {
    00368             // Get description from source surface
    00369             ZeroMemory(&src_ddsd, sizeof(DDSURFACEDESC2));
    00370             src_ddsd.dwSize = sizeof(DDSURFACEDESC2);
    00371             renderTarget->GetSurfaceDesc(&src_ddsd);
    00372
    00373             // Enumerate Depth Buffers
    00374             mDepthBufferFormats.clear();
    00375             lpD3D->EnumZBufferFormats(
    00376                 mD3DDeviceDesc.deviceGUID,
    00377                 EnumZBuffersCallback,
    00378                 (LPVOID)&mDepthBufferFormats );
    00379
    00380             // Choose the best one
    00381             // NB make sure Z buffer is the same depth as colour buffer (GeForce TnL problem)
    00382             // Also use best stencil if z depth is the same
    00383             bestDepth = 0;
    00384             bestStencil = 0;
    00385
    00386             std::vector<DDPIXELFORMAT>::iterator it, best_it;
    00387             for(
    00388                 it = mDepthBufferFormats.begin();
    00389                 it != mDepthBufferFormats.end();
    00390                 ++it )
    00391             {
    00392                 if( ( (*it).dwZBufferBitDepth > bestDepth || (*it).dwStencilBitDepth > bestStencil)
    00393                     &&
    00394                     (*it).dwZBufferBitDepth <= src_ddsd.ddpfPixelFormat.dwZBufferBitDepth )
    00395                 {
    00396                     best_it = it;
    00397                     bestDepth = (*it).dwZBufferBitDepth;
    00398                     bestStencil = (*it).dwStencilBitDepth;
    00399                 }
    00400             }
    00401
    00402             // Setup the surface desc for the z-buffer.
    00403             ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
    00404
    00405             ddsd.dwSize         = sizeof(DDSURFACEDESC2);
    00406             ddsd.dwFlags        = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
    00407
    00408             ddsd.dwWidth        = src_ddsd.dwWidth;
    00409             ddsd.dwHeight       = src_ddsd.dwHeight;
    00410
    00411             ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
    00412
    00413             memcpy( &ddsd.ddpfPixelFormat, &(*best_it), sizeof(DDPIXELFORMAT) );
    00414
    00415             // Software devices require system-memory depth buffers.
    00416             if( mIsHardwareAccelerated )
    00417                 ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
    00418             else
    00419                 ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
    00420
    00421             // Create the depth-buffer.
    00422             renderTarget->GetDDInterface( (VOID**)&lpDD7 );
    00423             lpDD7->Release();
    00424
    00425             if( FAILED( hr = lpDD7->CreateSurface( &ddsd, &lpZBuffer, NULL ) ) )
    00426                 Except(
    00427                     hr,
    00428                     "Error creating depth buffer",
    00429                     "D3DDevice::createDepthBuffer" );
    00430
    00431             if( FAILED( hr = renderTarget->AddAttachedSurface(lpZBuffer) ) )
    00432                 Except(
    00433                     hr,
    00434                     "Error attaching depth buffer to render target",
    00435                     "D3DDevice::createDepthBuffer" );
    00436
    00437             // Log stencil buffer depth
    00438             mStencilBufferDepth = ddsd.ddpfPixelFormat.dwStencilBitDepth;
    00439
    00440             LogManager::getSingleton().logMessage(
    00441                 LML_NORMAL,
    00442                 "Depth-Buffer created (%i-bit, %i-bit stencil)",
    00443                 ddsd.ddpfPixelFormat.dwZBufferBitDepth,
    00444                 mStencilBufferDepth);
    00445             if (mStencilBufferDepth == 0)
    00446             {
    00447                 LogManager::getSingleton().logMessage("Warning: software stencilling "
    00448                     "in use, stencil operations will not be hardware accelerated.");
    00449             }
    00450         }
    00451     }
    00452
    00453     bool D3DDevice::CanMipMap(void) const
    00454     {
    00455         return (mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MIPNEAREST) > 0;
    00456     }
    00457
    00458     bool D3DDevice::CanBilinearFilter(void) const
    00459     {
    00460         return (mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR) > 0;
    00461     }
    00462
    00463     bool D3DDevice::CanTrilinearFilter(void) const
    00464     {
    00465         return (mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR) > 0;
    00466     }
    00467
    00468     unsigned int D3DDevice::RenderBitDepth(void) const
    00469     {
    00470
    00471         if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_32)
    00472             return 32;
    00473         else if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_24)
    00474             return 24;
    00475         else if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_16)
    00476             return 16;
    00477         else if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_8)
    00478             return 8;
    00479         else
    00480             return 0;
    00481     }
    00482
    00483     unsigned int D3DDevice::ZBufferBitDepth(void) const
    00484     {
    00485         switch(mD3DDeviceDesc.dwDeviceZBufferBitDepth)
    00486         {
    00487         case DDBD_8:
    00488             return 8;
    00489         case DDBD_16:
    00490             return 16;
    00491         case DDBD_24:
    00492             return 24;
    00493         case DDBD_32:
    00494             return 32;
    00495         }
    00496
    00497         return 0;
    00498
    00499     }
    00500     bool D3DDevice::NeedsZBuffer(void) const
    00501     {
    00502         return mNeedsZBuffer;
    00503     }
    00504
    00505     bool D3DDevice::CanHWTransformAndLight(void) const
    00506     {
    00507         return (mD3DDeviceDesc.dwDevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) > 0;
    00508     }
    00509
    00510     unsigned int D3DDevice::MaxSinglePassTextureLayers(void) const
    00511     {
    00512         // The maximum number of texture layers the device can support in a singe pass
    00513
    00514         return mD3DDeviceDesc.wMaxSimultaneousTextures;
    00515     }
    00516
    00517     ushort D3DDevice::StencilBufferBitDepth(void) const
    00518     {
    00519         return mStencilBufferDepth;
    00520     }
    00521
    00522
    00523 } // Namespace

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