00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://ogre.sourceforge.net/ 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 <malloc.h> 00026 #include "OgreD3D7RenderSystem.h" 00027 #include "OgreDDDriver.h" 00028 #include "OgreD3D7Device.h" 00029 #include "OgreD3D7DeviceList.h" 00030 #include "OgreDDDriverList.h" 00031 #include "OgreDDVideoModeList.h" 00032 #include "OgreDDVideoMode.h" 00033 #include "OgreRenderWindow.h" 00034 #include "OgreLogManager.h" 00035 #include "OgreRenderSystem.h" 00036 #include "OgreException.h" 00037 #include "OgreSceneManager.h" 00038 #include "OgreD3D7TextureManager.h" 00039 #include "OgreViewport.h" 00040 #include "OgreLight.h" 00041 #include "OgreMatrix4.h" 00042 #include "OgreMath.h" 00043 #include "OgreD3D7RenderWindow.h" 00044 #include "OgreFrustum.h" 00045 #include "OgreD3D7GpuProgramManager.h" 00046 00047 00048 namespace Ogre { 00049 const Matrix4 PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE( 00050 0.5, 0, 0, -0.5, 00051 0, -0.5, 0, -0.5, 00052 0, 0, 0, 1, 00053 0, 0, 0, 1); 00054 00055 const Matrix4 PROJECTIONCLIPSPACE2DTOIMAGESPACE_ORTHO( 00056 -0.5, 0, 0, -0.5, 00057 0, 0.5, 0, -0.5, 00058 0, 0, 0, 1, 00059 0, 0, 0, 1); 00060 00061 //----------------------------------------------------------------------- 00062 D3DRenderSystem::D3DRenderSystem(HINSTANCE hInstance) 00063 { 00064 OgreGuard( "D3DRenderSystem::D3DRenderSystem" ); 00065 00066 LogManager::getSingleton().logMessage(getName() + " created."); 00067 00068 mlpD3DDevice = NULL; 00069 // Reset driver list 00070 mDriverList = NULL; 00071 mActiveDDDriver = NULL; 00072 mhInstance = hInstance; 00073 mHardwareBufferManager = NULL; 00074 mGpuProgramManager = NULL; 00075 00076 initConfigOptions(); 00077 00078 // Initialise D3DX library 00079 D3DXInitialize(); 00080 00081 // set stages desc. to defaults 00082 for (int n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++) 00083 { 00084 mTexStageDesc[n].autoTexCoordType = TEXCALC_NONE; 00085 mTexStageDesc[n].coordIndex = 0; 00086 mTexStageDesc[n].texType = D3D_TEX_TYPE_NORMAL; 00087 mTexStageDesc[n].pTex = NULL; 00088 } 00089 00090 mCurrentLights = 0; 00091 00092 OgreUnguard(); 00093 } 00094 00095 //----------------------------------------------------------------------- 00096 D3DRenderSystem::~D3DRenderSystem() 00097 { 00098 OgreGuard( "D3DRenderSystem::~D3DRenderSystem" ); 00099 shutdown(); 00100 00101 SAFE_DELETE(mTextureManager); 00102 SAFE_DELETE(mDriverList); 00103 SAFE_DELETE(mCapabilities); 00104 SAFE_DELETE(mHardwareBufferManager); 00105 SAFE_DELETE(mGpuProgramManager); 00106 00107 D3DXUninitialize(); 00108 LogManager::getSingleton().logMessage(getName() + " destroyed."); 00109 00110 OgreUnguard(); 00111 } 00112 00113 //----------------------------------------------------------------------- 00114 const String& D3DRenderSystem::getName(void) const 00115 { 00116 static String strName("Direct3D7 Rendering Subsystem"); 00117 return strName; 00118 } 00119 00120 //----------------------------------------------------------------------- 00121 void D3DRenderSystem::initConfigOptions(void) 00122 { 00123 OgreGuard( "D3DRenderSystem::initConfigOptions" ); 00124 00125 DDDriverList* ddList; 00126 DDDriver* dd; 00127 00128 ConfigOption optDevice; 00129 ConfigOption optVideoMode; 00130 ConfigOption optFullScreen; 00131 ConfigOption optVSync; 00132 00133 ddList = this->getDirectDrawDrivers(); 00134 00135 // Create option for devices 00136 optDevice.name = "Rendering Device"; 00137 optDevice.currentValue = ""; 00138 optDevice.possibleValues.clear(); 00139 optDevice.immutable = false; 00140 00141 // Option for video modes 00142 optVideoMode.name = "Video Mode"; 00143 optVideoMode.currentValue = ""; 00144 optVideoMode.immutable = false; 00145 00146 // Option for full screen 00147 optFullScreen.name = "Full Screen"; 00148 optFullScreen.possibleValues.push_back("Yes"); 00149 optFullScreen.possibleValues.push_back("No"); 00150 optFullScreen.currentValue = "Yes"; 00151 00152 00153 unsigned k = ddList->count(); 00154 // First, get DirectDraw driver options 00155 for( unsigned j = 0; j < ddList->count(); j++ ) 00156 { 00157 dd = ddList->item(j); 00158 // Add to device option list 00159 optDevice.possibleValues.push_back( dd->DriverDescription() ); 00160 00161 // Make first one default 00162 if( j==0 ) 00163 { 00164 optDevice.currentValue = dd->DriverDescription(); 00165 00166 } 00167 00168 00169 } 00170 00171 // VSync option 00172 optVSync.name = "VSync"; 00173 optVSync.immutable = false; 00174 optVSync.possibleValues.push_back("Yes"); 00175 optVSync.possibleValues.push_back("No"); 00176 optVSync.currentValue = "Yes"; 00177 00178 00179 mOptions[optDevice.name] = optDevice; 00180 mOptions[optVideoMode.name] = optVideoMode; 00181 mOptions[optFullScreen.name] = optFullScreen; 00182 mOptions[optVSync.name] = optVSync; 00183 00184 // Set default-based settings 00185 refreshDDSettings(); 00186 00187 OgreUnguard(); 00188 } 00189 00190 //----------------------------------------------------------------------- 00191 void D3DRenderSystem::refreshDDSettings(void) 00192 { 00193 OgreGuard( "D3DRenderSystem::refreshDDSettings" ); 00194 00195 DDVideoMode* vid; 00196 ConfigOption* optVideoMode; 00197 ConfigOption* optFullScreen; 00198 DDDriver* dd; 00199 00200 // Stuffs DD-Driver specific settings 00201 00202 // Find DD Driver selected in options 00203 ConfigOptionMap::iterator opt = mOptions.find("Rendering Device"); 00204 00205 if( opt != mOptions.end() ) 00206 { 00207 for( unsigned j = 0; j < getDirectDrawDrivers()->count(); j++ ) 00208 { 00209 dd = getDirectDrawDrivers()->item(j); 00210 if( dd->DriverDescription() == opt->second.currentValue ) 00211 break; 00212 } 00213 00214 // Get fullScreen and Video mode options 00215 opt = mOptions.find("Video Mode"); 00216 optVideoMode = &opt->second; 00217 opt = mOptions.find("Full Screen"); 00218 optFullScreen = &opt->second; 00219 00220 // Full screen forced? 00221 if (!(dd->CanRenderWindowed())) 00222 { 00223 setConfigOption("Full Screen", "Yes"); 00224 optFullScreen->immutable = true; 00225 } 00226 else 00227 optFullScreen->immutable = false; 00228 00229 // Get video modes for this device 00230 optVideoMode->possibleValues.clear(); 00231 00232 for( unsigned k = 0; k<dd->getVideoModeList()->count(); k++ ) 00233 { 00234 vid = dd->getVideoModeList()->item(k); 00235 optVideoMode->possibleValues.push_back(vid->Description()); 00236 } 00237 } 00238 00239 OgreUnguard(); 00240 } 00241 00242 00243 //----------------------------------------------------------------------- 00244 ConfigOptionMap& D3DRenderSystem::getConfigOptions(void) 00245 { 00246 // Return a COPY of the current config options 00247 return mOptions; 00248 00249 } 00250 00251 //----------------------------------------------------------------------- 00252 void D3DRenderSystem::setConfigOption(const String &name, const String &value) 00253 { 00254 OgreGuard( "D3DRenderSystem::setConfigOption" ); 00255 00256 char msg[128]; 00257 00258 sprintf(msg, "RenderSystem Option: %s = %s", name.c_str(), value.c_str()); 00259 LogManager::getSingleton().logMessage(msg); 00260 00261 // Find option 00262 ConfigOptionMap::iterator it = mOptions.find(name); 00263 00264 // Update 00265 if( it != mOptions.end()) 00266 it->second.currentValue = value; 00267 else 00268 { 00269 sprintf(msg, "Option named %s does not exist.", name.c_str()); 00270 Except(Exception::ERR_INVALIDPARAMS, 00271 msg, "D3DRenderSystem::setConfigOption"); 00272 } 00273 00274 // Refresh other options if DD Driver changed 00275 if (name == "Rendering Device") 00276 refreshDDSettings(); 00277 00278 if (name == "Full Screen") 00279 { 00280 if (value == "No") 00281 { 00282 // Video mode is not applicable 00283 it = mOptions.find("Video Mode"); 00284 it->second.currentValue = "N/A"; 00285 it->second.immutable = true; 00286 } 00287 else 00288 { 00289 // Video mode is applicable 00290 it = mOptions.find("Video Mode"); 00291 // default to 640 x 480 x 16 00292 it->second.currentValue = "640 x 480 @ 16-bit colour"; 00293 it->second.immutable = false; 00294 } 00295 } 00296 00297 OgreUnguard(); 00298 } 00299 //----------------------------------------------------------------------- 00300 String D3DRenderSystem::validateConfigOptions(void) 00301 { 00302 // Check video mode specified in full screen mode 00303 ConfigOptionMap::iterator o = mOptions.find("Full Screen"); 00304 if (o->second.currentValue == "Yes") 00305 { 00306 // Check video mode 00307 o = mOptions.find("Video Mode"); 00308 if (o->second.currentValue == "") 00309 { 00310 return "A video mode must be selected for running in full-screen mode."; 00311 } 00312 } 00313 00314 o = mOptions.find( "Rendering Device" ); 00315 bool foundDriver = false; 00316 DDDriverList* driverList = getDirectDrawDrivers(); 00317 for( ushort j=0; j < driverList->count(); j++ ) 00318 { 00319 if( driverList->item(j)->DriverDescription() == o->second.currentValue ) 00320 { 00321 foundDriver = true; 00322 break; 00323 } 00324 } 00325 if (!foundDriver) 00326 { 00327 // Just pick the first driver 00328 setConfigOption("Rendering Device", driverList->item(0)->DriverDescription()); 00329 return "Your DirectX driver name has changed since the last time you ran OGRE; " 00330 "the 'Rendering Device' has been changed."; 00331 } 00332 return ""; 00333 00334 } 00335 //----------------------------------------------------------------------- 00336 RenderWindow* D3DRenderSystem::initialise(bool autoCreateWindow, const String& windowTitle) 00337 { 00338 RenderWindow* autoWindow = 0; 00339 00340 00341 LogManager::getSingleton().logMessage( 00342 "***************************************\n" 00343 "*** Direct3D Subsystem Initialising ***\n" 00344 "***************************************" ); 00345 00346 // --------------------------- 00347 // Init using current settings 00348 // --------------------------- 00349 00350 // DirectDraw driver 00351 mActiveDDDriver = 0; 00352 ConfigOptionMap::iterator opt = mOptions.find("Rendering Device"); 00353 for( unsigned j = 0; j<getDirectDrawDrivers()->count(); j++ ) 00354 { 00355 if (getDirectDrawDrivers()->item(j)->DriverDescription() == opt->second.currentValue) 00356 { 00357 mActiveDDDriver = getDirectDrawDrivers()->item(j); 00358 break; 00359 } 00360 } 00361 00362 if (!mActiveDDDriver) 00363 Except(Exception::ERR_INVALIDPARAMS, "Problems finding requested DirectDraw driver!", 00364 "D3DRenderSystem::initialise"); 00365 00366 00367 // Sort out the creation of a new window if required 00368 if (autoCreateWindow) 00369 { 00370 // Full screen? 00371 bool fullScreen; 00372 opt = mOptions.find("Full Screen"); 00373 if( opt == mOptions.end() ) 00374 Except(999, "Can't find full screen option!", 00375 "D3DRenderSystem::initialise"); 00376 if (opt->second.currentValue == "Yes") 00377 fullScreen = true; 00378 else 00379 fullScreen = false; 00380 00381 // Get video mode 00382 DDVideoMode* vid; 00383 unsigned int height, width, colourDepth; 00384 00385 vid = 0; 00386 String temp; 00387 if (fullScreen) 00388 { 00389 opt = mOptions.find("Video Mode"); 00390 00391 for( unsigned j=0; j<mActiveDDDriver->getVideoModeList()->count(); j++ ) 00392 { 00393 temp = mActiveDDDriver->getVideoModeList()->item(j)->Description(); 00394 if (temp == opt->second.currentValue) 00395 { 00396 vid = mActiveDDDriver->getVideoModeList()->item(j); 00397 break; 00398 } 00399 } 00400 00401 if (!vid) 00402 Except(9999, "Can't find requested video mode.", 00403 "D3DRenderSystem::initilise"); 00404 width = vid->mWidth; 00405 height = vid->mHeight; 00406 colourDepth = vid->mColourDepth; 00407 00408 } 00409 else 00410 { 00411 // Notional height / width 00412 width = 800; 00413 height = 600; 00414 colourDepth = 0; // colour depth based on desktop 00415 } 00416 00417 // Create myself a window 00418 autoWindow = this->createRenderWindow(windowTitle, width, height, colourDepth, fullScreen); 00419 00420 // If we have 16bit depth buffer enable w-buffering. 00421 assert( autoWindow ); 00422 if ( autoWindow->getColourDepth() == 16 ) 00423 { 00424 mWBuffer = true; 00425 } 00426 else 00427 { 00428 mWBuffer = false; 00429 } 00430 00431 } 00432 00433 opt = mOptions.find("VSync"); 00434 if (opt!=mOptions.end()) 00435 { 00436 if (opt->second.currentValue == "Yes") 00437 { 00438 setWaitForVerticalBlank(true); 00439 } 00440 else 00441 { 00442 setWaitForVerticalBlank(false); 00443 } 00444 } 00445 00446 00447 LogManager::getSingleton().logMessage("*****************************************"); 00448 LogManager::getSingleton().logMessage("*** Direct3D Subsystem Initialised Ok ***"); 00449 LogManager::getSingleton().logMessage("*****************************************"); 00450 00451 // call superclass method 00452 RenderSystem::initialise(autoCreateWindow); 00453 00454 // Create buffer manager 00455 mHardwareBufferManager = new D3D7HardwareBufferManager(); 00456 // Create dummy gpu manager 00457 mGpuProgramManager = new D3D7GpuProgramManager(); 00458 00459 00460 return autoWindow; 00461 00462 } 00463 00464 //----------------------------------------------------------------------- 00465 void D3DRenderSystem::reinitialise(void) 00466 { 00467 this->shutdown(); 00468 this->initialise(true); 00469 } 00470 00471 00472 //----------------------------------------------------------------------- 00473 void D3DRenderSystem::shutdown(void) 00474 { 00475 RenderSystem::shutdown(); 00476 00477 // Cleanup 00478 // Release all DirectX resources 00479 //D3DTextr_InvalidateAllTextures(); 00480 if (mActiveDDDriver) 00481 { 00482 mActiveDDDriver->Cleanup(); 00483 } 00484 00485 // Delete system objects 00486 SAFE_DELETE(mDriverList); 00487 00488 mActiveDDDriver = NULL; 00489 00490 00491 00492 // Write termination message 00493 LogManager::getSingleton().logMessage("*-*-* Direct3D Subsystem shutting down cleanly."); 00494 00495 00496 } 00497 00498 //----------------------------------------------------------------------- 00499 void D3DRenderSystem::setAmbientLight(float r, float g, float b) 00500 { 00501 // Call D3D 00502 D3DCOLOR col = D3DRGB(r,g,b); 00503 00504 HRESULT hr = __SetRenderState(D3DRENDERSTATE_AMBIENT, col); 00505 if (FAILED(hr)) 00506 Except(hr, "Error setting ambient light.", "D3DRenderSystem::setAmbientLight"); 00507 } 00508 00509 //----------------------------------------------------------------------- 00510 void D3DRenderSystem::setShadingType(ShadeOptions so) 00511 { 00512 D3DSHADEMODE d3dMode; 00513 switch(so) 00514 { 00515 case SO_FLAT: 00516 d3dMode = D3DSHADE_FLAT; 00517 break; 00518 case SO_GOURAUD: 00519 d3dMode = D3DSHADE_GOURAUD; 00520 break; 00521 case SO_PHONG: 00522 d3dMode = D3DSHADE_PHONG; 00523 break; 00524 00525 } 00526 00527 HRESULT hr = __SetRenderState(D3DRENDERSTATE_SHADEMODE, d3dMode); 00528 if (FAILED(hr)) 00529 Except(hr, "Error setting shading mode.", "D3DRenderSystem::setShadingType"); 00530 00531 } 00532 00533 00534 //----------------------------------------------------------------------- 00535 RenderWindow* D3DRenderSystem::createRenderWindow(const String &name, unsigned int width, unsigned int height, unsigned int colourDepth, 00536 bool fullScreen, int left, int top, bool depthBuffer, RenderWindow* parentWindowHandle) 00537 { 00538 static bool firstWindow = true; 00539 OgreGuard( "D3DRenderSystem::createRenderWindow" ); 00540 00541 String msg; 00542 00543 // Make sure we don't already have a render target of the 00544 // same name as the one supplied 00545 if( mRenderTargets.find( name ) != mRenderTargets.end() ) 00546 { 00547 msg = msg + "A render target of the same name (" + name + ") already " 00548 "exists. You cannot create a new window with this name."; 00549 Except(999,msg,"D3DRenderSystem::createRenderWindow"); 00550 } 00551 00552 RenderWindow* win = new D3D7RenderWindow(); 00553 // Create window, supplying DD interface & hInstance 00554 win->create(name, width, height, colourDepth, fullScreen, 00555 left, top, depthBuffer, &mhInstance, mActiveDDDriver, parentWindowHandle); 00556 00557 attachRenderTarget( *win ); 00558 00559 // If this is the first window, get the D3D device 00560 // and create the texture manager, setup caps 00561 if (firstWindow) 00562 { 00563 win->getCustomAttribute("D3DDEVICE", &mlpD3DDevice); 00564 // Get caps 00565 mlpD3DDevice->GetCaps(&mD3DDeviceDesc); 00566 // Create my texture manager for use by others 00567 // Note this is a Singleton; pointer is held static by superclass 00568 mTextureManager = new D3DTextureManager(mlpD3DDevice); 00569 00570 // Check for hardware stencil support 00571 // Get render target, then depth buffer and check format 00572 LPDIRECTDRAWSURFACE7 lpTarget; 00573 win->getCustomAttribute("DDBACKBUFFER", &lpTarget); 00574 DDSCAPS2 ddscaps; 00575 ZeroMemory(&ddscaps, sizeof(DDSCAPS2)); 00576 ddscaps.dwCaps = DDSCAPS_ZBUFFER; 00577 lpTarget->GetAttachedSurface(&ddscaps, &lpTarget); 00578 lpTarget->Release(); 00579 DDSURFACEDESC2 ddsd; 00580 ddsd.dwSize = sizeof(DDSURFACEDESC2); 00581 lpTarget->GetSurfaceDesc(&ddsd); 00582 DWORD stencil = ddsd.ddpfPixelFormat.dwStencilBitDepth; 00583 if(stencil > 0) 00584 { 00585 mCapabilities->setCapability(RSC_HWSTENCIL); 00586 mCapabilities->setStencilBufferBitDepth(stencil); 00587 if ((mD3DDeviceDesc.dwStencilCaps & D3DSTENCILCAPS_INCR) && 00588 (mD3DDeviceDesc.dwStencilCaps & D3DSTENCILCAPS_DECR)) 00589 mCapabilities->setCapability(RSC_STENCIL_WRAP); 00590 } 00591 00592 // Anisotropy? 00593 if (mD3DDeviceDesc.dwMaxAnisotropy > 1) 00594 mCapabilities->setCapability(RSC_ANISOTROPY); 00595 // Blending between stages supported 00596 mCapabilities->setCapability(RSC_BLENDING); 00597 // Cubemapping 00598 if (mD3DDeviceDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP) 00599 mCapabilities->setCapability(RSC_CUBEMAPPING); 00600 00601 // DOT3 00602 if (mD3DDeviceDesc.dwTextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) 00603 mCapabilities->setCapability(RSC_DOT3); 00604 00605 // Set the number of texture units based on details from current device 00606 mCapabilities->setNumTextureUnits(mD3DDeviceDesc.wMaxSimultaneousTextures); 00607 00608 mCapabilities->log(LogManager::getSingleton().getDefaultLog()); 00609 00610 firstWindow = false; 00611 } 00612 00613 OgreUnguardRet( win ); 00614 } 00615 00616 RenderTexture * D3DRenderSystem::createRenderTexture( const String & name, unsigned int width, unsigned int height ) 00617 { 00618 RenderTexture * rt = new D3D7RenderTexture( name, width, height ); 00619 attachRenderTarget( *rt ); 00620 return rt; 00621 } 00622 00623 //----------------------------------------------------------------------- 00624 // Low-level overridden members 00625 //----------------------------------------------------------------------- 00626 //--------------------------------------------------------------------- 00627 void D3DRenderSystem::_useLights(const LightList& lights, unsigned short limit) 00628 { 00629 LightList::const_iterator i, iend; 00630 iend = lights.end(); 00631 unsigned short num = 0; 00632 for (i = lights.begin(); i != iend && num < limit; ++i, ++num) 00633 { 00634 setD3DLight(num, *i); 00635 } 00636 // Disable extra lights 00637 for (; num < mCurrentLights; ++num) 00638 { 00639 setD3DLight(num, NULL); 00640 } 00641 mCurrentLights = std::min(limit, static_cast<unsigned short>(lights.size())); 00642 00643 } 00644 //----------------------------------------------------------------------- 00645 void D3DRenderSystem::setD3DLight(size_t index, Light* lt) 00646 { 00647 // Add to D3D 00648 HRESULT hr; 00649 D3DLIGHT7 d3dLight; 00650 00651 if (!lt) 00652 { 00653 hr = mlpD3DDevice->LightEnable(index, FALSE); 00654 if (FAILED(hr)) 00655 Except(hr, "Unable to disable light.", "D3DRenderSystem::setD3DLight"); 00656 } 00657 else 00658 { 00659 switch (lt->getType()) 00660 { 00661 case Light::LT_POINT: 00662 d3dLight.dltType = D3DLIGHT_POINT; 00663 break; 00664 case Light::LT_DIRECTIONAL: 00665 d3dLight.dltType = D3DLIGHT_DIRECTIONAL; 00666 break; 00667 case Light::LT_SPOTLIGHT: 00668 d3dLight.dltType = D3DLIGHT_SPOT; 00669 d3dLight.dvFalloff = lt->getSpotlightFalloff(); 00670 d3dLight.dvTheta = lt->getSpotlightInnerAngle().valueRadians(); 00671 d3dLight.dvPhi = lt->getSpotlightOuterAngle().valueRadians(); 00672 break; 00673 } 00674 00675 // Colours 00676 ColourValue col; 00677 col = lt->getDiffuseColour(); 00678 d3dLight.dcvDiffuse.r = col.r; 00679 d3dLight.dcvDiffuse.g = col.g; 00680 d3dLight.dcvDiffuse.b = col.b; 00681 d3dLight.dcvDiffuse.a = col.a; 00682 00683 col = lt->getSpecularColour(); 00684 d3dLight.dcvSpecular.r = col.r; 00685 d3dLight.dcvSpecular.g = col.g; 00686 d3dLight.dcvSpecular.b = col.b; 00687 d3dLight.dcvSpecular.a = col.a; 00688 00689 // Never use ambient for a movable light 00690 d3dLight.dcvAmbient.r = 0.0; 00691 d3dLight.dcvAmbient.g = 0.0; 00692 d3dLight.dcvAmbient.b = 0.0; 00693 d3dLight.dcvAmbient.a = 0.0; 00694 00695 // Position (Irrelevant for directional) 00696 Vector3 vec; 00697 if (lt->getType() != Light::LT_DIRECTIONAL) 00698 { 00699 vec = lt->getDerivedPosition(); 00700 00701 d3dLight.dvPosition.x = vec.x; 00702 d3dLight.dvPosition.y = vec.y; 00703 d3dLight.dvPosition.z = vec.z; 00704 } 00705 // Direction (Irrelevant for point lights) 00706 if (lt->getType() != Light::LT_POINT) 00707 { 00708 vec = lt->getDerivedDirection(); 00709 d3dLight.dvDirection.x = vec.x; 00710 d3dLight.dvDirection.y = vec.y; 00711 d3dLight.dvDirection.z = vec.z; 00712 } 00713 // Attenuation parameters 00714 d3dLight.dvRange = lt->getAttenuationRange(); 00715 d3dLight.dvAttenuation0 = lt->getAttenuationConstant(); 00716 d3dLight.dvAttenuation1 = lt->getAttenuationLinear(); 00717 d3dLight.dvAttenuation2 = lt->getAttenuationQuadric(); 00718 00719 00720 00721 // Set light state 00722 hr = mlpD3DDevice->SetLight(index, &d3dLight); 00723 00724 if (FAILED(hr)) 00725 Except(hr, "Unable to set light details", "D3DRenderSystem::setD3DLight"); 00726 00727 hr = mlpD3DDevice->LightEnable(index, TRUE); 00728 if (FAILED(hr)) 00729 Except(hr, "Unable to enable light.", "D3DRenderSystem::setD3DLight"); 00730 } 00731 00732 00733 } 00734 //----------------------------------------------------------------------- 00735 D3DMATRIX D3DRenderSystem::makeD3DMatrix(const Matrix4& mat) 00736 { 00737 // Transpose matrix 00738 // D3D uses row vectors i.e. V*M 00739 // Ogre, OpenGL and everything else uses coloumn vectors i.e. M*V 00740 D3DMATRIX d3dMat; 00741 00742 d3dMat.m[0][0] = mat[0][0]; 00743 d3dMat.m[0][1] = mat[1][0]; 00744 d3dMat.m[0][2] = mat[2][0]; 00745 d3dMat.m[0][3] = mat[3][0]; 00746 00747 d3dMat.m[1][0] = mat[0][1]; 00748 d3dMat.m[1][1] = mat[1][1]; 00749 d3dMat.m[1][2] = mat[2][1]; 00750 d3dMat.m[1][3] = mat[3][1]; 00751 00752 d3dMat.m[2][0] = mat[0][2]; 00753 d3dMat.m[2][1] = mat[1][2]; 00754 d3dMat.m[2][2] = mat[2][2]; 00755 d3dMat.m[2][3] = mat[3][2]; 00756 00757 d3dMat.m[3][0] = mat[0][3]; 00758 d3dMat.m[3][1] = mat[1][3]; 00759 d3dMat.m[3][2] = mat[2][3]; 00760 d3dMat.m[3][3] = mat[3][3]; 00761 00762 return d3dMat; 00763 } 00764 00765 Matrix4 D3DRenderSystem::convertD3DMatrix(const D3DMATRIX& d3dmat) 00766 { 00767 // The reverse of makeD3DMatrix 00768 // Transpose matrix 00769 // D3D uses row vectors i.e. V*M 00770 // Ogre, OpenGL and everything else uses coloumn vectors i.e. M*V 00771 Matrix4 mat; 00772 for (unsigned row = 0; row < 4; ++row) 00773 for (unsigned col = 0; col < 4; ++col) 00774 mat[col][row] = d3dmat.m[row][col]; 00775 00776 return mat; 00777 00778 00779 } 00780 //----------------------------------------------------------------------- 00781 void D3DRenderSystem::_setWorldMatrix(const Matrix4 &m) 00782 { 00783 D3DMATRIX d3dmat; 00784 00785 d3dmat = makeD3DMatrix(m); 00786 00787 HRESULT hr = mlpD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &d3dmat); 00788 00789 if (FAILED(hr)) 00790 Except(hr, "Cannot set D3D world matrix", 00791 "D3DRenderSystem::_setWorldMatrix"); 00792 } 00793 00794 //----------------------------------------------------------------------- 00795 void D3DRenderSystem::_setViewMatrix(const Matrix4 &m) 00796 { 00797 // save latest view matrix 00798 mViewMatrix = m; 00799 mViewMatrix[2][0] = -mViewMatrix[2][0]; 00800 mViewMatrix[2][1] = -mViewMatrix[2][1]; 00801 mViewMatrix[2][2] = -mViewMatrix[2][2]; 00802 mViewMatrix[2][3] = -mViewMatrix[2][3]; 00803 00804 D3DMATRIX d3dmat = makeD3DMatrix(mViewMatrix); 00805 00806 HRESULT hr = mlpD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &d3dmat); 00807 00808 if (FAILED(hr)) 00809 Except(hr, "Cannot set D3D view matrix", 00810 "D3DRenderSystem::_setViewMatrix"); 00811 00812 } 00813 //----------------------------------------------------------------------- 00814 void D3DRenderSystem::_setProjectionMatrix(const Matrix4 &m) 00815 { 00816 D3DMATRIX d3dmat = makeD3DMatrix(m); 00817 00818 if( mActiveRenderTarget->requiresTextureFlipping() ) 00819 { 00820 d3dmat._22 = - d3dmat._22; 00821 } 00822 00823 HRESULT hr = mlpD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &d3dmat); 00824 00825 if (FAILED(hr)) 00826 Except(hr, "Cannot set D3D projection matrix", 00827 "D3DRenderSystem::_setProjectionMatrix"); 00828 } 00829 00830 00831 //----------------------------------------------------------------------- 00832 void D3DRenderSystem::_setSurfaceParams(const ColourValue &ambient, 00833 const ColourValue &diffuse, const ColourValue &specular, 00834 const ColourValue &emissive, const Real shininess) 00835 { 00836 // Remember last call 00837 static ColourValue lastAmbient = ColourValue::Black; 00838 static ColourValue lastDiffuse = ColourValue::Black; 00839 static ColourValue lastSpecular = ColourValue::Black; 00840 static ColourValue lastEmissive = ColourValue::Black; 00841 static Real lastShininess = 0.0; 00842 00843 // Only update if changed 00844 if (ambient != lastAmbient || diffuse != lastDiffuse || 00845 specular != lastSpecular || emissive != lastEmissive || 00846 shininess != lastShininess) 00847 { 00848 00849 // Convert to D3D 00850 D3DMATERIAL7 d3dMat; 00851 00852 d3dMat.dcvDiffuse.r = diffuse.r; 00853 d3dMat.dcvDiffuse.g = diffuse.g; 00854 d3dMat.dcvDiffuse.b = diffuse.b; 00855 d3dMat.dcvDiffuse.a = diffuse.a; 00856 00857 d3dMat.dcvAmbient.r = ambient.r; 00858 d3dMat.dcvAmbient.g = ambient.g; 00859 d3dMat.dcvAmbient.b = ambient.b; 00860 d3dMat.dcvAmbient.a = ambient.a; 00861 00862 d3dMat.dcvSpecular.r = specular.r; 00863 d3dMat.dcvSpecular.g = specular.g; 00864 d3dMat.dcvSpecular.b = specular.b; 00865 d3dMat.dcvSpecular.a = specular.a; 00866 00867 d3dMat.dcvEmissive.r = emissive.r; 00868 d3dMat.dcvEmissive.g = emissive.g; 00869 d3dMat.dcvEmissive.b = emissive.b; 00870 d3dMat.dcvEmissive.a = emissive.a; 00871 00872 d3dMat.dvPower = shininess; 00873 00874 HRESULT hr = mlpD3DDevice->SetMaterial(&d3dMat); 00875 if (FAILED(hr)) 00876 Except(hr, "Error setting D3D material.", "D3DRenderSystem::_setSurfaceParams"); 00877 00878 } 00879 } 00880 //----------------------------------------------------------------------- 00881 void D3DRenderSystem::_setTexture(size_t stage, bool enabled, const String &texname) 00882 { 00883 HRESULT hr; 00884 D3DTexture* dt = static_cast< D3DTexture* >(TextureManager::getSingleton().getByName(texname)); 00885 if (enabled && dt) 00886 { 00887 LPDIRECTDRAWSURFACE7 pTex = dt->getDDSurface(); 00888 if (pTex != mTexStageDesc[stage].pTex) 00889 { 00890 hr = mlpD3DDevice->SetTexture(stage, pTex ); 00891 if (FAILED(hr)) 00892 Except(hr, "Unable to set texture in D3D.", "D3DRenderSystem::_setTexture"); 00893 00894 // set stage desc. 00895 mTexStageDesc[stage].texType = _ogreTexTypeToD3DTexType(dt->getTextureType()); 00896 mTexStageDesc[stage].pTex = pTex; 00897 } 00898 } 00899 else 00900 { 00901 hr = mlpD3DDevice->SetTexture(stage, 0); 00902 if (FAILED(hr)) 00903 Except(hr, "Unable to disable texture in D3D.", "D3DRenderSystem::_setTexture"); 00904 hr = __SetTextureStageState( stage, D3DTSS_COLOROP, D3DTOP_DISABLE ); 00905 if (FAILED(hr)) 00906 Except(hr, "Unable to disable texture in D3D.", "D3DRenderSystem::_setTexture"); 00907 00908 // set stage desc. to defaults 00909 mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE; 00910 mTexStageDesc[stage].coordIndex = 0; 00911 mTexStageDesc[stage].texType = D3D_TEX_TYPE_NORMAL; 00912 mTexStageDesc[stage].pTex = NULL; 00913 } 00914 } 00915 //--------------------------------------------------------------------- 00916 DWORD getD3DTexCalc(TexCoordCalcMethod tcc) 00917 { 00918 switch (tcc) 00919 { 00920 case TEXCALC_NONE: 00921 return 0; 00922 case TEXCALC_ENVIRONMENT_MAP: 00923 // D3D7 does not support spherical reflection 00924 return D3DTSS_TCI_CAMERASPACENORMAL; 00925 case TEXCALC_ENVIRONMENT_MAP_REFLECTION: 00926 return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; 00927 case TEXCALC_ENVIRONMENT_MAP_PLANAR: 00928 case TEXCALC_PROJECTIVE_TEXTURE: 00929 return D3DTSS_TCI_CAMERASPACEPOSITION; 00930 case TEXCALC_ENVIRONMENT_MAP_NORMAL: 00931 return D3DTSS_TCI_CAMERASPACENORMAL; 00932 } 00933 } 00934 //----------------------------------------------------------------------- 00935 void D3DRenderSystem::_setTextureCoordCalculation(size_t stage, TexCoordCalcMethod m, 00936 const Frustum* frustum) 00937 { 00938 HRESULT hr = S_OK; 00939 // record the stage state 00940 mTexStageDesc[stage].autoTexCoordType = m; 00941 mTexStageDesc[stage].frustum = frustum; 00942 00943 hr = __SetTextureStageState(stage, D3DTSS_TEXCOORDINDEX, 00944 getD3DTexCalc(m) | mTexStageDesc[stage].coordIndex); 00945 if( FAILED( hr ) ) 00946 Except( hr, "Error setting texture coord calculation", "D3DRenderSystem::_setTextureCoordCalculation" ); 00947 00948 } 00949 //----------------------------------------------------------------------- 00950 void D3DRenderSystem::_setTextureMatrix(size_t stage, const Matrix4& xForm) 00951 { 00952 HRESULT hr; 00953 D3DMATRIX d3dMat; // the matrix we'll maybe apply 00954 Matrix4 newMat = xForm; // the matrix we'll apply after conv. to D3D format 00955 00956 00957 /* If envmap is applied, since D3D7 doesn't support spheremap, 00958 then we have to use texture transform to make the camera space normal 00959 reference the envmap properly. This isn't exactly the same as spheremap 00960 (it looks nasty on flat areas because the camera space normals are the same) 00961 but it's the best approximation we have in the absence of a proper spheremap */ 00962 if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_ENVIRONMENT_MAP) 00963 { 00964 // concatenate with the xForm 00965 newMat = newMat.concatenate(Matrix4::CLIPSPACE2DTOIMAGESPACE); 00966 } 00967 00968 // If this is a cubic reflection, we need to modify using the view matrix 00969 if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_ENVIRONMENT_MAP_REFLECTION) 00970 { 00971 D3DMATRIX viewMatrix; 00972 00973 // Get view matrix 00974 mlpD3DDevice->GetTransform(D3DTRANSFORMSTATE_VIEW, &viewMatrix); 00975 // Get transposed 3x3, ie since D3D is transposed just copy 00976 // We want to transpose since that will invert an orthonormal matrix ie rotation 00977 Matrix4 ogreViewTransposed; 00978 ogreViewTransposed[0][0] = viewMatrix.m[0][0]; 00979 ogreViewTransposed[0][1] = viewMatrix.m[0][1]; 00980 ogreViewTransposed[0][2] = viewMatrix.m[0][2]; 00981 ogreViewTransposed[0][3] = 0.0f; 00982 00983 ogreViewTransposed[1][0] = viewMatrix.m[1][0]; 00984 ogreViewTransposed[1][1] = viewMatrix.m[1][1]; 00985 ogreViewTransposed[1][2] = viewMatrix.m[1][2]; 00986 ogreViewTransposed[1][3] = 0.0f; 00987 00988 ogreViewTransposed[2][0] = viewMatrix.m[2][0]; 00989 ogreViewTransposed[2][1] = viewMatrix.m[2][1]; 00990 ogreViewTransposed[2][2] = viewMatrix.m[2][2]; 00991 ogreViewTransposed[2][3] = 0.0f; 00992 00993 ogreViewTransposed[3][0] = 0.0f; 00994 ogreViewTransposed[3][1] = 0.0f; 00995 ogreViewTransposed[3][2] = 0.0f; 00996 ogreViewTransposed[3][3] = 1.0f; 00997 00998 newMat = newMat.concatenate(ogreViewTransposed); 00999 } 01000 01001 if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE) 01002 { 01003 // Derive camera space to projector space transform 01004 // To do this, we need to undo the camera view matrix, then 01005 // apply the projector view & projection matrices 01006 newMat = mViewMatrix.inverse() * newMat; 01007 newMat = mTexStageDesc[stage].frustum->getViewMatrix() * newMat; 01008 newMat = mTexStageDesc[stage].frustum->getProjectionMatrix() * newMat; 01009 if (mTexStageDesc[stage].frustum->getProjectionType() == PT_PERSPECTIVE) 01010 { 01011 newMat = PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * newMat; 01012 } 01013 else 01014 { 01015 newMat = PROJECTIONCLIPSPACE2DTOIMAGESPACE_ORTHO * newMat; 01016 } 01017 01018 } 01019 01020 // convert our matrix to D3D format 01021 d3dMat = makeD3DMatrix(newMat); 01022 01023 // need this if texture is a cube map, to invert D3D's z coord 01024 if (mTexStageDesc[stage].autoTexCoordType != TEXCALC_NONE) 01025 { 01026 d3dMat._13 = -d3dMat._13; 01027 d3dMat._23 = -d3dMat._23; 01028 d3dMat._33 = -d3dMat._33; 01029 d3dMat._43 = -d3dMat._43; 01030 } 01031 01032 // set the matrix if it's not the identity 01033 if (!(newMat == Matrix4::IDENTITY)) 01034 { 01035 // tell D3D the dimension of tex. coord. 01036 int texCoordDim; 01037 if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE) 01038 { 01039 texCoordDim = D3DTTFF_PROJECTED | D3DTTFF_COUNT3; 01040 } 01041 else 01042 { 01043 switch (mTexStageDesc[stage].texType) 01044 { 01045 case D3D_TEX_TYPE_NORMAL: 01046 texCoordDim = D3DTTFF_COUNT2; 01047 break; 01048 case D3D_TEX_TYPE_CUBE: 01049 case D3D_TEX_TYPE_VOLUME: 01050 texCoordDim = D3DTTFF_COUNT3; 01051 } 01052 } 01053 01054 hr = __SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, texCoordDim ); 01055 if (FAILED(hr)) 01056 Except( hr, "Unable to set texture coord. dimension", "D3D9RenderSystem::_setTextureMatrix" ); 01057 01058 hr = mlpD3DDevice->SetTransform( 01059 (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + stage), &d3dMat ); 01060 if (FAILED(hr)) 01061 Except( hr, "Unable to set texture matrix", "D3D9RenderSystem::_setTextureMatrix" ); 01062 } 01063 else 01064 { 01065 // disable all of this 01066 hr = __SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); 01067 if( FAILED( hr ) ) 01068 Except( hr, "Error setting texture matrix", "D3D9RenderSystem::_setTextureMatrix" ); 01069 01070 // set the identity matrix 01071 D3DUtil_SetIdentityMatrix( d3dMat ); 01072 hr = mlpD3DDevice->SetTransform( 01073 (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + stage), &d3dMat ); 01074 if( FAILED( hr ) ) 01075 Except( hr, "Error setting texture matrix", "D3D9RenderSystem::_setTextureMatrix" ); 01076 } 01077 } 01078 //--------------------------------------------------------------------- 01079 void D3DRenderSystem::_setTextureCoordSet( size_t stage, size_t index ) 01080 { 01081 HRESULT hr; 01082 hr = __SetTextureStageState( stage, D3DTSS_TEXCOORDINDEX, 01083 getD3DTexCalc(mTexStageDesc[stage].autoTexCoordType) | index ); 01084 if( FAILED( hr ) ) 01085 Except( hr, "Unable to set texture coord. set index", "D3DRenderSystem::_setTextureCoordSet" ); 01086 // Record settings 01087 mTexStageDesc[stage].coordIndex = index; 01088 } 01089 //----------------------------------------------------------------------- 01090 void D3DRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm) 01091 { 01092 HRESULT hr; 01093 D3DTEXTURESTAGESTATETYPE tss; 01094 DWORD value; 01095 01096 if (bm.blendType == LBT_COLOUR) 01097 { 01098 tss = D3DTSS_COLOROP; 01099 } 01100 else if (bm.blendType == LBT_ALPHA) 01101 { 01102 tss= D3DTSS_ALPHAOP; 01103 } 01104 01105 switch (bm.operation) 01106 { 01107 case LBX_SOURCE1: 01108 value = D3DTOP_SELECTARG1; 01109 break; 01110 case LBX_SOURCE2: 01111 value = D3DTOP_SELECTARG2; 01112 break; 01113 case LBX_MODULATE: 01114 value = D3DTOP_MODULATE; 01115 break; 01116 case LBX_MODULATE_X2: 01117 value = D3DTOP_MODULATE2X; 01118 break; 01119 case LBX_MODULATE_X4: 01120 value = D3DTOP_MODULATE4X; 01121 break; 01122 case LBX_ADD: 01123 value = D3DTOP_ADD; 01124 break; 01125 case LBX_ADD_SIGNED: 01126 value = D3DTOP_ADDSIGNED; 01127 break; 01128 case LBX_ADD_SMOOTH: 01129 value = D3DTOP_ADDSMOOTH; 01130 break; 01131 case LBX_SUBTRACT: 01132 value = D3DTOP_SUBTRACT; 01133 break; 01134 case LBX_BLEND_DIFFUSE_ALPHA: 01135 value = D3DTOP_BLENDDIFFUSEALPHA; 01136 break; 01137 case LBX_BLEND_TEXTURE_ALPHA: 01138 value = D3DTOP_BLENDTEXTUREALPHA; 01139 break; 01140 case LBX_BLEND_CURRENT_ALPHA: 01141 value = D3DTOP_BLENDCURRENTALPHA; 01142 break; 01143 case LBX_BLEND_MANUAL: 01144 value = D3DTOP_BLENDFACTORALPHA; 01145 // Set factor in render state 01146 hr = __SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, 01147 D3DRGBA(0,0,0,bm.factor)); 01148 break; 01149 case LBX_DOTPRODUCT: 01150 if (mD3DDeviceDesc.dwTextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) 01151 value = D3DTOP_DOTPRODUCT3; 01152 else 01153 value = D3DTOP_MODULATE; 01154 break; 01155 } 01156 01157 // Make call to set operation 01158 hr = __SetTextureStageState(stage, tss, value); 01159 01160 // Now set up sources 01161 D3DCOLOR manualD3D; 01162 if (bm.blendType == LBT_COLOUR) 01163 { 01164 tss = D3DTSS_COLORARG1; 01165 manualD3D = D3DRGBA(bm.colourArg1.r,bm.colourArg1.g,bm.colourArg1.b,1.0); 01166 } 01167 else if (bm.blendType == LBT_ALPHA) 01168 { 01169 tss = D3DTSS_ALPHAARG1; 01170 manualD3D = D3DRGBA(0,0,0,bm.alphaArg1); 01171 } 01172 LayerBlendSource bs = bm.source1; 01173 for (int i = 0; i < 2; ++i) 01174 { 01175 switch (bs) 01176 { 01177 case LBS_CURRENT: 01178 value = D3DTA_CURRENT; 01179 break; 01180 case LBS_TEXTURE: 01181 value = D3DTA_TEXTURE; 01182 break; 01183 case LBS_DIFFUSE: 01184 value = D3DTA_DIFFUSE; 01185 break; 01186 case LBS_SPECULAR: 01187 value = D3DTA_SPECULAR; 01188 break; 01189 case LBS_MANUAL: 01190 value = D3DTA_TFACTOR; 01191 // Set factor in render state 01192 hr = __SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, manualD3D); 01193 break; 01194 } 01195 01196 // Set source 01197 hr = __SetTextureStageState(stage, tss, value); 01198 01199 // Source2 01200 bs = bm.source2; 01201 if (bm.blendType == LBT_COLOUR) 01202 { 01203 tss = D3DTSS_COLORARG2; 01204 manualD3D = D3DRGBA(bm.colourArg2.r,bm.colourArg2.g,bm.colourArg2.b,1.0); 01205 } 01206 else if (bm.blendType == LBT_ALPHA) 01207 { 01208 tss = D3DTSS_ALPHAARG2; 01209 manualD3D = D3DRGBA(0,0,0,bm.alphaArg2); 01210 } 01211 } 01212 } 01213 //----------------------------------------------------------------------- 01214 void D3DRenderSystem::_setTextureAddressingMode(size_t stage, TextureUnitState::TextureAddressingMode tam) 01215 { 01216 HRESULT hr; 01217 D3DTEXTUREADDRESS d3dType; 01218 01219 switch(tam) 01220 { 01221 case TextureUnitState::TAM_WRAP: 01222 d3dType = D3DTADDRESS_WRAP; 01223 break; 01224 case TextureUnitState::TAM_MIRROR: 01225 d3dType = D3DTADDRESS_MIRROR; 01226 break; 01227 case TextureUnitState::TAM_CLAMP: 01228 d3dType = D3DTADDRESS_CLAMP; 01229 break; 01230 } 01231 01232 01233 hr = __SetTextureStageState(stage, D3DTSS_ADDRESS, d3dType); 01234 } 01235 //----------------------------------------------------------------------- 01236 void D3DRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor) 01237 { 01238 HRESULT hr; 01239 D3DBLEND d3dSrcBlend, d3dDestBlend; 01240 01241 D3DBLEND* pBlend = &d3dSrcBlend; 01242 SceneBlendFactor ogreBlend = sourceFactor; 01243 01244 for (int i = 0 ; i < 2; ++i) 01245 { 01246 switch(ogreBlend) 01247 { 01248 case SBF_ONE: 01249 *pBlend = D3DBLEND_ONE; 01250 break; 01251 case SBF_ZERO: 01252 *pBlend = D3DBLEND_ZERO; 01253 break; 01254 case SBF_DEST_COLOUR: 01255 *pBlend = D3DBLEND_DESTCOLOR; 01256 break; 01257 case SBF_SOURCE_COLOUR: 01258 *pBlend = D3DBLEND_SRCCOLOR; 01259 break; 01260 case SBF_ONE_MINUS_DEST_COLOUR: 01261 *pBlend = D3DBLEND_INVDESTCOLOR; 01262 break; 01263 case SBF_ONE_MINUS_SOURCE_COLOUR: 01264 *pBlend = D3DBLEND_INVSRCCOLOR; 01265 break; 01266 case SBF_DEST_ALPHA: 01267 *pBlend = D3DBLEND_DESTALPHA; 01268 break; 01269 case SBF_SOURCE_ALPHA: 01270 *pBlend = D3DBLEND_SRCALPHA; 01271 break; 01272 case SBF_ONE_MINUS_DEST_ALPHA: 01273 *pBlend = D3DBLEND_INVDESTALPHA; 01274 break; 01275 case SBF_ONE_MINUS_SOURCE_ALPHA: 01276 *pBlend = D3DBLEND_INVSRCALPHA; 01277 break; 01278 } 01279 ogreBlend = destFactor; 01280 pBlend = &d3dDestBlend; 01281 01282 } 01283 01284 hr = __SetRenderState(D3DRENDERSTATE_SRCBLEND, d3dSrcBlend); 01285 01286 hr = __SetRenderState(D3DRENDERSTATE_DESTBLEND, d3dDestBlend); 01287 01288 // Save last scene blend, because colour write off is simulated 01289 // through scene blend 01290 mSavedDestFactor = destFactor; 01291 mSavedSrcFactor = sourceFactor; 01292 01293 01294 } 01295 //----------------------------------------------------------------------- 01296 void D3DRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value) 01297 { 01298 HRESULT hr; 01299 if (func != CMPF_ALWAYS_PASS) 01300 { 01301 if( FAILED( hr = __SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, TRUE ) ) ) 01302 Except( hr, "Failed to enable alpha testing", 01303 "D3DRenderSystem::_setAlphaRejectSettings" ); 01304 } 01305 else 01306 { 01307 if( FAILED( hr = __SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, FALSE ) ) ) 01308 Except( hr, "Failed to disable alpha testing", 01309 "D3DRenderSystem::_setAlphaRejectSettings" ); 01310 } 01311 01312 // Set always just be sure 01313 hr = __SetRenderState(D3DRENDERSTATE_ALPHAFUNC, 01314 convertCompareFunction(func)); 01315 01316 hr = __SetRenderState(D3DRENDERSTATE_ALPHAREF, value); 01317 } 01318 //----------------------------------------------------------------------- 01319 void D3DRenderSystem::_setViewport(Viewport *vp) 01320 { 01321 // Check if viewport is different 01322 if (vp != mActiveViewport || vp->_isUpdated()) 01323 { 01324 mActiveViewport = vp; 01325 mActiveRenderTarget = vp->getTarget(); 01326 // Ok, it's different. Time to set render target (maybe) 01327 // and viewport params. 01328 D3DVIEWPORT7 d3dvp; 01329 HRESULT hr; 01330 01331 // Set render target 01332 // TODO - maybe only set when required? 01333 RenderTarget* target; 01334 target = vp->getTarget(); 01335 // Get DD Back buffer 01336 LPDIRECTDRAWSURFACE7 pBack; 01337 target->getCustomAttribute("DDBACKBUFFER", &pBack); 01338 01339 hr = mlpD3DDevice->SetRenderTarget( pBack, 0 ); 01340 01341 _setCullingMode( mCullingMode ); 01342 01343 // Set viewport dimensions 01344 d3dvp.dwX = vp->getActualLeft(); 01345 d3dvp.dwY = vp->getActualTop(); 01346 d3dvp.dwWidth = vp->getActualWidth(); 01347 d3dvp.dwHeight = vp->getActualHeight(); 01348 01349 // Z-values from 0.0 to 1.0 (TODO - standardise with OpenGL?) 01350 d3dvp.dvMinZ = 0.0f; 01351 d3dvp.dvMaxZ = 1.0f; 01352 01353 hr = mlpD3DDevice->SetViewport(&d3dvp); 01354 01355 if (FAILED(hr)) 01356 Except(hr, "Error setting D3D viewport.", 01357 "D3DRenderSystem::_setViewport"); 01358 01359 vp->_clearUpdatedFlag(); 01360 01361 } 01362 } 01363 01364 //----------------------------------------------------------------------- 01365 void D3DRenderSystem::_beginFrame(void) 01366 { 01367 OgreGuard( "D3DRenderSystem::_beginFrame" ); 01368 01369 HRESULT hr; 01370 01371 if (!mActiveViewport) 01372 Except(999, "Cannot begin frame - no viewport selected.", 01373 "D3DRenderSystem::_beginFrame"); 01374 01375 // Clear the viewport if required 01376 if (mActiveViewport->getClearEveryFrame()) 01377 { 01378 clearFrameBuffer(FBT_COLOUR | FBT_DEPTH, 01379 mActiveViewport->getBackgroundColour()); 01380 } 01381 01382 hr = mlpD3DDevice->BeginScene(); 01383 if (FAILED(hr)) 01384 Except(hr, "Error beginning frame.", 01385 "D3DRenderSystem::_beginFrame"); 01386 01387 // Moved here from _render, no point checking every rendering call 01388 static bool firstTime = true; 01389 if (firstTime) 01390 { 01391 // First-time setup 01392 // Set up some defaults 01393 01394 // Allow alpha blending 01395 hr = __SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); 01396 if (FAILED(hr)) 01397 Except(hr, "Error enabling alpha blending option.", 01398 "D3DRenderSystem::_beginFrame"); 01399 01400 // Allow specular effects 01401 hr = __SetRenderState(D3DRENDERSTATE_SPECULARENABLE, TRUE); 01402 if (FAILED(hr)) 01403 Except(hr, "Error enabling specular option.", 01404 "D3DRenderSystem::_beginFrame"); 01405 01406 firstTime = false; 01407 } 01408 01409 OgreUnguard(); 01410 } 01411 01412 //----------------------------------------------------------------------- 01413 void D3DRenderSystem::_render(const RenderOperation& op) 01414 { 01415 OgreGuard( "D3DRenderSystem::_render" ); 01416 HRESULT hr; 01417 01418 // Exit immediately if there is nothing to render 01419 // Passing 0 arguments causes problems for Direct3D 01420 if (op.vertexData->vertexCount == 0 || 01421 (op.useIndexes && op.indexData->indexCount == 0)) 01422 return; 01423 01424 // call superclass 01425 RenderSystem::_render(op); 01426 // Set up vertex flags 01427 DWORD d3dVertexFormat = 0; 01428 unsigned int numTexCoords = 0; 01429 01430 // Assume no more than 10 buffers! 01431 static unsigned char* pBufPtrs[10]; 01432 01433 // Lock all the buffers first 01434 // They're system memory buffers anyway 01435 const VertexBufferBinding::VertexBufferBindingMap binds = 01436 op.vertexData->vertexBufferBinding->getBindings(); 01437 VertexBufferBinding::VertexBufferBindingMap::const_iterator bindi, bindend; 01438 bindend = binds.end(); 01439 for (bindi = binds.begin(); bindi != bindend; ++bindi) 01440 { 01441 // lock from vertex start only 01442 pBufPtrs[bindi->first] = static_cast<unsigned char*>( 01443 bindi->second->lock( 01444 op.vertexData->vertexStart * bindi->second->getVertexSize(), 01445 op.vertexData->vertexCount * bindi->second->getVertexSize(), 01446 HardwareBuffer::HBL_READ_ONLY) 01447 ); 01448 01449 } 01450 01451 // Determine vertex format 01452 01453 // Struct for data pointers 01454 D3DDRAWPRIMITIVESTRIDEDDATA strideData; 01455 01456 // Iterate over elements 01457 VertexDeclaration::VertexElementList::const_iterator elemi, elemend; 01458 const VertexDeclaration::VertexElementList elems = 01459 op.vertexData->vertexDeclaration->getElements(); 01460 elemend = elems.end(); 01461 for (elemi = elems.begin(); elemi != elemend; ++elemi) 01462 { 01463 // Get a few basic details 01464 const VertexElement& elem = *elemi; 01465 unsigned short source = elem.getSource(); 01466 size_t vertexSize = op.vertexData->vertexDeclaration->getVertexSize(source); 01467 size_t offset = elem.getOffset(); 01468 // semantic-specific stuff 01469 switch (elem.getSemantic()) 01470 { 01471 case VES_POSITION: 01472 d3dVertexFormat |= D3DFVF_XYZ; // Untransformed 01473 strideData.position.lpvData = pBufPtrs[source] + offset; 01474 strideData.position.dwStride = static_cast<DWORD>(vertexSize); 01475 // Set up pointer 01476 break; 01477 case VES_NORMAL: 01478 d3dVertexFormat |= D3DFVF_NORMAL; 01479 strideData.normal.lpvData = pBufPtrs[source] + offset; 01480 strideData.normal.dwStride = static_cast<DWORD>(vertexSize); 01481 break; 01482 case VES_DIFFUSE: 01483 d3dVertexFormat |= D3DFVF_DIFFUSE; 01484 strideData.diffuse.lpvData = pBufPtrs[source] + offset; 01485 strideData.diffuse.dwStride = static_cast<DWORD>(vertexSize); 01486 break; 01487 case VES_SPECULAR: 01488 d3dVertexFormat |= D3DFVF_SPECULAR; 01489 strideData.specular.lpvData = pBufPtrs[source] + offset; 01490 strideData.specular.dwStride = static_cast<DWORD>(vertexSize); 01491 break; 01492 case VES_TEXTURE_COORDINATES: 01493 // texcoords must go in order 01494 if (elem.getIndex() != numTexCoords) 01495 { 01496 Except(Exception::ERR_INVALIDPARAMS, "Invalid vertex format, texture coordinates" 01497 " must be in order wih no gaps.", "D3DRenderSystem::_render"); 01498 } 01499 // Don't add D3DFVF_TEXn flag here, wait until we know how many total 01500 // However, specify size 01501 switch (elem.getType()) 01502 { 01503 case VET_FLOAT1: 01504 d3dVertexFormat |= D3DFVF_TEXCOORDSIZE1(numTexCoords); 01505 break; 01506 case VET_FLOAT2: 01507 d3dVertexFormat |= D3DFVF_TEXCOORDSIZE2(numTexCoords); 01508 break; 01509 case VET_FLOAT3: 01510 d3dVertexFormat |= D3DFVF_TEXCOORDSIZE3(numTexCoords); 01511 break; 01512 case VET_FLOAT4: 01513 d3dVertexFormat |= D3DFVF_TEXCOORDSIZE4(numTexCoords); 01514 break; 01515 } 01516 01517 strideData.textureCoords[numTexCoords].lpvData = pBufPtrs[source] + offset; 01518 strideData.textureCoords[numTexCoords].dwStride = static_cast<DWORD>(vertexSize); 01519 01520 // Increment number of coords 01521 ++numTexCoords; 01522 } 01523 01524 } 01525 // Add combined texture flag 01526 switch(numTexCoords) 01527 { 01528 case 0: 01529 // do nothing 01530 break; 01531 case 1: 01532 d3dVertexFormat |= D3DFVF_TEX1; 01533 break; 01534 case 2: 01535 d3dVertexFormat |= D3DFVF_TEX2; 01536 break; 01537 case 3: 01538 d3dVertexFormat |= D3DFVF_TEX3; 01539 break; 01540 case 4: 01541 d3dVertexFormat |= D3DFVF_TEX4; 01542 break; 01543 case 5: 01544 d3dVertexFormat |= D3DFVF_TEX5; 01545 break; 01546 case 6: 01547 d3dVertexFormat |= D3DFVF_TEX6; 01548 break; 01549 case 7: 01550 d3dVertexFormat |= D3DFVF_TEX7; 01551 break; 01552 case 8: 01553 d3dVertexFormat |= D3DFVF_TEX8; 01554 break; 01555 } 01556 01557 // Determine rendering operation 01558 D3DPRIMITIVETYPE primType; 01559 switch (op.operationType) 01560 { 01561 case RenderOperation::OT_POINT_LIST: 01562 primType = D3DPT_POINTLIST; 01563 break; 01564 case RenderOperation::OT_LINE_LIST: 01565 primType = D3DPT_LINELIST; 01566 break; 01567 case RenderOperation::OT_LINE_STRIP: 01568 primType = D3DPT_LINESTRIP; 01569 break; 01570 case RenderOperation::OT_TRIANGLE_LIST: 01571 primType = D3DPT_TRIANGLELIST; 01572 break; 01573 case RenderOperation::OT_TRIANGLE_STRIP: 01574 primType = D3DPT_TRIANGLESTRIP; 01575 break; 01576 case RenderOperation::OT_TRIANGLE_FAN: 01577 primType = D3DPT_TRIANGLEFAN; 01578 break; 01579 } 01580 01581 01582 if (op.useIndexes) 01583 { 01584 // Get pointer to index buffer 01585 // D3D7 only allows 16-bit indexes, this is enforced in buffer manager 01586 unsigned short* pIdx = static_cast<unsigned short*>( 01587 op.indexData->indexBuffer->lock( 01588 op.indexData->indexStart, 01589 op.indexData->indexCount * sizeof(unsigned short), 01590 HardwareBuffer::HBL_READ_ONLY) ); 01591 01592 hr = mlpD3DDevice->DrawIndexedPrimitiveStrided(primType, 01593 d3dVertexFormat, 01594 &strideData, 01595 static_cast<DWORD>(op.vertexData->vertexCount), 01596 pIdx, 01597 static_cast<DWORD>(op.indexData->indexCount) 01598 , 0); 01599 } 01600 else 01601 { 01602 hr = mlpD3DDevice->DrawPrimitiveStrided(primType, 01603 d3dVertexFormat, 01604 &strideData, 01605 static_cast<DWORD>(op.vertexData->vertexCount), 01606 0); 01607 } 01608 01609 // unlock buffers 01610 for (bindi = binds.begin(); bindi != bindend; ++bindi) 01611 { 01612 bindi->second->unlock(); 01613 } 01614 01615 if (FAILED(hr)) 01616 { 01617 char szBuffer[512]; 01618 D3DXGetErrorString( hr, 512, szBuffer ); 01619 Except( hr, szBuffer, "D3DRenderSystem::_render"); 01620 } 01621 01622 01623 01624 01625 OgreUnguard(); 01626 } 01627 01628 //----------------------------------------------------------------------- 01629 void D3DRenderSystem::_endFrame(void) 01630 { 01631 OgreGuard( "D3DRenderSystem::_endFrame" ); 01632 01633 HRESULT hr; 01634 hr = mlpD3DDevice->EndScene(); 01635 01636 if (FAILED(hr)) 01637 Except(hr, "Error ending frame.", 01638 "D3DRenderSystem::_endFrame"); 01639 01640 OgreUnguard(); 01641 } 01642 01643 //----------------------------------------------------------------------- 01644 void D3DRenderSystem::_setCullingMode(CullingMode mode) 01645 { 01646 HRESULT hr; 01647 DWORD d3dMode; 01648 01649 mCullingMode = mode; 01650 01651 if (mode == CULL_NONE) 01652 { 01653 d3dMode = D3DCULL_NONE; 01654 } 01655 else if( mode == CULL_CLOCKWISE ) 01656 { 01657 if( (mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || 01658 (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)) 01659 d3dMode = D3DCULL_CCW; 01660 else 01661 d3dMode = D3DCULL_CW; 01662 } 01663 else if (mode == CULL_ANTICLOCKWISE) 01664 { 01665 if( (mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || 01666 (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)) 01667 d3dMode = D3DCULL_CW; 01668 else 01669 d3dMode = D3DCULL_CCW; 01670 } 01671 01672 hr = __SetRenderState(D3DRENDERSTATE_CULLMODE, d3dMode); 01673 if (FAILED(hr)) 01674 Except(hr, "Unable to set D3D culling mode.", 01675 "D3DRenderSystem::_setCullingMode"); 01676 01677 } 01678 01679 //----------------------------------------------------------------------- 01680 void D3DRenderSystem::_setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction) 01681 { 01682 _setDepthBufferCheckEnabled(depthTest); 01683 _setDepthBufferWriteEnabled(depthWrite); 01684 _setDepthBufferFunction(depthFunction); 01685 01686 } 01687 //----------------------------------------------------------------------- 01688 void D3DRenderSystem::_setDepthBufferCheckEnabled(bool enabled) 01689 { 01690 HRESULT hr; 01691 01692 if (enabled) 01693 { 01694 // Use w-buffer if available and enabled 01695 if (mWBuffer && mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_WBUFFER) 01696 hr = __SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_USEW); 01697 else 01698 hr = __SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE); 01699 if (FAILED(hr)) 01700 Except(hr, "Error setting depth buffer test state.", 01701 "D3DRenderSystem::_setDepthBufferCheckEnabled"); 01702 } 01703 else 01704 { 01705 hr = __SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); 01706 if (FAILED(hr)) 01707 Except(hr, "Error setting depth buffer test state.", 01708 "D3DRenderSystem::_setDepthBufferCheckEnabled"); 01709 } 01710 } 01711 //----------------------------------------------------------------------- 01712 void D3DRenderSystem::_setDepthBufferWriteEnabled(bool enabled) 01713 { 01714 HRESULT hr; 01715 01716 hr = __SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, enabled); 01717 if (FAILED(hr)) 01718 Except(hr, "Error setting depth buffer write state.", 01719 "D3DRenderSystem::_setDepthBufferWriteEnabled"); 01720 } 01721 //----------------------------------------------------------------------- 01722 void D3DRenderSystem::_setDepthBufferFunction(CompareFunction func) 01723 { 01724 HRESULT hr = __SetRenderState(D3DRENDERSTATE_ZFUNC, 01725 convertCompareFunction(func)); 01726 if (FAILED(hr)) 01727 Except(hr, "Error setting depth buffer test function.", 01728 "D3DRenderSystem::_setDepthBufferFunction"); 01729 } 01730 //----------------------------------------------------------------------- 01731 void D3DRenderSystem::_setDepthBias(ushort bias) 01732 { 01733 HRESULT hr = __SetRenderState(D3DRENDERSTATE_ZBIAS, 01734 bias); 01735 if (FAILED(hr)) 01736 Except(hr, "Error setting depth bias.", 01737 "D3DRenderSystem::_setDepthBias"); 01738 } 01739 //----------------------------------------------------------------------- 01740 String D3DRenderSystem::getErrorDescription(long errCode) const 01741 { 01742 char* errDesc; 01743 DWORD i; 01744 01745 errDesc = new char[255]; 01746 // Try windows errors first 01747 i = FormatMessage( 01748 FORMAT_MESSAGE_FROM_HMODULE | 01749 FORMAT_MESSAGE_FROM_SYSTEM | 01750 FORMAT_MESSAGE_IGNORE_INSERTS, 01751 NULL, 01752 DDERR_SURFACELOST, 01753 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 01754 (LPTSTR) errDesc, 01755 255, 01756 NULL 01757 ); 01758 01759 01760 if (i == 0) 01761 { 01762 // Not found in windows message descriptions 01763 switch (errCode) 01764 { 01765 case DD_OK: 01766 strcpy(errDesc, "DD_OK: The request completed successfully."); 01767 break; 01768 case DDERR_ALREADYINITIALIZED: 01769 strcpy(errDesc, "DDERR_ALREADYINITIALIZED: The object has already been initialized."); 01770 break; 01771 case DDERR_BLTFASTCANTCLIP : 01772 strcpy(errDesc, "DDERR_BLTFASTCANTCLIP: A DirectDrawClipper object is attached to a source surface that has passed into a call to the IDirectDrawSurface7::BltFast method."); 01773 break; 01774 case DDERR_CANNOTATTACHSURFACE: 01775 strcpy(errDesc, "DDERR_CANNOTATTACHSURFACE: A surface cannot be attached to another requested surface."); 01776 break; 01777 case DDERR_CANNOTDETACHSURFACE: 01778 strcpy(errDesc, "DDERR_CANNOTATTACHSURFACE: A surface cannot be detached from another requested surface."); 01779 break; 01780 case DDERR_CANTCREATEDC: 01781 strcpy(errDesc, "DDERR_CANTCREATEDC: Windows can not create any more device contexts (DCs), or a DC was requested for a palette-indexed surface when the surface had no palette and the display mode was not palette-indexed."); 01782 break; 01783 case DDERR_CANTDUPLICATE: 01784 strcpy(errDesc, "DDERR_CANTDUPLICATE: Primary and 3-D surfaces, or surfaces that are implicitly created, cannot be duplicated."); 01785 break; 01786 case DDERR_CANTLOCKSURFACE: 01787 strcpy(errDesc, "DDERR_CANTLOCKSURFACE: Access to this surface is refused because an attempt was made to lock the primary surface without DCI support."); 01788 break; 01789 case DDERR_CANTPAGELOCK: 01790 strcpy(errDesc, "DDERR_CANTPAGELOCK: An attempt to page lock a surface failed. Page lock will not work on a display-memory surface or an emulated primary surface."); 01791 break; 01792 case DDERR_CANTPAGEUNLOCK: 01793 strcpy(errDesc, "DDERR_CANTPAGEUNLOCK: An attempt to page unlock a surface failed. Page unlock will not work on a display-memory surface or an emulated primary surface."); 01794 break; 01795 case DDERR_CLIPPERISUSINGHWND: 01796 strcpy(errDesc, "DDERR_CLIPPERISUSINGHWND: An attempt was made to set a clip list for a DirectDrawClipper object that is already monitoring a window handle."); 01797 break; 01798 case DDERR_COLORKEYNOTSET: 01799 strcpy(errDesc, "DDERR_COLORKEYNOTSET: No source color key is specified for this operation."); 01800 break; 01801 case DDERR_CURRENTLYNOTAVAIL: 01802 strcpy(errDesc, "DDERR_CURRENTLYNOTAVAIL: No support is currently available."); 01803 break; 01804 case DDERR_DCALREADYCREATED: 01805 strcpy(errDesc, "DDERR_DCALREADYCREATED: A device context (DC) has already been returned for this surface. Only one DC can be retrieved for each surface."); 01806 break; 01807 case DDERR_DEVICEDOESNTOWNSURFACE: 01808 strcpy(errDesc, "DDERR_DEVICEDOESNTOWNSURFACE: Surfaces created by one DirectDraw device cannot be used directly by another DirectDraw device."); 01809 break; 01810 case DDERR_DIRECTDRAWALREADYCREATED: 01811 strcpy(errDesc, "DDERR_DIRECTDRAWALREADYCREATED: A DirectDraw object representing this driver has already been created for this process."); 01812 break; 01813 case DDERR_EXCEPTION: 01814 strcpy(errDesc, "DDERR_EXCEPTION: An exception was encountered while performing the requested operation."); 01815 break; 01816 case DDERR_EXCLUSIVEMODEALREADYSET: 01817 strcpy(errDesc, "DDERR_EXCLUSIVEMODEALREADYSET: An attempt was made to set the cooperative level when it was already set to exclusive."); 01818 break; 01819 case DDERR_EXPIRED: 01820 strcpy(errDesc, "DDERR_EXPIRED: The data has expired and is therefore no longer valid."); 01821 break; 01822 case DDERR_GENERIC: 01823 strcpy(errDesc, "DDERR_GENERIC: There is an undefined error condition."); 01824 break; 01825 case DDERR_HEIGHTALIGN: 01826 strcpy(errDesc, "DDERR_HEIGHTALIGN: The height of the provided rectangle is not a multiple of the required alignment."); 01827 break; 01828 case DDERR_HWNDALREADYSET: 01829 strcpy(errDesc, "DDERR_HWNDALREADYSET: The DirectDraw cooperative level window handle has already been set. It cannot be reset while the process has surfaces or palettes created."); 01830 break; 01831 case DDERR_HWNDSUBCLASSED: 01832 strcpy(errDesc, "DDERR_HWNDSUBCLASSED: DirectDraw is prevented from restoring state because the DirectDraw cooperative level window handle has been subclassed."); 01833 break; 01834 case DDERR_IMPLICITLYCREATED: 01835 strcpy(errDesc, "DDERR_IMPLICITLYCREATED: The surface cannot be restored because it is an implicitly created surface."); 01836 break; 01837 case DDERR_INCOMPATIBLEPRIMARY: 01838 strcpy(errDesc, "DDERR_INCOMPATIBLEPRIMARY: The primary surface creation request does not match with the existing primary surface."); 01839 break; 01840 case DDERR_INVALIDCAPS: 01841 strcpy(errDesc, "DDERR_INVALIDCAPS: One or more of the capability bits passed to the callback function are incorrect."); 01842 break; 01843 case DDERR_INVALIDCLIPLIST: 01844 strcpy(errDesc, "DDERR_INVALIDCLIPLIST: DirectDraw does not support the provided clip list."); 01845 break; 01846 case DDERR_INVALIDDIRECTDRAWGUID: 01847 strcpy(errDesc, "DDERR_INVALIDDIRECTDRAWGUID: The globally unique identifier (GUID) passed to the DirectDrawCreate function is not a valid DirectDraw driver identifier."); 01848 break; 01849 case DDERR_INVALIDMODE: 01850 strcpy(errDesc, "DDERR_INVALIDMODE: DirectDraw does not support the requested mode."); 01851 break; 01852 case DDERR_INVALIDOBJECT: 01853 strcpy(errDesc, "DDERR_INVALIDOBJECT: DirectDraw received a pointer that was an invalid DirectDraw object."); 01854 break; 01855 case DDERR_INVALIDPARAMS: 01856 strcpy(errDesc, "DDERR_INVALIDPARAMS: One or more of the parameters passed to the method are incorrect."); 01857 break; 01858 case DDERR_INVALIDPIXELFORMAT: 01859 strcpy(errDesc, "DDERR_INVALIDPIXELFORMAT: The pixel format was invalid as specified."); 01860 break; 01861 case DDERR_INVALIDPOSITION: 01862 strcpy(errDesc, "DDERR_INVALIDPOSITION: The position of the overlay on the destination is no longer legal."); 01863 break; 01864 case DDERR_INVALIDRECT: 01865 strcpy(errDesc, "DDERR_INVALIDRECT: The provided rectangle was invalid."); 01866 break; 01867 case DDERR_INVALIDSTREAM: 01868 strcpy(errDesc, "DDERR_INVALIDSTREAM: The specified stream contains invalid data."); 01869 break; 01870 case DDERR_INVALIDSURFACETYPE: 01871 strcpy(errDesc, "DDERR_INVALIDSURFACETYPE: The requested operation could not be performed because the surface was of the wrong type."); 01872 break; 01873 case DDERR_LOCKEDSURFACES: 01874 strcpy(errDesc, "DDERR_LOCKEDSURFACES: One or more surfaces are locked, causing the failure of the requested operation."); 01875 break; 01876 case DDERR_MOREDATA: 01877 strcpy(errDesc, "DDERR_MOREDATA: There is more data available than the specified buffer size can hold."); 01878 break; 01879 case DDERR_NO3D: 01880 strcpy(errDesc, "DDERR_NO3D: No 3-D hardware or emulation is present."); 01881 break; 01882 case DDERR_NOALPHAHW: 01883 strcpy(errDesc, "DDERR_NOALPHAHW: No alpha acceleration hardware is present or available, causing the failure of the requested operation."); 01884 break; 01885 case DDERR_NOBLTHW: 01886 strcpy(errDesc, "DDERR_NOBLTHW: No blitter hardware is present."); 01887 break; 01888 case DDERR_NOCLIPLIST: 01889 strcpy(errDesc, "DDERR_NOCLIPLIST: No clip list is available."); 01890 break; 01891 case DDERR_NOCLIPPERATTACHED: 01892 strcpy(errDesc, "DDERR_NOCLIPPERATTACHED: No DirectDrawClipper object is attached to the surface object."); 01893 break; 01894 case DDERR_NOCOLORCONVHW: 01895 strcpy(errDesc, "DDERR_NOCOLORCONVHW: The operation cannot be carried out because no color-conversion hardware is present or available."); 01896 break; 01897 case DDERR_NOCOLORKEY: 01898 strcpy(errDesc, "DDERR_NOCOLORKEY: The surface does not currently have a color key."); 01899 break; 01900 case DDERR_NOCOLORKEYHW: 01901 strcpy(errDesc, "DDERR_NOCOLORKEYHW: The operation cannot be carried out because there is no hardware support for the destination color key."); 01902 break; 01903 case DDERR_NOCOOPERATIVELEVELSET: 01904 strcpy(errDesc, "DDERR_NOCOOPERATIVELEVELSET: A create function is called without the IDirectDraw7::SetCooperativeLevel method being called."); 01905 break; 01906 case DDERR_NODC: 01907 strcpy(errDesc, "DDERR_NODC: No DC has ever been created for this surface."); 01908 break; 01909 case DDERR_NODDROPSHW: 01910 strcpy(errDesc, "DDERR_NODDROPSHW: No DirectDraw raster operation (ROP) hardware is available."); 01911 break; 01912 case DDERR_NODIRECTDRAWHW: 01913 strcpy(errDesc, "DDERR_NODIRECTDRAWHW: Hardware-only DirectDraw object creation is not possible; the driver does not support any hardware."); 01914 break; 01915 case DDERR_NODIRECTDRAWSUPPORT: 01916 strcpy(errDesc, "DDERR_NODIRECTDRAWSUPPORT: DirectDraw support is not possible with the current display driver."); 01917 break; 01918 case DDERR_NOEMULATION: 01919 strcpy(errDesc, "DDERR_NOEMULATION: Software emulation is not available."); 01920 break; 01921 case DDERR_NOEXCLUSIVEMODE: 01922 strcpy(errDesc, "DDERR_NOEXCLUSIVEMODE: The operation requires the application to have exclusive mode, but the application does not have exclusive mode."); 01923 break; 01924 case DDERR_NOFLIPHW: 01925 strcpy(errDesc, "DDERR_NOFLIPHW: Flipping visible surfaces is not supported."); 01926 break; 01927 case DDERR_NOFOCUSWINDOW: 01928 strcpy(errDesc, "DDERR_NOFOCUSWINDOW: An attempt was made to create or set a device window without first setting the focus window."); 01929 break; 01930 case DDERR_NOGDI: 01931 strcpy(errDesc, "DDERR_NOGDI: No GDI is present."); 01932 break; 01933 case DDERR_NOHWND: 01934 strcpy(errDesc, "DDERR_NOHWND: Clipper notification requires a window handle, or no window handle has been previously set as the cooperative level window handle."); 01935 break; 01936 case DDERR_NOMIPMAPHW: 01937 strcpy(errDesc, "DDERR_NOMIPMAPHW: The operation cannot be carried out because no mipmap capable texture mapping hardware is present or available."); 01938 break; 01939 case DDERR_NOMIRRORHW: 01940 strcpy(errDesc, "DDERR_NOMIRRORHW: The operation cannot be carried out because no mirroring hardware is present or available."); 01941 break; 01942 case DDERR_NONONLOCALVIDMEM: 01943 strcpy(errDesc, "DDERR_NONONLOCALVIDMEM: An attempt was made to allocate non-local video memory from a device that does not support non-local video memory."); 01944 break; 01945 case DDERR_NOOPTIMIZEHW: 01946 strcpy(errDesc, "DDERR_NOOPTIMIZEHW: The device does not support optimized surfaces."); 01947 break; 01948 case DDERR_NOOVERLAYDEST: 01949 strcpy(errDesc, "DDERR_NOOVERLAYDEST: The IDirectDrawSurface4::GetOverlayPosition method is called on an overlay that the IDirectDrawSurface7::UpdateOverlay method has not been called on to establish a destination."); 01950 break; 01951 case DDERR_NOOVERLAYHW: 01952 strcpy(errDesc, "DDERR_NOOVERLAYHW: The operation cannot be carried out because no overlay hardware is present or available."); 01953 break; 01954 case DDERR_NOPALETTEATTACHED: 01955 strcpy(errDesc, "DDERR_NOPALETTEATTACHED: No palette object is attached to this surface."); 01956 break; 01957 case DDERR_NOPALETTEHW: 01958 strcpy(errDesc, "DDERR_NOPALETTEHW: There is no hardware support for 16- or 256-color palettes."); 01959 break; 01960 case DDERR_NORASTEROPHW: 01961 strcpy(errDesc, "DDERR_NORASTEROPHW: The operation cannot be carried out because no appropriate raster operation hardware is present or available."); 01962 break; 01963 case DDERR_NOROTATIONHW: 01964 strcpy(errDesc, "DDERR_NOROTATIONHW: The operation cannot be carried out because no rotation hardware is present or available."); 01965 break; 01966 case DDERR_NOSTRETCHHW: 01967 strcpy(errDesc, "DDERR_NOSTRETCHHW: The operation cannot be carried out because there is no hardware support for stretching."); 01968 break; 01969 case DDERR_NOT4BITCOLOR: 01970 strcpy(errDesc, "DDERR_NOT4BITCOLOR: The DirectDrawSurface object is not using a 4-bit color palette and the requested operation requires a 4-bit color palette."); 01971 break; 01972 case DDERR_NOT4BITCOLORINDEX: 01973 strcpy(errDesc, "DDERR_NOT4BITCOLORINDEX: The DirectDrawSurface object is not using a 4-bit color index palette and the requested operation requires a 4-bit color index palette."); 01974 break; 01975 case DDERR_NOT8BITCOLOR: 01976 strcpy(errDesc, "DDERR_NOT8BITCOLOR: The DirectDrawSurface object is not using an 8-bit color palette and the requested operation requires an 8-bit color palette."); 01977 break; 01978 case DDERR_NOTAOVERLAYSURFACE: 01979 strcpy(errDesc, "DDERR_NOTAOVERLAYSURFACE: An overlay component is called for a non-overlay surface."); 01980 break; 01981 case DDERR_NOTEXTUREHW: 01982 strcpy(errDesc, "DDERR_NOTEXTUREHW: The operation cannot be carried out because no texture-mapping hardware is present or available."); 01983 break; 01984 case DDERR_NOTFLIPPABLE: 01985 strcpy(errDesc, "DDERR_NOTFLIPPABLE: An attempt has been made to flip a surface that cannot be flipped."); 01986 break; 01987 case DDERR_NOTFOUND: 01988 strcpy(errDesc, "DDERR_NOTFOUND: The requested item was not found."); 01989 break; 01990 case DDERR_NOTINITIALIZED: 01991 strcpy(errDesc, "DDERR_NOTINITIALIZED: An attempt was made to call an interface method of a DirectDraw object created by CoCreateInstance before the object was initialized."); 01992 break; 01993 case DDERR_NOTLOADED: 01994 strcpy(errDesc, "DDERR_NOTLOADED: The surface is an optimized surface, but it has not yet been allocated any memory."); 01995 break; 01996 case DDERR_NOTLOCKED: 01997 strcpy(errDesc, "DDERR_NOTLOCKED: An attempt is made to unlock a surface that was not locked."); 01998 break; 01999 case DDERR_NOTPAGELOCKED: 02000 strcpy(errDesc, "DDERR_NOTPAGELOCKED: An attempt is made to page unlock a surface with no outstanding page locks."); 02001 break; 02002 case DDERR_NOTPALETTIZED: 02003 strcpy(errDesc, "DDERR_NOTPALETTIZED: The surface being used is not a palette-based surface."); 02004 break; 02005 case DDERR_NOVSYNCHW: 02006 strcpy(errDesc, "DDERR_NOVSYNCHW: The operation cannot be carried out because there is no hardware support for vertical blank synchronized operations."); 02007 break; 02008 case DDERR_NOZBUFFERHW: 02009 strcpy(errDesc, "DDERR_NOZBUFFERHW: The operation to create a z-buffer in display memory or to perform a blit using a z-buffer cannot be carried out because there is no hardware support for z-buffers."); 02010 break; 02011 case DDERR_NOZOVERLAYHW: 02012 strcpy(errDesc, "DDERR_NOZOVERLAYHW: The overlay surfaces cannot be z-layered based on the z-order because the hardware does not support z-ordering of overlays."); 02013 break; 02014 case DDERR_OUTOFCAPS: 02015 strcpy(errDesc, "DDERR_OUTOFCAPS: The hardware needed for the requested operation has already been allocated."); 02016 break; 02017 case DDERR_OUTOFMEMORY: 02018 strcpy(errDesc, "DDERR_OUTOFMEMORY: DirectDraw does not have enough memory to perform the operation."); 02019 break; 02020 case DDERR_OUTOFVIDEOMEMORY: 02021 strcpy(errDesc, "DDERR_OUTOFVIDEOMEMORY: DirectDraw does not have enough display memory to perform the operation."); 02022 break; 02023 case DDERR_OVERLAPPINGRECTS: 02024 strcpy(errDesc, "DDERR_OVERLAPPINGRECTS: Operation could not be carried out because the source and destination rectangles are on the same surface and overlap each other."); 02025 break; 02026 case DDERR_OVERLAYCANTCLIP: 02027 strcpy(errDesc, "DDERR_OVERLAYCANTCLIP: The hardware does not support clipped overlays."); 02028 break; 02029 case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: 02030 strcpy(errDesc, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE: An attempt was made to have more than one color key active on an overlay."); 02031 break; 02032 case DDERR_OVERLAYNOTVISIBLE: 02033 strcpy(errDesc, "DDERR_OVERLAYNOTVISIBLE: The IDirectDrawSurface7::GetOverlayPosition method is called on a hidden overlay."); 02034 break; 02035 case DDERR_PALETTEBUSY: 02036 strcpy(errDesc, "DDERR_PALETTEBUSY: Access to this palette is refused because the palette is locked by another thread."); 02037 break; 02038 case DDERR_PRIMARYSURFACEALREADYEXISTS: 02039 strcpy(errDesc, "DDERR_PRIMARYSURFACEALREADYEXISTS: This process has already created a primary surface."); 02040 break; 02041 case DDERR_REGIONTOOSMALL: 02042 strcpy(errDesc, "DDERR_REGIONTOOSMALL: The region passed to the IDirectDrawClipper::GetClipList method is too small."); 02043 break; 02044 case DDERR_SURFACEALREADYATTACHED: 02045 strcpy(errDesc, "DDERR_SURFACEALREADYATTACHED: An attempt was made to attach a surface to another surface to which it is already attached."); 02046 break; 02047 case DDERR_SURFACEALREADYDEPENDENT: 02048 strcpy(errDesc, "DDERR_SURFACEALREADYDEPENDENT: An attempt was made to make a surface a dependency of another surface to which it is already dependent."); 02049 break; 02050 case DDERR_SURFACEBUSY: 02051 strcpy(errDesc, "DDERR_SURFACEBUSY: Access to the surface is refused because the surface is locked by another thread."); 02052 break; 02053 case DDERR_SURFACEISOBSCURED: 02054 strcpy(errDesc, "DDERR_SURFACEISOBSCURED: Access to the surface is refused because the surface is obscured."); 02055 break; 02056 case DDERR_SURFACELOST: 02057 strcpy(errDesc, "DDERR_SURFACELOST: Access to the surface is refused because the surface memory is gone. Call the IDirectDrawSurface7::Restore method on this surface to restore the memory associated with it."); 02058 break; 02059 case DDERR_SURFACENOTATTACHED: 02060 strcpy(errDesc, "DDERR_SURFACENOTATTACHED: The requested surface is not attached."); 02061 break; 02062 case DDERR_TOOBIGHEIGHT: 02063 strcpy(errDesc, "DDERR_TOOBIGHEIGHT: The height requested by DirectDraw is too large."); 02064 break; 02065 case DDERR_TOOBIGSIZE: 02066 strcpy(errDesc, "DDERR_TOOBIGSIZE: The size requested by DirectDraw is too large. However, the individual height and width are valid sizes."); 02067 break; 02068 case DDERR_TOOBIGWIDTH: 02069 strcpy(errDesc, "DDERR_TOOBIGWIDTH: The width requested by DirectDraw is too large."); 02070 break; 02071 case DDERR_UNSUPPORTED: 02072 strcpy(errDesc, "DDERR_UNSUPPORTED: The operation is not supported."); 02073 break; 02074 case DDERR_UNSUPPORTEDFORMAT: 02075 strcpy(errDesc, "DDERR_UNSUPPORTEDFORMAT: The FourCC format requested is not supported by DirectDraw."); 02076 break; 02077 case DDERR_UNSUPPORTEDMASK: 02078 strcpy(errDesc, "DDERR_UNSUPPORTEDMASK: The bitmask in the pixel format requested is not supported by DirectDraw."); 02079 break; 02080 case DDERR_UNSUPPORTEDMODE: 02081 strcpy(errDesc, "DDERR_UNSUPPORTEDMODE: The display is currently in an unsupported mode."); 02082 break; 02083 case DDERR_VERTICALBLANKINPROGRESS: 02084 strcpy(errDesc, "DDERR_VERTICALBLANKINPROGRESS: A vertical blank is in progress."); 02085 break; 02086 case DDERR_VIDEONOTACTIVE: 02087 strcpy(errDesc, "DDERR_VIDEONOTACTIVE: The video port is not active."); 02088 break; 02089 case DDERR_WASSTILLDRAWING: 02090 strcpy(errDesc, "DDERR_WASSTILLDRAWING: The previous blit operation that is transferring information to or from this surface is incomplete."); 02091 break; 02092 case DDERR_WRONGMODE: 02093 strcpy(errDesc, "DDERR_WRONGMODE: This surface cannot be restored because it was created in a different mode."); 02094 break; 02095 case DDERR_XALIGN: 02096 strcpy(errDesc, "DDERR_XALIGN: The provided rectangle was not horizontally aligned on a required boundary."); 02097 break; 02098 default: 02099 strcpy(errDesc, "Unknown error code."); 02100 } 02101 } 02102 return errDesc; 02103 } 02104 02105 /* 02106 D3D_OK 02107 D3DERR_BADMAJORVERSION 02108 D3DERR_BADMINORVERSION 02109 D3DERR_COLORKEYATTACHED 02110 D3DERR_CONFLICTINGTEXTUREFILTER 02111 D3DERR_CONFLICTINGTEXTUREPALETTE 02112 D3DERR_CONFLICTINGRENDERSTATE 02113 D3DERR_DEVICEAGGREGATED (new for DirectX 5.0) 02114 D3DERR_EXECUTE_CLIPPED_FAILED 02115 D3DERR_EXECUTE_CREATE_FAILED 02116 D3DERR_EXECUTE_DESTROY_FAILED 02117 D3DERR_EXECUTE_FAILED 02118 D3DERR_EXECUTE_LOCK_FAILED 02119 D3DERR_EXECUTE_LOCKED 02120 D3DERR_EXECUTE_NOT_LOCKED 02121 D3DERR_EXECUTE_UNLOCK_FAILED 02122 D3DERR_INITFAILED (new for DirectX 5.0) 02123 D3DERR_INBEGIN (new for DirectX 5.0) 02124 D3DERR_INVALID_DEVICE (new for DirectX 5.0) 02125 D3DERR_INVALIDCURRENTVIEWPORT (new for DirectX 5.0) 02126 D3DERR_INVALIDMATRIX 02127 D3DERR_INVALIDPALETTE(new for DirectX 5.0) 02128 D3DERR_INVALIDPRIMITIVETYPE (new for DirectX 5.0) 02129 D3DERR_INVALIDRAMPTEXTURE (new for DirectX 5.0) 02130 D3DERR_INVALIDVERTEXFORMAT (new for DirectX 6.0) 02131 D3DERR_INVALIDVERTEXTYPE (new for DirectX 5.0) 02132 D3DERR_LIGHT_SET_FAILED 02133 D3DERR_LIGHTHASVIEWPORT (new for DirectX 5.0) 02134 D3DERR_LIGHTNOTINTHISVIEWPORT (new for DirectX 5.0) 02135 D3DERR_MATERIAL_CREATE_FAILED 02136 D3DERR_MATERIAL_DESTROY_FAILED 02137 D3DERR_MATERIAL_GETDATA_FAILED 02138 D3DERR_MATERIAL_SETDATA_FAILED 02139 D3DERR_MATRIX_CREATE_FAILED 02140 D3DERR_MATRIX_DESTROY_FAILED 02141 D3DERR_MATRIX_GETDATA_FAILED 02142 D3DERR_MATRIX_SETDATA_FAILED 02143 D3DERR_NOCURRENTVIEWPORT (new for DirectX 5.0) 02144 D3DERR_NOTINBEGIN (new for DirectX 5.0) 02145 D3DERR_NOVIEWPORTS (new for DirectX 5.0) 02146 D3DERR_SCENE_BEGIN_FAILED 02147 D3DERR_SCENE_END_FAILED 02148 D3DERR_SCENE_IN_SCENE 02149 D3DERR_SCENE_NOT_IN_SCENE 02150 D3DERR_SETVIEWPORTDATA_FAILED 02151 D3DERR_STENCILBUFFER_NOTPRESENT 02152 D3DERR_SURFACENOTINVIDMEM (new for DirectX 5.0) 02153 D3DERR_TEXTURE_BADSIZE (new for DirectX 5.0) 02154 D3DERR_TEXTURE_CREATE_FAILED 02155 D3DERR_TEXTURE_DESTROY_FAILED 02156 D3DERR_TEXTURE_GETSURF_FAILED 02157 D3DERR_TEXTURE_LOAD_FAILED 02158 D3DERR_TEXTURE_LOCK_FAILED 02159 D3DERR_TEXTURE_LOCKED 02160 D3DERR_TEXTURE_NO_SUPPORT 02161 D3DERR_TEXTURE_NOT_LOCKED 02162 D3DERR_TEXTURE_SWAP_FAILED 02163 D3DERR_TEXTURE_UNLOCK_FAILED 02164 D3DERR_TOOMANYOPERATIONS 02165 D3DERR_TOOMANYPRIMITIVES 02166 D3DERR_UNSUPPORTEDALPHAARG 02167 D3DERR_UNSUPPORTEDALPHAOPERATION 02168 D3DERR_UNSUPPORTEDCOLORARG 02169 D3DERR_UNSUPPORTEDCOLOROPERATION 02170 D3DERR_UNSUPPORTEDFACTORVALUE 02171 D3DERR_UNSUPPORTEDTEXTUREFILTER 02172 D3DERR_VBUF_CREATE_FAILED 02173 D3DERR_VERTEXBUFFERLOCKED 02174 D3DERR_VERTEXBUFFEROPTIMIZED 02175 D3DERR_VIEWPORTDATANOTSET (new for DirectX 5.0) 02176 D3DERR_VIEWPORTHASNODEVICE (new for DirectX 5.0) 02177 D3DERR_WRONGTEXTUREFORMAT 02178 D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY (new for DirectX 5.0) 02179 D3DERR_ZBUFF_NEEDS_VIDEOMEMORY (new for DirectX 5.0) 02180 D3DERR_ZBUFFER_NOTPRESENT 02181 */ 02182 02183 //----------------------------------------------------------------------- 02184 DDDriverList* D3DRenderSystem::getDirectDrawDrivers(void) 02185 { 02186 if (!mDriverList) 02187 { 02188 mDriverList = new DDDriverList; 02189 } 02190 02191 return mDriverList; 02192 } 02193 //----------------------------------------------------------------------- 02194 void D3DRenderSystem::setLightingEnabled(bool enabled) 02195 { 02196 // Call D3D 02197 HRESULT hr = __SetRenderState(D3DRENDERSTATE_LIGHTING, enabled); 02198 if (FAILED(hr)) 02199 Except(hr, "Error lighting status.", "D3DRenderSystem::setLightingEnabled"); 02200 } 02201 //----------------------------------------------------------------------- 02202 void D3DRenderSystem::_setFog(FogMode mode, const ColourValue& colour, Real density, Real start, Real end) 02203 { 02204 HRESULT hr; 02205 02206 D3DRENDERSTATETYPE fogType, fogTypeNot; 02207 02208 if (mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE) 02209 { 02210 fogType = D3DRENDERSTATE_FOGTABLEMODE; 02211 fogTypeNot = D3DRENDERSTATE_FOGVERTEXMODE; 02212 } 02213 else 02214 { 02215 fogType = D3DRENDERSTATE_FOGVERTEXMODE; 02216 fogTypeNot = D3DRENDERSTATE_FOGTABLEMODE; 02217 } 02218 02219 if( mode == FOG_NONE) 02220 { 02221 // just disable 02222 hr = __SetRenderState(fogType, D3DFOG_NONE ); 02223 hr = __SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE); 02224 } 02225 else 02226 { 02227 // Allow fog 02228 hr = __SetRenderState( D3DRENDERSTATE_FOGENABLE, TRUE ); 02229 hr = __SetRenderState( fogTypeNot, D3DFOG_NONE ); 02230 switch(mode) 02231 { 02232 case FOG_EXP: 02233 hr = __SetRenderState( fogType, D3DFOG_EXP); 02234 break; 02235 case FOG_EXP2: 02236 hr = __SetRenderState( fogType, D3DFOG_EXP2); 02237 break; 02238 case FOG_LINEAR: 02239 hr = __SetRenderState( fogType, D3DFOG_LINEAR); 02240 break; 02241 02242 } 02243 02244 hr = __SetRenderState( D3DRENDERSTATE_FOGCOLOR, colour.getAsLongARGB() ); 02245 hr = __SetRenderState( D3DRENDERSTATE_FOGSTART, *((LPDWORD)(&start)) ); 02246 hr = __SetRenderState( D3DRENDERSTATE_FOGEND, *((LPDWORD)(&end)) ); 02247 hr = __SetRenderState( D3DRENDERSTATE_FOGDENSITY, *((LPDWORD)(&density)) ); 02248 } 02249 02250 02251 } 02252 02253 //--------------------------------------------------------------------- 02254 void D3DRenderSystem::convertColourValue(const ColourValue& colour, unsigned long* pDest) 02255 { 02256 *pDest = colour.getAsLongARGB(); 02257 } 02258 //--------------------------------------------------------------------- 02259 void D3DRenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, 02260 Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram) 02261 { 02262 Radian theta(fovy * 0.5); 02263 Real h = 1 / Math::Tan(theta); 02264 Real w = h / aspect; 02265 Real q, qn; 02266 if (farPlane == 0) 02267 { 02268 q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; 02269 qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1); 02270 } 02271 else 02272 { 02273 q = farPlane / ( farPlane - nearPlane ); 02274 qn = -q * nearPlane; 02275 } 02276 02277 dest = Matrix4::ZERO; 02278 dest[0][0] = w; 02279 dest[1][1] = h; 02280 02281 if (forGpuProgram) 02282 { 02283 dest[2][2] = -q; 02284 dest[3][2] = -1.0f; 02285 } 02286 else 02287 { 02288 dest[2][2] = q; 02289 dest[3][2] = 1.0f; 02290 } 02291 02292 dest[2][3] = qn; 02293 02294 } 02295 //--------------------------------------------------------------------- 02296 void D3DRenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, 02297 Matrix4& dest, bool forGpuProgram ) 02298 { 02299 Radian thetaY (fovy / 2.0f); 02300 Real tanThetaY = Math::Tan(thetaY); 02301 02302 //Real thetaX = thetaY * aspect; 02303 Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX); 02304 Real half_w = tanThetaX * nearPlane; 02305 Real half_h = tanThetaY * nearPlane; 02306 Real iw = 1.0 / half_w; 02307 Real ih = 1.0 / half_h; 02308 Real q; 02309 if (farPlane == 0) 02310 { 02311 q = 0; 02312 } 02313 else 02314 { 02315 q = 1.0 / (farPlane - nearPlane); 02316 } 02317 02318 dest = Matrix4::ZERO; 02319 dest[0][0] = iw; 02320 dest[1][1] = ih; 02321 dest[2][2] = q; 02322 dest[2][3] = -nearPlane / (farPlane - nearPlane); 02323 dest[3][3] = 1; 02324 02325 if (forGpuProgram) 02326 { 02327 dest[2][2] = -dest[2][2]; 02328 } 02329 } 02330 //--------------------------------------------------------------------- 02331 void D3DRenderSystem::_setRasterisationMode(SceneDetailLevel level) 02332 { 02333 D3DFILLMODE d3dmode; 02334 02335 switch(level) 02336 { 02337 case SDL_POINTS: 02338 d3dmode = D3DFILL_POINT; 02339 break; 02340 case SDL_WIREFRAME: 02341 d3dmode = D3DFILL_WIREFRAME; 02342 break; 02343 case SDL_SOLID: 02344 d3dmode = D3DFILL_SOLID; 02345 break; 02346 02347 } 02348 02349 HRESULT hr = __SetRenderState(D3DRENDERSTATE_FILLMODE, d3dmode); 02350 if (FAILED(hr)) 02351 { 02352 Except(hr, "Error setting rasterisation mode.", 02353 "D3DRenderSystem::setRasterisationMode"); 02354 } 02355 02356 02357 } 02358 //--------------------------------------------------------------------- 02359 void D3DRenderSystem::setStencilCheckEnabled(bool enabled) 02360 { 02361 // Allow stencilling 02362 HRESULT hr = __SetRenderState(D3DRENDERSTATE_STENCILENABLE, enabled); 02363 if (FAILED(hr)) 02364 Except(hr, "Error enabling / disabling stencilling.", 02365 "D3DRenderSystem::setStencilCheckEnabled"); 02366 02367 } 02368 //--------------------------------------------------------------------- 02369 void D3DRenderSystem::setStencilBufferParams(CompareFunction func, ulong refValue, 02370 ulong mask, StencilOperation stencilFailOp, 02371 StencilOperation depthFailOp, StencilOperation passOp, 02372 bool twoSidedOperation) 02373 { 02374 HRESULT hr; 02375 02376 // D3D7 does not support 2-sided stencil operations 02377 if (twoSidedOperation) 02378 Except(Exception::ERR_INVALIDPARAMS, "Direct3D7 does not support 2-sided stencil ops", 02379 "D3DRenderSystem::setStencilBufferParams"); 02380 02381 // Function 02382 hr = __SetRenderState(D3DRENDERSTATE_STENCILFUNC, 02383 convertCompareFunction(func)); 02384 02385 if (FAILED(hr)) 02386 Except(hr, "Error setting stencil buffer test function.", 02387 "D3DRenderSystem::setStencilBufferParams"); 02388 02389 // reference value 02390 hr = __SetRenderState(D3DRENDERSTATE_STENCILREF, refValue); 02391 if (FAILED(hr)) 02392 Except(hr, "Error setting stencil buffer reference value.", 02393 "D3DRenderSystem::setStencilBufferParams"); 02394 02395 // mask 02396 hr = __SetRenderState(D3DRENDERSTATE_STENCILMASK, mask); 02397 if (FAILED(hr)) 02398 Except(hr, "Error setting stencil buffer mask.", 02399 "D3DRenderSystem::setStencilBufferParams"); 02400 02401 // fail op 02402 hr = __SetRenderState(D3DRENDERSTATE_STENCILFAIL, 02403 convertStencilOp(stencilFailOp)); 02404 if (FAILED(hr)) 02405 Except(hr, "Error setting stencil fail operation.", 02406 "D3DRenderSystem::setStencilBufferParams"); 02407 02408 // depth fail op 02409 hr = __SetRenderState(D3DRENDERSTATE_STENCILZFAIL, 02410 convertStencilOp(depthFailOp)); 02411 if (FAILED(hr)) 02412 Except(hr, "Error setting stencil depth fail operation.", 02413 "D3DRenderSystem::setStencilBufferParams"); 02414 02415 // pass op 02416 hr = __SetRenderState(D3DRENDERSTATE_STENCILPASS, 02417 convertStencilOp(passOp)); 02418 if (FAILED(hr)) 02419 Except(hr, "Error setting stencil pass operation.", 02420 "D3DRenderSystem::setStencilBufferParams"); 02421 } 02422 //--------------------------------------------------------------------- 02423 D3DCMPFUNC D3DRenderSystem::convertCompareFunction(CompareFunction func) 02424 { 02425 switch(func) 02426 { 02427 case CMPF_ALWAYS_FAIL: 02428 return D3DCMP_NEVER; 02429 case CMPF_ALWAYS_PASS: 02430 return D3DCMP_ALWAYS; 02431 case CMPF_LESS: 02432 return D3DCMP_LESS; 02433 case CMPF_LESS_EQUAL: 02434 return D3DCMP_LESSEQUAL; 02435 case CMPF_EQUAL: 02436 return D3DCMP_EQUAL; 02437 case CMPF_NOT_EQUAL: 02438 return D3DCMP_NOTEQUAL; 02439 case CMPF_GREATER_EQUAL: 02440 return D3DCMP_GREATEREQUAL; 02441 case CMPF_GREATER: 02442 return D3DCMP_GREATER; 02443 }; 02444 // to shut the compiler up 02445 return D3DCMP_ALWAYS; 02446 } 02447 //--------------------------------------------------------------------- 02448 D3DSTENCILOP D3DRenderSystem::convertStencilOp(StencilOperation op) 02449 { 02450 switch(op) 02451 { 02452 case SOP_KEEP: 02453 return D3DSTENCILOP_KEEP; 02454 case SOP_ZERO: 02455 return D3DSTENCILOP_ZERO; 02456 case SOP_REPLACE: 02457 return D3DSTENCILOP_REPLACE; 02458 case SOP_INCREMENT: 02459 return D3DSTENCILOP_INCRSAT; 02460 case SOP_DECREMENT: 02461 return D3DSTENCILOP_DECRSAT; 02462 case SOP_INCREMENT_WRAP: 02463 return D3DSTENCILOP_INCR; 02464 case SOP_DECREMENT_WRAP: 02465 return D3DSTENCILOP_DECR; 02466 case SOP_INVERT: 02467 return D3DSTENCILOP_INVERT; 02468 }; 02469 // To shut the compiler up 02470 return D3DSTENCILOP_KEEP; 02471 } 02472 02473 DWORD D3DRenderSystem::_getCurrentAnisotropy(size_t unit) 02474 { 02475 DWORD oldVal; 02476 mlpD3DDevice->GetTextureStageState(unit, D3DTSS_MAXANISOTROPY, &oldVal); 02477 return oldVal; 02478 } 02479 02480 02481 void D3DRenderSystem::_setTextureUnitFiltering(size_t unit, 02482 FilterType ftype, FilterOptions filter) 02483 { 02484 __SetTextureStageState(unit, _getFilterCode(ftype), _getFilter(ftype, filter)); 02485 } 02486 02487 void D3DRenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) 02488 { 02489 if ((DWORD)maxAnisotropy > mD3DDeviceDesc.dwMaxAnisotropy) 02490 maxAnisotropy = mD3DDeviceDesc.dwMaxAnisotropy; 02491 02492 if (_getCurrentAnisotropy(unit) != maxAnisotropy) 02493 __SetTextureStageState( unit, D3DTSS_MAXANISOTROPY, maxAnisotropy ); 02494 } 02495 02496 void D3DRenderSystem::setVertexDeclaration(VertexDeclaration* decl) 02497 { 02498 // TODO 02499 } 02500 02501 void D3DRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding) 02502 { 02503 // TODO 02504 } 02505 //----------------------------------------------------------------------- 02506 D3DTEXTURESTAGESTATETYPE D3DRenderSystem::_getFilterCode(FilterType ft) const 02507 { 02508 switch (ft) 02509 { 02510 case FT_MIN: 02511 return D3DTSS_MINFILTER; 02512 break; 02513 case FT_MAG: 02514 return D3DTSS_MAGFILTER; 02515 break; 02516 case FT_MIP: 02517 return D3DTSS_MIPFILTER; 02518 break; 02519 } 02520 02521 // to keep compiler happy 02522 return D3DTSS_MINFILTER; 02523 } 02524 //----------------------------------------------------------------------- 02525 DWORD D3DRenderSystem::_getFilter(FilterType ft, FilterOptions fo) const 02526 { 02527 switch (ft) 02528 { 02529 case FT_MIN: 02530 switch( fo ) 02531 { 02532 // NOTE: Fall through if device doesn't support requested type 02533 case FO_ANISOTROPIC: 02534 if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC ) 02535 { 02536 return D3DTFN_ANISOTROPIC; 02537 break; 02538 } 02539 case FO_LINEAR: 02540 if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR ) 02541 { 02542 return D3DTFN_LINEAR; 02543 break; 02544 } 02545 case FO_POINT: 02546 case TFO_NONE: 02547 return D3DTFN_POINT; 02548 break; 02549 } 02550 break; 02551 case FT_MAG: 02552 switch( fo ) 02553 { 02554 // NOTE: Fall through if device doesn't support requested type 02555 case FO_ANISOTROPIC: 02556 if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC ) 02557 { 02558 return D3DTFG_ANISOTROPIC; 02559 break; 02560 } 02561 case FO_LINEAR: 02562 if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR ) 02563 { 02564 return D3DTFG_LINEAR; 02565 break; 02566 } 02567 case FO_POINT: 02568 case FO_NONE: 02569 return D3DTFG_POINT; 02570 break; 02571 } 02572 break; 02573 case FT_MIP: 02574 switch( fo ) 02575 { 02576 case FO_ANISOTROPIC: 02577 case FO_LINEAR: 02578 if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR ) 02579 { 02580 return D3DTFP_LINEAR; 02581 break; 02582 } 02583 case FO_POINT: 02584 if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR ) 02585 { 02586 return D3DTFP_POINT; 02587 break; 02588 } 02589 case TFO_NONE: 02590 return D3DTFP_NONE; 02591 break; 02592 } 02593 break; 02594 } 02595 02596 // should never get here 02597 return 0; 02598 } 02599 //--------------------------------------------------------------------- 02600 void D3DRenderSystem::setNormaliseNormals(bool normalise) 02601 { 02602 __SetRenderState(D3DRENDERSTATE_NORMALIZENORMALS, 02603 normalise ? TRUE : FALSE); 02604 } 02605 //--------------------------------------------------------------------- 02606 HRESULT D3DRenderSystem::__SetRenderState(D3DRENDERSTATETYPE state, DWORD value) 02607 { 02608 HRESULT hr; 02609 DWORD oldVal; 02610 02611 if ( FAILED( hr = mlpD3DDevice->GetRenderState(state, &oldVal) ) ) 02612 return hr; 02613 if ( oldVal == value ) 02614 return D3D_OK; 02615 else 02616 return mlpD3DDevice->SetRenderState(state, value); 02617 } 02618 //--------------------------------------------------------------------- 02619 HRESULT D3DRenderSystem::__SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value) 02620 { 02621 HRESULT hr; 02622 DWORD oldVal; 02623 02624 if ( FAILED( hr = mlpD3DDevice->GetTextureStageState(stage, type, &oldVal) ) ) 02625 return hr; 02626 if ( oldVal == value ) 02627 return D3D_OK; 02628 else 02629 return mlpD3DDevice->SetTextureStageState(stage, type, value); 02630 } 02631 02632 //--------------------------------------------------------------------- 02633 void D3DRenderSystem::clearFrameBuffer(unsigned int buffers, 02634 const ColourValue& colour, Real depth, unsigned short stencil) 02635 { 02636 DWORD flags = 0; 02637 if (buffers & FBT_COLOUR) 02638 { 02639 flags |= D3DCLEAR_TARGET; 02640 } 02641 if (buffers & FBT_DEPTH) 02642 { 02643 flags |= D3DCLEAR_ZBUFFER; 02644 } 02645 // Only try to clear the stencil if supported, otherwise it will fail 02646 if (buffers & FBT_STENCIL && mCapabilities->hasCapability(RSC_HWSTENCIL)) 02647 { 02648 flags |= D3DCLEAR_STENCIL; 02649 } 02650 HRESULT hr; 02651 if( FAILED( hr = mlpD3DDevice->Clear( 02652 0, 02653 NULL, 02654 flags, 02655 colour.getAsLongARGB(), 02656 depth, 02657 stencil ) ) ) 02658 { 02659 String msg = getErrorDescription(hr); 02660 Except( hr, "Error clearing frame buffer : " 02661 + msg, "D3DRenderSystem::clearFrameBuffer" ); 02662 } 02663 } 02664 //--------------------------------------------------------------------- 02665 void D3DRenderSystem::_makeProjectionMatrix(Real left, Real right, 02666 Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, 02667 bool forGpuProgram) 02668 { 02669 Real width = right - left; 02670 Real height = top - bottom; 02671 Real q, qn; 02672 if (farPlane == 0) 02673 { 02674 q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; 02675 qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1); 02676 } 02677 else 02678 { 02679 q = farPlane / ( farPlane - nearPlane ); 02680 qn = -q * nearPlane; 02681 } 02682 dest = Matrix4::ZERO; 02683 dest[0][0] = 2 * nearPlane / width; 02684 dest[0][2] = (right+left) / width; 02685 dest[1][1] = 2 * nearPlane / height; 02686 dest[1][2] = (top+bottom) / height; 02687 if (forGpuProgram) 02688 { 02689 dest[2][2] = -q; 02690 dest[3][2] = -1.0f; 02691 } 02692 else 02693 { 02694 dest[2][2] = q; 02695 dest[3][2] = 1.0f; 02696 } 02697 dest[2][3] = qn; 02698 } 02699 02700 //--------------------------------------------------------------------- 02701 void D3DRenderSystem::setClipPlanes(const PlaneList& clipPlanes) 02702 { 02703 size_t i; 02704 size_t numClipPlanes; 02705 D3DVALUE dx7ClipPlane[4]; 02706 DWORD mask = 0; 02707 HRESULT hr; 02708 numClipPlanes = clipPlanes.size(); 02709 02710 for (i = 0; i < numClipPlanes; ++i) 02711 { 02712 const Plane& plane = clipPlanes[i]; 02713 02714 dx7ClipPlane[0] = plane.normal.x; 02715 dx7ClipPlane[1] = plane.normal.y; 02716 dx7ClipPlane[2] = plane.normal.z; 02717 dx7ClipPlane[3] = -plane.d; 02718 02719 hr = mlpD3DDevice->SetClipPlane(i, dx7ClipPlane); 02720 if (FAILED(hr)) 02721 { 02722 Except(hr, "Unable to set clip plane", 02723 "D3D7RenderSystem::setClipPlanes"); 02724 } 02725 02726 mask |= (1 << i); 02727 } 02728 02729 hr = mlpD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE, mask); 02730 if (FAILED(hr)) 02731 { 02732 Except(hr, "Unable to set render state for clip planes", 02733 "D3D7RenderSystem::setClipPlanes"); 02734 } 02735 } 02736 02737 // ------------------------------------------------------------------ 02738 void D3DRenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D) 02739 { 02740 float plane[4] = { A, B, C, D }; 02741 mlpD3DDevice->SetClipPlane (index, plane); 02742 } 02743 02744 // ------------------------------------------------------------------ 02745 void D3DRenderSystem::enableClipPlane (ushort index, bool enable) 02746 { 02747 DWORD prev; 02748 mlpD3DDevice->GetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE, &prev); 02749 __SetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE, prev | (1 << index)); 02750 } 02751 //--------------------------------------------------------------------- 02752 HardwareOcclusionQuery* D3DRenderSystem::createHardwareOcclusionQuery(void) 02753 { 02754 return (HardwareOcclusionQuery*) 0; // Hardware occlusion is not supported when DirectX7 is used 02755 } 02756 //----------------------------------------------------------------------- 02757 void D3DRenderSystem::_setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) 02758 { 02759 // D3D7 does not have a colour write mask setting, so emulate it using 02760 // scene blending, on the assumption that setSceneBlend will be called 02761 // before this 02762 if (red || green || blue || alpha) 02763 { 02764 // restore saved scene blend 02765 _setSceneBlending(mSavedSrcFactor, mSavedDestFactor); 02766 } 02767 else 02768 { 02769 _setSceneBlending(SBF_ZERO, SBF_ONE); 02770 } 02771 } 02772 //--------------------------------------------------------------------- 02773 Real D3DRenderSystem::getHorizontalTexelOffset(void) 02774 { 02775 // D3D considers the origin to be in the center of a pixel 02776 return -0.5f; 02777 } 02778 //--------------------------------------------------------------------- 02779 Real D3DRenderSystem::getVerticalTexelOffset(void) 02780 { 02781 // D3D considers the origin to be in the center of a pixel 02782 return -0.5f; 02783 } 02784 //--------------------------------------------------------------------- 02785 void D3DRenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, 02786 const Plane& plane, bool forGpuProgram) 02787 { 02788 // Thanks to Eric Lenyel for posting this calculation at www.terathon.com 02789 02790 // Calculate the clip-space corner point opposite the clipping plane 02791 // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and 02792 // transform it into camera space by multiplying it 02793 // by the inverse of the projection matrix 02794 02795 /* generalised version 02796 Vector4 q = matrix.inverse() * 02797 Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f); 02798 */ 02799 Vector4 q; 02800 q.x = Math::Sign(plane.normal.x) / matrix[0][0]; 02801 q.y = Math::Sign(plane.normal.y) / matrix[1][1]; 02802 q.z = 1.0F; 02803 // flip the next bit from Lengyel since we're right-handed 02804 //q.w = (1.0F - matrix[2][2]) / matrix[2][3]; 02805 q.w = (1.0F + matrix[2][2]) / matrix[2][3]; 02806 02807 // Calculate the scaled plane vector 02808 Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d); 02809 Vector4 c = clipPlane4d * (1.0F / (clipPlane4d.dotProduct(q))); 02810 02811 // Replace the third row of the projection matrix 02812 matrix[2][0] = c.x; 02813 matrix[2][1] = c.y; 02814 // flip the next bit from Lengyel since we're right-handed 02815 //matrix[2][2] = c.z; 02816 matrix[2][2] = -c.z; 02817 matrix[2][3] = c.w; 02818 02819 } 02820 //--------------------------------------------------------------------- 02821 Real D3DRenderSystem::getMinimumDepthInputValue(void) 02822 { 02823 // Range [0.0f, 1.0f] 02824 return 0.0f; 02825 } 02826 //--------------------------------------------------------------------- 02827 Real D3DRenderSystem::getMaximumDepthInputValue(void) 02828 { 02829 // Range [0.0f, 1.0f] 02830 // D3D inverts even identity view matrices, so maximum INPUT is -1.0 02831 return -1.0f; 02832 } 02833 02834 02835 }
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:19 2004