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 Fri May 14 23:21:58 2004