[657] | 1 | /*
|
---|
| 2 | -----------------------------------------------------------------------------
|
---|
| 3 | This source file is part of OGRE
|
---|
| 4 | (Object-oriented Graphics Rendering Engine)
|
---|
| 5 | For the latest info, see http://ogre.sourceforge.net/
|
---|
| 6 |
|
---|
| 7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
| 8 | Also see acknowledgements in Readme.html
|
---|
| 9 |
|
---|
| 10 | This program is free software; you can redistribute it and/or modify it under
|
---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
| 13 | version.
|
---|
| 14 |
|
---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
| 18 |
|
---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
| 22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
| 23 | -----------------------------------------------------------------------------
|
---|
| 24 | */
|
---|
| 25 | #include <malloc.h>
|
---|
| 26 | #include "OgreD3D7RenderSystem.h"
|
---|
| 27 | #include "OgreDDDriver.h"
|
---|
| 28 | #include "OgreD3D7Device.h"
|
---|
| 29 | #include "OgreD3D7DeviceList.h"
|
---|
| 30 | #include "OgreDDDriverList.h"
|
---|
| 31 | #include "OgreDDVideoModeList.h"
|
---|
| 32 | #include "OgreDDVideoMode.h"
|
---|
| 33 | #include "OgreRenderWindow.h"
|
---|
| 34 | #include "OgreLogManager.h"
|
---|
| 35 | #include "OgreRenderSystem.h"
|
---|
| 36 | #include "OgreException.h"
|
---|
| 37 | #include "OgreSceneManager.h"
|
---|
| 38 | #include "OgreD3D7TextureManager.h"
|
---|
| 39 | #include "OgreViewport.h"
|
---|
| 40 | #include "OgreLight.h"
|
---|
| 41 | #include "OgreMatrix4.h"
|
---|
| 42 | #include "OgreMath.h"
|
---|
| 43 | #include "OgreD3D7RenderWindow.h"
|
---|
| 44 | #include "OgreFrustum.h"
|
---|
| 45 | #include "OgreD3D7GpuProgramManager.h"
|
---|
| 46 | #include "OgreStringConverter.h"
|
---|
| 47 |
|
---|
| 48 | namespace Ogre {
|
---|
| 49 | const Matrix4 PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE(
|
---|
| 50 | 0.5, 0, 0, -0.5,
|
---|
| 51 | 0, -0.5, 0, -0.5,
|
---|
| 52 | 0, 0, 0, -1,
|
---|
| 53 | 0, 0, 0, 1);
|
---|
| 54 |
|
---|
| 55 | const Matrix4 PROJECTIONCLIPSPACE2DTOIMAGESPACE_ORTHO(
|
---|
| 56 | -0.5, 0, 0, -0.5,
|
---|
| 57 | 0, 0.5, 0, -0.5,
|
---|
| 58 | 0, 0, 0, -1,
|
---|
| 59 | 0, 0, 0, 1);
|
---|
| 60 |
|
---|
| 61 | //-----------------------------------------------------------------------
|
---|
| 62 | D3DRenderSystem::D3DRenderSystem(HINSTANCE hInstance)
|
---|
| 63 | {
|
---|
| 64 | OgreGuard( "D3DRenderSystem::D3DRenderSystem" );
|
---|
| 65 |
|
---|
| 66 | LogManager::getSingleton().logMessage(getName() + " created.");
|
---|
| 67 |
|
---|
| 68 | mlpD3DDevice = NULL;
|
---|
| 69 | // Reset driver list
|
---|
| 70 | mDriverList = NULL;
|
---|
| 71 | mActiveDDDriver = NULL;
|
---|
| 72 | mhInstance = hInstance;
|
---|
| 73 | mHardwareBufferManager = NULL;
|
---|
| 74 | mGpuProgramManager = NULL;
|
---|
| 75 | mDeviceLost = false;
|
---|
| 76 |
|
---|
| 77 | initConfigOptions();
|
---|
| 78 |
|
---|
| 79 | // Initialise D3DX library
|
---|
| 80 | D3DXInitialize();
|
---|
| 81 |
|
---|
| 82 | // set stages desc. to defaults
|
---|
| 83 | for (int n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++)
|
---|
| 84 | {
|
---|
| 85 | mTexStageDesc[n].autoTexCoordType = TEXCALC_NONE;
|
---|
| 86 | mTexStageDesc[n].coordIndex = 0;
|
---|
| 87 | mTexStageDesc[n].texType = D3D_TEX_TYPE_NORMAL;
|
---|
| 88 | mTexStageDesc[n].pTex = NULL;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | mCurrentLights = 0;
|
---|
| 92 |
|
---|
| 93 | mEventNames.push_back("DeviceLost");
|
---|
| 94 | mEventNames.push_back("DeviceRestored");
|
---|
| 95 |
|
---|
| 96 | OgreUnguard();
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | //-----------------------------------------------------------------------
|
---|
| 100 | D3DRenderSystem::~D3DRenderSystem()
|
---|
| 101 | {
|
---|
| 102 | OgreGuard( "D3DRenderSystem::~D3DRenderSystem" );
|
---|
| 103 | shutdown();
|
---|
| 104 |
|
---|
| 105 | SAFE_DELETE(mTextureManager);
|
---|
| 106 | SAFE_DELETE(mDriverList);
|
---|
| 107 | SAFE_DELETE(mHardwareBufferManager);
|
---|
| 108 | SAFE_DELETE(mGpuProgramManager);
|
---|
| 109 |
|
---|
| 110 | D3DXUninitialize();
|
---|
| 111 | LogManager::getSingleton().logMessage(getName() + " destroyed.");
|
---|
| 112 |
|
---|
| 113 | OgreUnguard();
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | //-----------------------------------------------------------------------
|
---|
| 117 | const String& D3DRenderSystem::getName(void) const
|
---|
| 118 | {
|
---|
| 119 | static String strName("Direct3D7 Rendering Subsystem");
|
---|
| 120 | return strName;
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | //-----------------------------------------------------------------------
|
---|
| 124 | void D3DRenderSystem::initConfigOptions(void)
|
---|
| 125 | {
|
---|
| 126 | OgreGuard( "D3DRenderSystem::initConfigOptions" );
|
---|
| 127 |
|
---|
| 128 | DDDriverList* ddList;
|
---|
| 129 | DDDriver* dd;
|
---|
| 130 |
|
---|
| 131 | ConfigOption optDevice;
|
---|
| 132 | ConfigOption optVideoMode;
|
---|
| 133 | ConfigOption optFullScreen;
|
---|
| 134 | ConfigOption optVSync;
|
---|
| 135 |
|
---|
| 136 | ddList = this->getDirectDrawDrivers();
|
---|
| 137 |
|
---|
| 138 | // Create option for devices
|
---|
| 139 | optDevice.name = "Rendering Device";
|
---|
| 140 | optDevice.currentValue = "";
|
---|
| 141 | optDevice.possibleValues.clear();
|
---|
| 142 | optDevice.immutable = false;
|
---|
| 143 |
|
---|
| 144 | // Option for video modes
|
---|
| 145 | optVideoMode.name = "Video Mode";
|
---|
| 146 | optVideoMode.currentValue = "";
|
---|
| 147 | optVideoMode.immutable = false;
|
---|
| 148 |
|
---|
| 149 | // Option for full screen
|
---|
| 150 | optFullScreen.name = "Full Screen";
|
---|
| 151 | optFullScreen.possibleValues.push_back("Yes");
|
---|
| 152 | optFullScreen.possibleValues.push_back("No");
|
---|
| 153 | optFullScreen.currentValue = "Yes";
|
---|
| 154 |
|
---|
| 155 |
|
---|
| 156 | unsigned k = ddList->count();
|
---|
| 157 | // First, get DirectDraw driver options
|
---|
| 158 | for( unsigned j = 0; j < ddList->count(); j++ )
|
---|
| 159 | {
|
---|
| 160 | dd = ddList->item(j);
|
---|
| 161 | // Add to device option list
|
---|
| 162 | optDevice.possibleValues.push_back( dd->DriverDescription() );
|
---|
| 163 |
|
---|
| 164 | // Make first one default
|
---|
| 165 | if( j==0 )
|
---|
| 166 | {
|
---|
| 167 | optDevice.currentValue = dd->DriverDescription();
|
---|
| 168 |
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 |
|
---|
| 172 | }
|
---|
| 173 |
|
---|
| 174 | // VSync option
|
---|
| 175 | optVSync.name = "VSync";
|
---|
| 176 | optVSync.immutable = false;
|
---|
| 177 | optVSync.possibleValues.push_back("Yes");
|
---|
| 178 | optVSync.possibleValues.push_back("No");
|
---|
| 179 | optVSync.currentValue = "Yes";
|
---|
| 180 |
|
---|
| 181 |
|
---|
| 182 | mOptions[optDevice.name] = optDevice;
|
---|
| 183 | mOptions[optVideoMode.name] = optVideoMode;
|
---|
| 184 | mOptions[optFullScreen.name] = optFullScreen;
|
---|
| 185 | mOptions[optVSync.name] = optVSync;
|
---|
| 186 |
|
---|
| 187 | // Set default-based settings
|
---|
| 188 | refreshDDSettings();
|
---|
| 189 |
|
---|
| 190 | OgreUnguard();
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 | //-----------------------------------------------------------------------
|
---|
| 194 | void D3DRenderSystem::refreshDDSettings(void)
|
---|
| 195 | {
|
---|
| 196 | OgreGuard( "D3DRenderSystem::refreshDDSettings" );
|
---|
| 197 |
|
---|
| 198 | DDVideoMode* vid;
|
---|
| 199 | ConfigOption* optVideoMode;
|
---|
| 200 | ConfigOption* optFullScreen;
|
---|
| 201 | DDDriver* dd;
|
---|
| 202 |
|
---|
| 203 | // Stuffs DD-Driver specific settings
|
---|
| 204 |
|
---|
| 205 | // Find DD Driver selected in options
|
---|
| 206 | ConfigOptionMap::iterator opt = mOptions.find("Rendering Device");
|
---|
| 207 |
|
---|
| 208 | if( opt != mOptions.end() )
|
---|
| 209 | {
|
---|
| 210 | for( unsigned j = 0; j < getDirectDrawDrivers()->count(); j++ )
|
---|
| 211 | {
|
---|
| 212 | dd = getDirectDrawDrivers()->item(j);
|
---|
| 213 | if( dd->DriverDescription() == opt->second.currentValue )
|
---|
| 214 | break;
|
---|
| 215 | }
|
---|
| 216 |
|
---|
| 217 | // Get fullScreen and Video mode options
|
---|
| 218 | opt = mOptions.find("Video Mode");
|
---|
| 219 | optVideoMode = &opt->second;
|
---|
| 220 | opt = mOptions.find("Full Screen");
|
---|
| 221 | optFullScreen = &opt->second;
|
---|
| 222 |
|
---|
| 223 | // Full screen forced?
|
---|
| 224 | if (!(dd->CanRenderWindowed()))
|
---|
| 225 | {
|
---|
| 226 | setConfigOption("Full Screen", "Yes");
|
---|
| 227 | optFullScreen->immutable = true;
|
---|
| 228 | }
|
---|
| 229 | else
|
---|
| 230 | optFullScreen->immutable = false;
|
---|
| 231 |
|
---|
| 232 | // Get video modes for this device
|
---|
| 233 | optVideoMode->possibleValues.clear();
|
---|
| 234 |
|
---|
| 235 | for( unsigned k = 0; k<dd->getVideoModeList()->count(); k++ )
|
---|
| 236 | {
|
---|
| 237 | vid = dd->getVideoModeList()->item(k);
|
---|
| 238 | optVideoMode->possibleValues.push_back(vid->Description());
|
---|
| 239 | }
|
---|
| 240 | }
|
---|
| 241 |
|
---|
| 242 | OgreUnguard();
|
---|
| 243 | }
|
---|
| 244 |
|
---|
| 245 |
|
---|
| 246 | //-----------------------------------------------------------------------
|
---|
| 247 | ConfigOptionMap& D3DRenderSystem::getConfigOptions(void)
|
---|
| 248 | {
|
---|
| 249 | // Return a COPY of the current config options
|
---|
| 250 | return mOptions;
|
---|
| 251 |
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | //-----------------------------------------------------------------------
|
---|
| 255 | void D3DRenderSystem::setConfigOption(const String &name, const String &value)
|
---|
| 256 | {
|
---|
| 257 | OgreGuard( "D3DRenderSystem::setConfigOption" );
|
---|
| 258 |
|
---|
| 259 | StringUtil::StrStreamType str;
|
---|
| 260 | str << "RenderSystem Option: " << name << " = " << value;
|
---|
| 261 | LogManager::getSingleton().logMessage(str.str());
|
---|
| 262 |
|
---|
| 263 | // Find option
|
---|
| 264 | ConfigOptionMap::iterator it = mOptions.find(name);
|
---|
| 265 |
|
---|
| 266 | // Update
|
---|
| 267 | if( it != mOptions.end())
|
---|
| 268 | it->second.currentValue = value;
|
---|
| 269 | else
|
---|
| 270 | {
|
---|
| 271 | str.clear();
|
---|
| 272 | str << "Option named " << name << " does not exist.";
|
---|
| 273 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
|
---|
| 274 | str.str(), "D3DRenderSystem::setConfigOption");
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 | // Refresh other options if DD Driver changed
|
---|
| 278 | if (name == "Rendering Device")
|
---|
| 279 | refreshDDSettings();
|
---|
| 280 |
|
---|
| 281 | if (name == "Full Screen")
|
---|
| 282 | {
|
---|
| 283 | if (value == "No")
|
---|
| 284 | {
|
---|
| 285 | // Video mode is not applicable
|
---|
| 286 | it = mOptions.find("Video Mode");
|
---|
| 287 | it->second.currentValue = "N/A";
|
---|
| 288 | it->second.immutable = true;
|
---|
| 289 | }
|
---|
| 290 | else
|
---|
| 291 | {
|
---|
| 292 | // Video mode is applicable
|
---|
| 293 | it = mOptions.find("Video Mode");
|
---|
| 294 | // default to 640 x 480 x 16
|
---|
| 295 | it->second.currentValue = "640 x 480 @ 16-bit colour";
|
---|
| 296 | it->second.immutable = false;
|
---|
| 297 | }
|
---|
| 298 | }
|
---|
| 299 | if( name == "VSync" )
|
---|
| 300 | {
|
---|
| 301 | if (value == "Yes")
|
---|
| 302 | mVSync = true;
|
---|
| 303 | else
|
---|
| 304 | mVSync = false;
|
---|
| 305 | }
|
---|
| 306 |
|
---|
| 307 | OgreUnguard();
|
---|
| 308 | }
|
---|
| 309 | //-----------------------------------------------------------------------
|
---|
| 310 | String D3DRenderSystem::validateConfigOptions(void)
|
---|
| 311 | {
|
---|
| 312 | // Check video mode specified in full screen mode
|
---|
| 313 | ConfigOptionMap::iterator o = mOptions.find("Full Screen");
|
---|
| 314 | if (o->second.currentValue == "Yes")
|
---|
| 315 | {
|
---|
| 316 | // Check video mode
|
---|
| 317 | o = mOptions.find("Video Mode");
|
---|
| 318 | if (o->second.currentValue == "")
|
---|
| 319 | {
|
---|
| 320 | return "A video mode must be selected for running in full-screen mode.";
|
---|
| 321 | }
|
---|
| 322 | }
|
---|
| 323 |
|
---|
| 324 | o = mOptions.find( "Rendering Device" );
|
---|
| 325 | bool foundDriver = false;
|
---|
| 326 | DDDriverList* driverList = getDirectDrawDrivers();
|
---|
| 327 | for( ushort j=0; j < driverList->count(); j++ )
|
---|
| 328 | {
|
---|
| 329 | if( driverList->item(j)->DriverDescription() == o->second.currentValue )
|
---|
| 330 | {
|
---|
| 331 | foundDriver = true;
|
---|
| 332 | break;
|
---|
| 333 | }
|
---|
| 334 | }
|
---|
| 335 | if (!foundDriver)
|
---|
| 336 | {
|
---|
| 337 | // Just pick the first driver
|
---|
| 338 | setConfigOption("Rendering Device", driverList->item(0)->DriverDescription());
|
---|
| 339 | return "Your DirectX driver name has changed since the last time you ran OGRE; "
|
---|
| 340 | "the 'Rendering Device' has been changed.";
|
---|
| 341 | }
|
---|
| 342 | return "";
|
---|
| 343 |
|
---|
| 344 | }
|
---|
| 345 | //-----------------------------------------------------------------------
|
---|
| 346 | RenderWindow* D3DRenderSystem::initialise(bool autoCreateWindow, const String& windowTitle)
|
---|
| 347 | {
|
---|
| 348 | RenderWindow* autoWindow = 0;
|
---|
| 349 |
|
---|
| 350 |
|
---|
| 351 | LogManager::getSingleton().logMessage(
|
---|
| 352 | "***************************************\n"
|
---|
| 353 | "*** Direct3D Subsystem Initialising ***\n"
|
---|
| 354 | "***************************************" );
|
---|
| 355 |
|
---|
| 356 | // ---------------------------
|
---|
| 357 | // Init using current settings
|
---|
| 358 | // ---------------------------
|
---|
| 359 |
|
---|
| 360 | // DirectDraw driver
|
---|
| 361 | mActiveDDDriver = 0;
|
---|
| 362 | ConfigOptionMap::iterator opt = mOptions.find("Rendering Device");
|
---|
| 363 | for( unsigned j = 0; j<getDirectDrawDrivers()->count(); j++ )
|
---|
| 364 | {
|
---|
| 365 | if (getDirectDrawDrivers()->item(j)->DriverDescription() == opt->second.currentValue)
|
---|
| 366 | {
|
---|
| 367 | mActiveDDDriver = getDirectDrawDrivers()->item(j);
|
---|
| 368 | break;
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 |
|
---|
| 372 | if (!mActiveDDDriver)
|
---|
| 373 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Problems finding requested DirectDraw driver!",
|
---|
| 374 | "D3DRenderSystem::initialise");
|
---|
| 375 |
|
---|
| 376 |
|
---|
| 377 | // Sort out the creation of a new window if required
|
---|
| 378 | if (autoCreateWindow)
|
---|
| 379 | {
|
---|
| 380 | // Full screen?
|
---|
| 381 | bool fullScreen;
|
---|
| 382 | opt = mOptions.find("Full Screen");
|
---|
| 383 | if( opt == mOptions.end() )
|
---|
| 384 | OGRE_EXCEPT(999, "Can't find full screen option!",
|
---|
| 385 | "D3DRenderSystem::initialise");
|
---|
| 386 | if (opt->second.currentValue == "Yes")
|
---|
| 387 | fullScreen = true;
|
---|
| 388 | else
|
---|
| 389 | fullScreen = false;
|
---|
| 390 |
|
---|
| 391 | // Get video mode
|
---|
| 392 | DDVideoMode* vid;
|
---|
| 393 | unsigned int height, width, colourDepth;
|
---|
| 394 |
|
---|
| 395 | vid = 0;
|
---|
| 396 | String temp;
|
---|
| 397 | if (fullScreen)
|
---|
| 398 | {
|
---|
| 399 | opt = mOptions.find("Video Mode");
|
---|
| 400 |
|
---|
| 401 | for( unsigned j=0; j<mActiveDDDriver->getVideoModeList()->count(); j++ )
|
---|
| 402 | {
|
---|
| 403 | temp = mActiveDDDriver->getVideoModeList()->item(j)->Description();
|
---|
| 404 | if (temp == opt->second.currentValue)
|
---|
| 405 | {
|
---|
| 406 | vid = mActiveDDDriver->getVideoModeList()->item(j);
|
---|
| 407 | break;
|
---|
| 408 | }
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | if (!vid)
|
---|
| 412 | OGRE_EXCEPT(9999, "Can't find requested video mode.",
|
---|
| 413 | "D3DRenderSystem::initilise");
|
---|
| 414 | width = vid->mWidth;
|
---|
| 415 | height = vid->mHeight;
|
---|
| 416 | colourDepth = vid->mColourDepth;
|
---|
| 417 |
|
---|
| 418 | }
|
---|
| 419 | else
|
---|
| 420 | {
|
---|
| 421 | // Notional height / width
|
---|
| 422 | width = 800;
|
---|
| 423 | height = 600;
|
---|
| 424 | colourDepth = 0; // colour depth based on desktop
|
---|
| 425 | }
|
---|
| 426 |
|
---|
| 427 | // Create myself a window
|
---|
| 428 | NameValuePairList params;
|
---|
| 429 | params["colourDepth"] = StringConverter::toString(colourDepth);
|
---|
| 430 | params["vsync"] = StringConverter::toString(mVSync);
|
---|
| 431 | autoWindow = this->createRenderWindow(windowTitle, width, height, fullScreen, ¶ms);
|
---|
| 432 |
|
---|
| 433 | // If we have 16bit depth buffer enable w-buffering.
|
---|
| 434 | assert( autoWindow );
|
---|
| 435 | if ( autoWindow->getColourDepth() == 16 )
|
---|
| 436 | {
|
---|
| 437 | mWBuffer = true;
|
---|
| 438 | }
|
---|
| 439 | else
|
---|
| 440 | {
|
---|
| 441 | mWBuffer = false;
|
---|
| 442 | }
|
---|
| 443 |
|
---|
| 444 | }
|
---|
| 445 |
|
---|
| 446 | opt = mOptions.find("VSync");
|
---|
| 447 | if (opt!=mOptions.end())
|
---|
| 448 | {
|
---|
| 449 | if (opt->second.currentValue == "Yes")
|
---|
| 450 | {
|
---|
| 451 | setWaitForVerticalBlank(true);
|
---|
| 452 | }
|
---|
| 453 | else
|
---|
| 454 | {
|
---|
| 455 | setWaitForVerticalBlank(false);
|
---|
| 456 | }
|
---|
| 457 | }
|
---|
| 458 |
|
---|
| 459 |
|
---|
| 460 | LogManager::getSingleton().logMessage("*****************************************");
|
---|
| 461 | LogManager::getSingleton().logMessage("*** Direct3D Subsystem Initialised Ok ***");
|
---|
| 462 | LogManager::getSingleton().logMessage("*****************************************");
|
---|
| 463 |
|
---|
| 464 | // call superclass method
|
---|
| 465 | RenderSystem::initialise(autoCreateWindow);
|
---|
| 466 |
|
---|
| 467 | // Create buffer manager
|
---|
| 468 | mHardwareBufferManager = new D3D7HardwareBufferManager();
|
---|
| 469 | // Create dummy gpu manager
|
---|
| 470 | mGpuProgramManager = new D3D7GpuProgramManager();
|
---|
| 471 |
|
---|
| 472 |
|
---|
| 473 | return autoWindow;
|
---|
| 474 |
|
---|
| 475 | }
|
---|
| 476 |
|
---|
| 477 | //-----------------------------------------------------------------------
|
---|
| 478 | void D3DRenderSystem::reinitialise(void)
|
---|
| 479 | {
|
---|
| 480 | this->shutdown();
|
---|
| 481 | this->initialise(true);
|
---|
| 482 | }
|
---|
| 483 |
|
---|
| 484 |
|
---|
| 485 | //-----------------------------------------------------------------------
|
---|
| 486 | void D3DRenderSystem::shutdown(void)
|
---|
| 487 | {
|
---|
| 488 | RenderSystem::shutdown();
|
---|
| 489 |
|
---|
| 490 | // Cleanup
|
---|
| 491 | // Release all DirectX resources
|
---|
| 492 | //D3DTextr_InvalidateAllTextures();
|
---|
| 493 | if (mActiveDDDriver)
|
---|
| 494 | {
|
---|
| 495 | mActiveDDDriver->Cleanup();
|
---|
| 496 | }
|
---|
| 497 |
|
---|
| 498 | // Delete system objects
|
---|
| 499 | SAFE_DELETE(mDriverList);
|
---|
| 500 |
|
---|
| 501 | mActiveDDDriver = NULL;
|
---|
| 502 |
|
---|
| 503 |
|
---|
| 504 |
|
---|
| 505 | // Write termination message
|
---|
| 506 | LogManager::getSingleton().logMessage("*-*-* Direct3D Subsystem shutting down cleanly.");
|
---|
| 507 |
|
---|
| 508 |
|
---|
| 509 | }
|
---|
| 510 |
|
---|
| 511 | //-----------------------------------------------------------------------
|
---|
| 512 | void D3DRenderSystem::setAmbientLight(float r, float g, float b)
|
---|
| 513 | {
|
---|
| 514 | // Call D3D
|
---|
| 515 | D3DCOLOR col = D3DRGB(r,g,b);
|
---|
| 516 |
|
---|
| 517 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_AMBIENT, col);
|
---|
| 518 | if (FAILED(hr))
|
---|
| 519 | OGRE_EXCEPT(hr, "Error setting ambient light.", "D3DRenderSystem::setAmbientLight");
|
---|
| 520 | }
|
---|
| 521 |
|
---|
| 522 | //-----------------------------------------------------------------------
|
---|
| 523 | void D3DRenderSystem::setShadingType(ShadeOptions so)
|
---|
| 524 | {
|
---|
| 525 | D3DSHADEMODE d3dMode;
|
---|
| 526 | switch(so)
|
---|
| 527 | {
|
---|
| 528 | case SO_FLAT:
|
---|
| 529 | d3dMode = D3DSHADE_FLAT;
|
---|
| 530 | break;
|
---|
| 531 | case SO_GOURAUD:
|
---|
| 532 | d3dMode = D3DSHADE_GOURAUD;
|
---|
| 533 | break;
|
---|
| 534 | case SO_PHONG:
|
---|
| 535 | d3dMode = D3DSHADE_PHONG;
|
---|
| 536 | break;
|
---|
| 537 |
|
---|
| 538 | }
|
---|
| 539 |
|
---|
| 540 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_SHADEMODE, d3dMode);
|
---|
| 541 | if (FAILED(hr))
|
---|
| 542 | OGRE_EXCEPT(hr, "Error setting shading mode.", "D3DRenderSystem::setShadingType");
|
---|
| 543 |
|
---|
| 544 | }
|
---|
| 545 |
|
---|
| 546 |
|
---|
| 547 | //-----------------------------------------------------------------------
|
---|
| 548 | RenderWindow* D3DRenderSystem::createRenderWindow(const String &name,
|
---|
| 549 | unsigned int width, unsigned int height, bool fullScreen,
|
---|
| 550 | const NameValuePairList *miscParams)
|
---|
| 551 | {
|
---|
| 552 | static bool firstWindow = true;
|
---|
| 553 | OgreGuard( "D3DRenderSystem::createRenderWindow" );
|
---|
| 554 |
|
---|
| 555 | String msg;
|
---|
| 556 |
|
---|
| 557 | // Make sure we don't already have a render target of the
|
---|
| 558 | // same name as the one supplied
|
---|
| 559 | if( mRenderTargets.find( name ) != mRenderTargets.end() )
|
---|
| 560 | {
|
---|
| 561 | msg = msg + "A render target of the same name (" + name + ") already "
|
---|
| 562 | "exists. You cannot create a new window with this name.";
|
---|
| 563 | OGRE_EXCEPT(999,msg,"D3DRenderSystem::createRenderWindow");
|
---|
| 564 | }
|
---|
| 565 |
|
---|
| 566 | RenderWindow* win = new D3D7RenderWindow(mhInstance, mActiveDDDriver);
|
---|
| 567 | // Create window, supplying DD interface & hInstance
|
---|
| 568 | win->create(name, width, height, fullScreen, miscParams);
|
---|
| 569 |
|
---|
| 570 | attachRenderTarget( *win );
|
---|
| 571 |
|
---|
| 572 | // If this is the first window, get the D3D device
|
---|
| 573 | // and create the texture manager, setup caps
|
---|
| 574 | if (firstWindow)
|
---|
| 575 | {
|
---|
| 576 | win->getCustomAttribute("D3DDEVICE", &mlpD3DDevice);
|
---|
| 577 | // Get caps
|
---|
| 578 | mlpD3DDevice->GetCaps(&mD3DDeviceDesc);
|
---|
| 579 | // Create my texture manager for use by others
|
---|
| 580 | // Note this is a Singleton; pointer is held static by superclass
|
---|
| 581 | mTextureManager = new D3DTextureManager(mlpD3DDevice);
|
---|
| 582 |
|
---|
| 583 | // Check for hardware stencil support
|
---|
| 584 | // Get render target, then depth buffer and check format
|
---|
| 585 | LPDIRECTDRAWSURFACE7 lpTarget;
|
---|
| 586 | win->getCustomAttribute("DDBACKBUFFER", &lpTarget);
|
---|
| 587 | DDSCAPS2 ddscaps;
|
---|
| 588 | ZeroMemory(&ddscaps, sizeof(DDSCAPS2));
|
---|
| 589 | ddscaps.dwCaps = DDSCAPS_ZBUFFER;
|
---|
| 590 | lpTarget->GetAttachedSurface(&ddscaps, &lpTarget);
|
---|
| 591 | lpTarget->Release();
|
---|
| 592 | DDSURFACEDESC2 ddsd;
|
---|
| 593 | ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
---|
| 594 | lpTarget->GetSurfaceDesc(&ddsd);
|
---|
| 595 | DWORD stencil = ddsd.ddpfPixelFormat.dwStencilBitDepth;
|
---|
| 596 | if(stencil > 0)
|
---|
| 597 | {
|
---|
| 598 | mCapabilities->setCapability(RSC_HWSTENCIL);
|
---|
| 599 | mCapabilities->setStencilBufferBitDepth(stencil);
|
---|
| 600 | if ((mD3DDeviceDesc.dwStencilCaps & D3DSTENCILCAPS_INCR) &&
|
---|
| 601 | (mD3DDeviceDesc.dwStencilCaps & D3DSTENCILCAPS_DECR))
|
---|
| 602 | mCapabilities->setCapability(RSC_STENCIL_WRAP);
|
---|
| 603 | }
|
---|
| 604 |
|
---|
| 605 | // Anisotropy?
|
---|
| 606 | if (mD3DDeviceDesc.dwMaxAnisotropy > 1)
|
---|
| 607 | mCapabilities->setCapability(RSC_ANISOTROPY);
|
---|
| 608 | // Blending between stages supported
|
---|
| 609 | mCapabilities->setCapability(RSC_BLENDING);
|
---|
| 610 | // Cubemapping
|
---|
| 611 | if (mD3DDeviceDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP)
|
---|
| 612 | mCapabilities->setCapability(RSC_CUBEMAPPING);
|
---|
| 613 |
|
---|
| 614 | // DOT3
|
---|
| 615 | if (mD3DDeviceDesc.dwTextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)
|
---|
| 616 | mCapabilities->setCapability(RSC_DOT3);
|
---|
| 617 |
|
---|
| 618 | // Set the number of texture units based on details from current device
|
---|
| 619 | mCapabilities->setNumTextureUnits(mD3DDeviceDesc.wMaxSimultaneousTextures);
|
---|
| 620 |
|
---|
| 621 | Log* defaultLog = LogManager::getSingleton().getDefaultLog();
|
---|
| 622 | if (defaultLog)
|
---|
| 623 | {
|
---|
| 624 | mCapabilities->log(defaultLog);
|
---|
| 625 | }
|
---|
| 626 |
|
---|
| 627 | firstWindow = false;
|
---|
| 628 | }
|
---|
| 629 |
|
---|
| 630 | OgreUnguardRet( win );
|
---|
| 631 | }
|
---|
| 632 |
|
---|
| 633 | RenderTexture * D3DRenderSystem::createRenderTexture( const String & name, unsigned int width, unsigned int height,
|
---|
| 634 | TextureType texType, PixelFormat internalFormat, const NameValuePairList *miscParams )
|
---|
| 635 | {
|
---|
| 636 | RenderTexture * rt = new D3D7RenderTexture( name, width, height, texType, internalFormat, miscParams );
|
---|
| 637 | attachRenderTarget( *rt );
|
---|
| 638 | return rt;
|
---|
| 639 | }
|
---|
| 640 |
|
---|
| 641 | //-----------------------------------------------------------------------
|
---|
| 642 | // Low-level overridden members
|
---|
| 643 | //-----------------------------------------------------------------------
|
---|
| 644 | //---------------------------------------------------------------------
|
---|
| 645 | void D3DRenderSystem::_useLights(const LightList& lights, unsigned short limit)
|
---|
| 646 | {
|
---|
| 647 | LightList::const_iterator i, iend;
|
---|
| 648 | iend = lights.end();
|
---|
| 649 | unsigned short num = 0;
|
---|
| 650 | for (i = lights.begin(); i != iend && num < limit; ++i, ++num)
|
---|
| 651 | {
|
---|
| 652 | setD3DLight(num, *i);
|
---|
| 653 | }
|
---|
| 654 | // Disable extra lights
|
---|
| 655 | for (; num < mCurrentLights; ++num)
|
---|
| 656 | {
|
---|
| 657 | setD3DLight(num, NULL);
|
---|
| 658 | }
|
---|
| 659 | mCurrentLights = std::min(limit, static_cast<unsigned short>(lights.size()));
|
---|
| 660 |
|
---|
| 661 | }
|
---|
| 662 | //-----------------------------------------------------------------------
|
---|
| 663 | void D3DRenderSystem::setD3DLight(size_t index, Light* lt)
|
---|
| 664 | {
|
---|
| 665 | // Add to D3D
|
---|
| 666 | HRESULT hr;
|
---|
| 667 | D3DLIGHT7 d3dLight;
|
---|
| 668 |
|
---|
| 669 | if (!lt)
|
---|
| 670 | {
|
---|
| 671 | hr = mlpD3DDevice->LightEnable(index, FALSE);
|
---|
| 672 | if (FAILED(hr))
|
---|
| 673 | OGRE_EXCEPT(hr, "Unable to disable light.", "D3DRenderSystem::setD3DLight");
|
---|
| 674 | }
|
---|
| 675 | else
|
---|
| 676 | {
|
---|
| 677 | switch (lt->getType())
|
---|
| 678 | {
|
---|
| 679 | case Light::LT_POINT:
|
---|
| 680 | d3dLight.dltType = D3DLIGHT_POINT;
|
---|
| 681 | break;
|
---|
| 682 | case Light::LT_DIRECTIONAL:
|
---|
| 683 | d3dLight.dltType = D3DLIGHT_DIRECTIONAL;
|
---|
| 684 | break;
|
---|
| 685 | case Light::LT_SPOTLIGHT:
|
---|
| 686 | d3dLight.dltType = D3DLIGHT_SPOT;
|
---|
| 687 | d3dLight.dvFalloff = lt->getSpotlightFalloff();
|
---|
| 688 | d3dLight.dvTheta = lt->getSpotlightInnerAngle().valueRadians();
|
---|
| 689 | d3dLight.dvPhi = lt->getSpotlightOuterAngle().valueRadians();
|
---|
| 690 | break;
|
---|
| 691 | }
|
---|
| 692 |
|
---|
| 693 | // Colours
|
---|
| 694 | ColourValue col;
|
---|
| 695 | col = lt->getDiffuseColour();
|
---|
| 696 | d3dLight.dcvDiffuse.r = col.r;
|
---|
| 697 | d3dLight.dcvDiffuse.g = col.g;
|
---|
| 698 | d3dLight.dcvDiffuse.b = col.b;
|
---|
| 699 | d3dLight.dcvDiffuse.a = col.a;
|
---|
| 700 |
|
---|
| 701 | col = lt->getSpecularColour();
|
---|
| 702 | d3dLight.dcvSpecular.r = col.r;
|
---|
| 703 | d3dLight.dcvSpecular.g = col.g;
|
---|
| 704 | d3dLight.dcvSpecular.b = col.b;
|
---|
| 705 | d3dLight.dcvSpecular.a = col.a;
|
---|
| 706 |
|
---|
| 707 | // Never use ambient for a movable light
|
---|
| 708 | d3dLight.dcvAmbient.r = 0.0;
|
---|
| 709 | d3dLight.dcvAmbient.g = 0.0;
|
---|
| 710 | d3dLight.dcvAmbient.b = 0.0;
|
---|
| 711 | d3dLight.dcvAmbient.a = 0.0;
|
---|
| 712 |
|
---|
| 713 | // Position (Irrelevant for directional)
|
---|
| 714 | Vector3 vec;
|
---|
| 715 | if (lt->getType() != Light::LT_DIRECTIONAL)
|
---|
| 716 | {
|
---|
| 717 | vec = lt->getDerivedPosition();
|
---|
| 718 |
|
---|
| 719 | d3dLight.dvPosition.x = vec.x;
|
---|
| 720 | d3dLight.dvPosition.y = vec.y;
|
---|
| 721 | d3dLight.dvPosition.z = vec.z;
|
---|
| 722 | }
|
---|
| 723 | // Direction (Irrelevant for point lights)
|
---|
| 724 | if (lt->getType() != Light::LT_POINT)
|
---|
| 725 | {
|
---|
| 726 | vec = lt->getDerivedDirection();
|
---|
| 727 | d3dLight.dvDirection.x = vec.x;
|
---|
| 728 | d3dLight.dvDirection.y = vec.y;
|
---|
| 729 | d3dLight.dvDirection.z = vec.z;
|
---|
| 730 | }
|
---|
| 731 | // Attenuation parameters
|
---|
| 732 | d3dLight.dvRange = lt->getAttenuationRange();
|
---|
| 733 | d3dLight.dvAttenuation0 = lt->getAttenuationConstant();
|
---|
| 734 | d3dLight.dvAttenuation1 = lt->getAttenuationLinear();
|
---|
| 735 | d3dLight.dvAttenuation2 = lt->getAttenuationQuadric();
|
---|
| 736 |
|
---|
| 737 |
|
---|
| 738 |
|
---|
| 739 | // Set light state
|
---|
| 740 | hr = mlpD3DDevice->SetLight(index, &d3dLight);
|
---|
| 741 |
|
---|
| 742 | if (FAILED(hr))
|
---|
| 743 | OGRE_EXCEPT(hr, "Unable to set light details", "D3DRenderSystem::setD3DLight");
|
---|
| 744 |
|
---|
| 745 | hr = mlpD3DDevice->LightEnable(index, TRUE);
|
---|
| 746 | if (FAILED(hr))
|
---|
| 747 | OGRE_EXCEPT(hr, "Unable to enable light.", "D3DRenderSystem::setD3DLight");
|
---|
| 748 | }
|
---|
| 749 |
|
---|
| 750 |
|
---|
| 751 | }
|
---|
| 752 | //-----------------------------------------------------------------------
|
---|
| 753 | D3DMATRIX D3DRenderSystem::makeD3DMatrix(const Matrix4& mat)
|
---|
| 754 | {
|
---|
| 755 | // Transpose matrix
|
---|
| 756 | // D3D uses row vectors i.e. V*M
|
---|
| 757 | // Ogre, OpenGL and everything else uses coloumn vectors i.e. M*V
|
---|
| 758 | D3DMATRIX d3dMat;
|
---|
| 759 |
|
---|
| 760 | d3dMat.m[0][0] = mat[0][0];
|
---|
| 761 | d3dMat.m[0][1] = mat[1][0];
|
---|
| 762 | d3dMat.m[0][2] = mat[2][0];
|
---|
| 763 | d3dMat.m[0][3] = mat[3][0];
|
---|
| 764 |
|
---|
| 765 | d3dMat.m[1][0] = mat[0][1];
|
---|
| 766 | d3dMat.m[1][1] = mat[1][1];
|
---|
| 767 | d3dMat.m[1][2] = mat[2][1];
|
---|
| 768 | d3dMat.m[1][3] = mat[3][1];
|
---|
| 769 |
|
---|
| 770 | d3dMat.m[2][0] = mat[0][2];
|
---|
| 771 | d3dMat.m[2][1] = mat[1][2];
|
---|
| 772 | d3dMat.m[2][2] = mat[2][2];
|
---|
| 773 | d3dMat.m[2][3] = mat[3][2];
|
---|
| 774 |
|
---|
| 775 | d3dMat.m[3][0] = mat[0][3];
|
---|
| 776 | d3dMat.m[3][1] = mat[1][3];
|
---|
| 777 | d3dMat.m[3][2] = mat[2][3];
|
---|
| 778 | d3dMat.m[3][3] = mat[3][3];
|
---|
| 779 |
|
---|
| 780 | return d3dMat;
|
---|
| 781 | }
|
---|
| 782 |
|
---|
| 783 | Matrix4 D3DRenderSystem::convertD3DMatrix(const D3DMATRIX& d3dmat)
|
---|
| 784 | {
|
---|
| 785 | // The reverse of makeD3DMatrix
|
---|
| 786 | // Transpose matrix
|
---|
| 787 | // D3D uses row vectors i.e. V*M
|
---|
| 788 | // Ogre, OpenGL and everything else uses coloumn vectors i.e. M*V
|
---|
| 789 | Matrix4 mat;
|
---|
| 790 | for (unsigned row = 0; row < 4; ++row)
|
---|
| 791 | for (unsigned col = 0; col < 4; ++col)
|
---|
| 792 | mat[col][row] = d3dmat.m[row][col];
|
---|
| 793 |
|
---|
| 794 | return mat;
|
---|
| 795 |
|
---|
| 796 |
|
---|
| 797 | }
|
---|
| 798 | //-----------------------------------------------------------------------
|
---|
| 799 | void D3DRenderSystem::_setWorldMatrix(const Matrix4 &m)
|
---|
| 800 | {
|
---|
| 801 | D3DMATRIX d3dmat;
|
---|
| 802 |
|
---|
| 803 | d3dmat = makeD3DMatrix(m);
|
---|
| 804 |
|
---|
| 805 | HRESULT hr = mlpD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &d3dmat);
|
---|
| 806 |
|
---|
| 807 | if (FAILED(hr))
|
---|
| 808 | OGRE_EXCEPT(hr, "Cannot set D3D world matrix",
|
---|
| 809 | "D3DRenderSystem::_setWorldMatrix");
|
---|
| 810 | }
|
---|
| 811 |
|
---|
| 812 | //-----------------------------------------------------------------------
|
---|
| 813 | void D3DRenderSystem::_setViewMatrix(const Matrix4 &m)
|
---|
| 814 | {
|
---|
| 815 | // save latest view matrix
|
---|
| 816 | mViewMatrix = m;
|
---|
| 817 | mViewMatrix[2][0] = -mViewMatrix[2][0];
|
---|
| 818 | mViewMatrix[2][1] = -mViewMatrix[2][1];
|
---|
| 819 | mViewMatrix[2][2] = -mViewMatrix[2][2];
|
---|
| 820 | mViewMatrix[2][3] = -mViewMatrix[2][3];
|
---|
| 821 |
|
---|
| 822 | D3DMATRIX d3dmat = makeD3DMatrix(mViewMatrix);
|
---|
| 823 |
|
---|
| 824 | HRESULT hr = mlpD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &d3dmat);
|
---|
| 825 |
|
---|
| 826 | if (FAILED(hr))
|
---|
| 827 | OGRE_EXCEPT(hr, "Cannot set D3D view matrix",
|
---|
| 828 | "D3DRenderSystem::_setViewMatrix");
|
---|
| 829 |
|
---|
| 830 | }
|
---|
| 831 | //-----------------------------------------------------------------------
|
---|
| 832 | void D3DRenderSystem::_setProjectionMatrix(const Matrix4 &m)
|
---|
| 833 | {
|
---|
| 834 | D3DMATRIX d3dmat = makeD3DMatrix(m);
|
---|
| 835 |
|
---|
| 836 | if( mActiveRenderTarget->requiresTextureFlipping() )
|
---|
| 837 | {
|
---|
| 838 | d3dmat._22 = - d3dmat._22;
|
---|
| 839 | }
|
---|
| 840 |
|
---|
| 841 | HRESULT hr = mlpD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &d3dmat);
|
---|
| 842 |
|
---|
| 843 | if (FAILED(hr))
|
---|
| 844 | OGRE_EXCEPT(hr, "Cannot set D3D projection matrix",
|
---|
| 845 | "D3DRenderSystem::_setProjectionMatrix");
|
---|
| 846 | }
|
---|
| 847 |
|
---|
| 848 |
|
---|
| 849 | //-----------------------------------------------------------------------
|
---|
| 850 | void D3DRenderSystem::_setSurfaceParams(const ColourValue &ambient,
|
---|
| 851 | const ColourValue &diffuse, const ColourValue &specular,
|
---|
| 852 | const ColourValue &emissive, const Real shininess,
|
---|
| 853 | TrackVertexColourType tracking)
|
---|
| 854 | {
|
---|
| 855 | // Remember last call
|
---|
| 856 | static ColourValue lastAmbient = ColourValue::Black;
|
---|
| 857 | static ColourValue lastDiffuse = ColourValue::Black;
|
---|
| 858 | static ColourValue lastSpecular = ColourValue::Black;
|
---|
| 859 | static ColourValue lastEmissive = ColourValue::Black;
|
---|
| 860 | static Real lastShininess = 0.0;
|
---|
| 861 | static TrackVertexColourType lastTracking = -1;
|
---|
| 862 |
|
---|
| 863 | // Only update if changed
|
---|
| 864 | if (ambient != lastAmbient || diffuse != lastDiffuse ||
|
---|
| 865 | specular != lastSpecular || emissive != lastEmissive ||
|
---|
| 866 | shininess != lastShininess)
|
---|
| 867 | {
|
---|
| 868 | // Convert to D3D
|
---|
| 869 | D3DMATERIAL7 d3dMat;
|
---|
| 870 |
|
---|
| 871 | d3dMat.dcvDiffuse.r = diffuse.r;
|
---|
| 872 | d3dMat.dcvDiffuse.g = diffuse.g;
|
---|
| 873 | d3dMat.dcvDiffuse.b = diffuse.b;
|
---|
| 874 | d3dMat.dcvDiffuse.a = diffuse.a;
|
---|
| 875 |
|
---|
| 876 | d3dMat.dcvAmbient.r = ambient.r;
|
---|
| 877 | d3dMat.dcvAmbient.g = ambient.g;
|
---|
| 878 | d3dMat.dcvAmbient.b = ambient.b;
|
---|
| 879 | d3dMat.dcvAmbient.a = ambient.a;
|
---|
| 880 |
|
---|
| 881 | d3dMat.dcvSpecular.r = specular.r;
|
---|
| 882 | d3dMat.dcvSpecular.g = specular.g;
|
---|
| 883 | d3dMat.dcvSpecular.b = specular.b;
|
---|
| 884 | d3dMat.dcvSpecular.a = specular.a;
|
---|
| 885 |
|
---|
| 886 | d3dMat.dcvEmissive.r = emissive.r;
|
---|
| 887 | d3dMat.dcvEmissive.g = emissive.g;
|
---|
| 888 | d3dMat.dcvEmissive.b = emissive.b;
|
---|
| 889 | d3dMat.dcvEmissive.a = emissive.a;
|
---|
| 890 |
|
---|
| 891 | d3dMat.dvPower = shininess;
|
---|
| 892 |
|
---|
| 893 | HRESULT hr = mlpD3DDevice->SetMaterial(&d3dMat);
|
---|
| 894 | if (FAILED(hr))
|
---|
| 895 | OGRE_EXCEPT(hr, "Error setting D3D material.", "D3DRenderSystem::_setSurfaceParams");
|
---|
| 896 |
|
---|
| 897 | // Remember the details
|
---|
| 898 | lastAmbient = ambient;
|
---|
| 899 | lastDiffuse = diffuse;
|
---|
| 900 | lastSpecular = specular;
|
---|
| 901 | lastEmissive = emissive;
|
---|
| 902 | lastShininess = shininess;
|
---|
| 903 | }
|
---|
| 904 | if(tracking != lastTracking)
|
---|
| 905 | {
|
---|
| 906 | if(tracking != TVC_NONE)
|
---|
| 907 | {
|
---|
| 908 | mlpD3DDevice->SetRenderState(D3DRENDERSTATE_COLORVERTEX, TRUE);
|
---|
| 909 | mlpD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENTMATERIALSOURCE, (tracking&TVC_AMBIENT)?D3DMCS_COLOR1:D3DMCS_MATERIAL);
|
---|
| 910 | mlpD3DDevice->SetRenderState(D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, (tracking&TVC_DIFFUSE)?D3DMCS_COLOR1:D3DMCS_MATERIAL);
|
---|
| 911 | mlpD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARMATERIALSOURCE, (tracking&TVC_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL);
|
---|
| 912 | mlpD3DDevice->SetRenderState(D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, (tracking&TVC_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL);
|
---|
| 913 | }
|
---|
| 914 | else
|
---|
| 915 | {
|
---|
| 916 | mlpD3DDevice->SetRenderState(D3DRENDERSTATE_COLORVERTEX, FALSE);
|
---|
| 917 | }
|
---|
| 918 | lastTracking = tracking;
|
---|
| 919 | }
|
---|
| 920 | }
|
---|
| 921 | //-----------------------------------------------------------------------
|
---|
| 922 | void D3DRenderSystem::_setTexture(size_t stage, bool enabled, const String &texname)
|
---|
| 923 | {
|
---|
| 924 | HRESULT hr;
|
---|
| 925 | D3DTexturePtr dt = TextureManager::getSingleton().getByName(texname);
|
---|
| 926 | if (enabled && !dt.isNull())
|
---|
| 927 | {
|
---|
| 928 | // note used
|
---|
| 929 | dt->touch();
|
---|
| 930 |
|
---|
| 931 | LPDIRECTDRAWSURFACE7 pTex = dt->getDDSurface();
|
---|
| 932 | if (pTex != mTexStageDesc[stage].pTex)
|
---|
| 933 | {
|
---|
| 934 | hr = mlpD3DDevice->SetTexture(stage, pTex );
|
---|
| 935 | if (FAILED(hr))
|
---|
| 936 | OGRE_EXCEPT(hr, "Unable to set texture in D3D.", "D3DRenderSystem::_setTexture");
|
---|
| 937 |
|
---|
| 938 | // set stage desc.
|
---|
| 939 | mTexStageDesc[stage].texType = _ogreTexTypeToD3DTexType(dt->getTextureType());
|
---|
| 940 | mTexStageDesc[stage].pTex = pTex;
|
---|
| 941 | }
|
---|
| 942 | }
|
---|
| 943 | else
|
---|
| 944 | {
|
---|
| 945 | hr = mlpD3DDevice->SetTexture(stage, 0);
|
---|
| 946 | if (FAILED(hr))
|
---|
| 947 | OGRE_EXCEPT(hr, "Unable to disable texture in D3D.", "D3DRenderSystem::_setTexture");
|
---|
| 948 | hr = __SetTextureStageState( stage, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
---|
| 949 | if (FAILED(hr))
|
---|
| 950 | OGRE_EXCEPT(hr, "Unable to disable texture in D3D.", "D3DRenderSystem::_setTexture");
|
---|
| 951 |
|
---|
| 952 | // set stage desc. to defaults
|
---|
| 953 | mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE;
|
---|
| 954 | mTexStageDesc[stage].coordIndex = 0;
|
---|
| 955 | mTexStageDesc[stage].texType = D3D_TEX_TYPE_NORMAL;
|
---|
| 956 | mTexStageDesc[stage].pTex = NULL;
|
---|
| 957 | }
|
---|
| 958 | }
|
---|
| 959 | //---------------------------------------------------------------------
|
---|
| 960 | DWORD getD3DTexCalc(TexCoordCalcMethod tcc)
|
---|
| 961 | {
|
---|
| 962 | switch (tcc)
|
---|
| 963 | {
|
---|
| 964 | case TEXCALC_NONE:
|
---|
| 965 | return 0;
|
---|
| 966 | case TEXCALC_ENVIRONMENT_MAP:
|
---|
| 967 | // D3D7 does not support spherical reflection
|
---|
| 968 | return D3DTSS_TCI_CAMERASPACENORMAL;
|
---|
| 969 | case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
|
---|
| 970 | return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR;
|
---|
| 971 | case TEXCALC_ENVIRONMENT_MAP_PLANAR:
|
---|
| 972 | case TEXCALC_PROJECTIVE_TEXTURE:
|
---|
| 973 | return D3DTSS_TCI_CAMERASPACEPOSITION;
|
---|
| 974 | case TEXCALC_ENVIRONMENT_MAP_NORMAL:
|
---|
| 975 | return D3DTSS_TCI_CAMERASPACENORMAL;
|
---|
| 976 | }
|
---|
| 977 | }
|
---|
| 978 | //-----------------------------------------------------------------------
|
---|
| 979 | void D3DRenderSystem::_setTextureCoordCalculation(size_t stage, TexCoordCalcMethod m,
|
---|
| 980 | const Frustum* frustum)
|
---|
| 981 | {
|
---|
| 982 | HRESULT hr = S_OK;
|
---|
| 983 | // record the stage state
|
---|
| 984 | mTexStageDesc[stage].autoTexCoordType = m;
|
---|
| 985 | mTexStageDesc[stage].frustum = frustum;
|
---|
| 986 |
|
---|
| 987 | hr = __SetTextureStageState(stage, D3DTSS_TEXCOORDINDEX,
|
---|
| 988 | getD3DTexCalc(m) | mTexStageDesc[stage].coordIndex);
|
---|
| 989 | if( FAILED( hr ) )
|
---|
| 990 | OGRE_EXCEPT( hr, "Error setting texture coord calculation", "D3DRenderSystem::_setTextureCoordCalculation" );
|
---|
| 991 |
|
---|
| 992 | }
|
---|
| 993 | //-----------------------------------------------------------------------
|
---|
| 994 | void D3DRenderSystem::_setTextureMatrix(size_t stage, const Matrix4& xForm)
|
---|
| 995 | {
|
---|
| 996 | HRESULT hr;
|
---|
| 997 | D3DMATRIX d3dMat; // the matrix we'll maybe apply
|
---|
| 998 | Matrix4 newMat = xForm; // the matrix we'll apply after conv. to D3D format
|
---|
| 999 |
|
---|
| 1000 |
|
---|
| 1001 | /* If envmap is applied, since D3D7 doesn't support spheremap,
|
---|
| 1002 | then we have to use texture transform to make the camera space normal
|
---|
| 1003 | reference the envmap properly. This isn't exactly the same as spheremap
|
---|
| 1004 | (it looks nasty on flat areas because the camera space normals are the same)
|
---|
| 1005 | but it's the best approximation we have in the absence of a proper spheremap */
|
---|
| 1006 | if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_ENVIRONMENT_MAP)
|
---|
| 1007 | {
|
---|
| 1008 | // concatenate with the xForm
|
---|
| 1009 | newMat = newMat.concatenate(Matrix4::CLIPSPACE2DTOIMAGESPACE);
|
---|
| 1010 | }
|
---|
| 1011 |
|
---|
| 1012 | // If this is a cubic reflection, we need to modify using the view matrix
|
---|
| 1013 | if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_ENVIRONMENT_MAP_REFLECTION)
|
---|
| 1014 | {
|
---|
| 1015 | D3DMATRIX viewMatrix;
|
---|
| 1016 |
|
---|
| 1017 | // Get view matrix
|
---|
| 1018 | mlpD3DDevice->GetTransform(D3DTRANSFORMSTATE_VIEW, &viewMatrix);
|
---|
| 1019 | // Get transposed 3x3, ie since D3D is transposed just copy
|
---|
| 1020 | // We want to transpose since that will invert an orthonormal matrix ie rotation
|
---|
| 1021 | Matrix4 ogreViewTransposed;
|
---|
| 1022 | ogreViewTransposed[0][0] = viewMatrix.m[0][0];
|
---|
| 1023 | ogreViewTransposed[0][1] = viewMatrix.m[0][1];
|
---|
| 1024 | ogreViewTransposed[0][2] = viewMatrix.m[0][2];
|
---|
| 1025 | ogreViewTransposed[0][3] = 0.0f;
|
---|
| 1026 |
|
---|
| 1027 | ogreViewTransposed[1][0] = viewMatrix.m[1][0];
|
---|
| 1028 | ogreViewTransposed[1][1] = viewMatrix.m[1][1];
|
---|
| 1029 | ogreViewTransposed[1][2] = viewMatrix.m[1][2];
|
---|
| 1030 | ogreViewTransposed[1][3] = 0.0f;
|
---|
| 1031 |
|
---|
| 1032 | ogreViewTransposed[2][0] = viewMatrix.m[2][0];
|
---|
| 1033 | ogreViewTransposed[2][1] = viewMatrix.m[2][1];
|
---|
| 1034 | ogreViewTransposed[2][2] = viewMatrix.m[2][2];
|
---|
| 1035 | ogreViewTransposed[2][3] = 0.0f;
|
---|
| 1036 |
|
---|
| 1037 | ogreViewTransposed[3][0] = 0.0f;
|
---|
| 1038 | ogreViewTransposed[3][1] = 0.0f;
|
---|
| 1039 | ogreViewTransposed[3][2] = 0.0f;
|
---|
| 1040 | ogreViewTransposed[3][3] = 1.0f;
|
---|
| 1041 |
|
---|
| 1042 | newMat = newMat.concatenate(ogreViewTransposed);
|
---|
| 1043 | }
|
---|
| 1044 |
|
---|
| 1045 | if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE)
|
---|
| 1046 | {
|
---|
| 1047 | // Derive camera space to projector space transform
|
---|
| 1048 | // To do this, we need to undo the camera view matrix, then
|
---|
| 1049 | // apply the projector view & projection matrices
|
---|
| 1050 | newMat = mViewMatrix.inverse();
|
---|
| 1051 | newMat = mTexStageDesc[stage].frustum->getViewMatrix() * newMat;
|
---|
| 1052 | newMat = mTexStageDesc[stage].frustum->getProjectionMatrix() * newMat;
|
---|
| 1053 | if (mTexStageDesc[stage].frustum->getProjectionType() == PT_PERSPECTIVE)
|
---|
| 1054 | {
|
---|
| 1055 | newMat = PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * newMat;
|
---|
| 1056 | }
|
---|
| 1057 | else
|
---|
| 1058 | {
|
---|
| 1059 | newMat = PROJECTIONCLIPSPACE2DTOIMAGESPACE_ORTHO * newMat;
|
---|
| 1060 | }
|
---|
| 1061 | newMat = xForm * newMat;
|
---|
| 1062 |
|
---|
| 1063 | }
|
---|
| 1064 |
|
---|
| 1065 | // convert our matrix to D3D format
|
---|
| 1066 | d3dMat = makeD3DMatrix(newMat);
|
---|
| 1067 |
|
---|
| 1068 | // need this if texture is a cube map, to invert D3D's z coord
|
---|
| 1069 | if (mTexStageDesc[stage].autoTexCoordType != TEXCALC_NONE &&
|
---|
| 1070 | mTexStageDesc[stage].autoTexCoordType != TEXCALC_PROJECTIVE_TEXTURE)
|
---|
| 1071 | {
|
---|
| 1072 | d3dMat._13 = -d3dMat._13;
|
---|
| 1073 | d3dMat._23 = -d3dMat._23;
|
---|
| 1074 | d3dMat._33 = -d3dMat._33;
|
---|
| 1075 | d3dMat._43 = -d3dMat._43;
|
---|
| 1076 | }
|
---|
| 1077 |
|
---|
| 1078 | // set the matrix if it's not the identity
|
---|
| 1079 | if (!(newMat == Matrix4::IDENTITY))
|
---|
| 1080 | {
|
---|
| 1081 | // tell D3D the dimension of tex. coord.
|
---|
| 1082 | int texCoordDim;
|
---|
| 1083 | if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE)
|
---|
| 1084 | {
|
---|
| 1085 | texCoordDim = D3DTTFF_PROJECTED | D3DTTFF_COUNT3;
|
---|
| 1086 | }
|
---|
| 1087 | else
|
---|
| 1088 | {
|
---|
| 1089 | switch (mTexStageDesc[stage].texType)
|
---|
| 1090 | {
|
---|
| 1091 | case D3D_TEX_TYPE_NORMAL:
|
---|
| 1092 | texCoordDim = D3DTTFF_COUNT2;
|
---|
| 1093 | break;
|
---|
| 1094 | case D3D_TEX_TYPE_CUBE:
|
---|
| 1095 | case D3D_TEX_TYPE_VOLUME:
|
---|
| 1096 | texCoordDim = D3DTTFF_COUNT3;
|
---|
| 1097 | }
|
---|
| 1098 | }
|
---|
| 1099 |
|
---|
| 1100 | hr = __SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, texCoordDim );
|
---|
| 1101 | if (FAILED(hr))
|
---|
| 1102 | OGRE_EXCEPT( hr, "Unable to set texture coord. dimension", "D3D9RenderSystem::_setTextureMatrix" );
|
---|
| 1103 |
|
---|
| 1104 | hr = mlpD3DDevice->SetTransform(
|
---|
| 1105 | (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + stage), &d3dMat );
|
---|
| 1106 | if (FAILED(hr))
|
---|
| 1107 | OGRE_EXCEPT( hr, "Unable to set texture matrix", "D3D9RenderSystem::_setTextureMatrix" );
|
---|
| 1108 | }
|
---|
| 1109 | else
|
---|
| 1110 | {
|
---|
| 1111 | // disable all of this
|
---|
| 1112 | hr = __SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
|
---|
| 1113 | if( FAILED( hr ) )
|
---|
| 1114 | OGRE_EXCEPT( hr, "Error setting texture matrix", "D3D9RenderSystem::_setTextureMatrix" );
|
---|
| 1115 |
|
---|
| 1116 | // set the identity matrix
|
---|
| 1117 | D3DUtil_SetIdentityMatrix( d3dMat );
|
---|
| 1118 | hr = mlpD3DDevice->SetTransform(
|
---|
| 1119 | (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + stage), &d3dMat );
|
---|
| 1120 | if( FAILED( hr ) )
|
---|
| 1121 | OGRE_EXCEPT( hr, "Error setting texture matrix", "D3D9RenderSystem::_setTextureMatrix" );
|
---|
| 1122 | }
|
---|
| 1123 | }
|
---|
| 1124 | //---------------------------------------------------------------------
|
---|
| 1125 | void D3DRenderSystem::_setTextureCoordSet( size_t stage, size_t index )
|
---|
| 1126 | {
|
---|
| 1127 | HRESULT hr;
|
---|
| 1128 | hr = __SetTextureStageState( stage, D3DTSS_TEXCOORDINDEX,
|
---|
| 1129 | getD3DTexCalc(mTexStageDesc[stage].autoTexCoordType) | index );
|
---|
| 1130 | if( FAILED( hr ) )
|
---|
| 1131 | OGRE_EXCEPT( hr, "Unable to set texture coord. set index", "D3DRenderSystem::_setTextureCoordSet" );
|
---|
| 1132 | // Record settings
|
---|
| 1133 | mTexStageDesc[stage].coordIndex = index;
|
---|
| 1134 | }
|
---|
| 1135 | //-----------------------------------------------------------------------
|
---|
| 1136 | void D3DRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm)
|
---|
| 1137 | {
|
---|
| 1138 | HRESULT hr;
|
---|
| 1139 | D3DTEXTURESTAGESTATETYPE tss;
|
---|
| 1140 | DWORD value;
|
---|
| 1141 |
|
---|
| 1142 | if (bm.blendType == LBT_COLOUR)
|
---|
| 1143 | {
|
---|
| 1144 | tss = D3DTSS_COLOROP;
|
---|
| 1145 | }
|
---|
| 1146 | else if (bm.blendType == LBT_ALPHA)
|
---|
| 1147 | {
|
---|
| 1148 | tss= D3DTSS_ALPHAOP;
|
---|
| 1149 | }
|
---|
| 1150 |
|
---|
| 1151 | switch (bm.operation)
|
---|
| 1152 | {
|
---|
| 1153 | case LBX_SOURCE1:
|
---|
| 1154 | value = D3DTOP_SELECTARG1;
|
---|
| 1155 | break;
|
---|
| 1156 | case LBX_SOURCE2:
|
---|
| 1157 | value = D3DTOP_SELECTARG2;
|
---|
| 1158 | break;
|
---|
| 1159 | case LBX_MODULATE:
|
---|
| 1160 | value = D3DTOP_MODULATE;
|
---|
| 1161 | break;
|
---|
| 1162 | case LBX_MODULATE_X2:
|
---|
| 1163 | value = D3DTOP_MODULATE2X;
|
---|
| 1164 | break;
|
---|
| 1165 | case LBX_MODULATE_X4:
|
---|
| 1166 | value = D3DTOP_MODULATE4X;
|
---|
| 1167 | break;
|
---|
| 1168 | case LBX_ADD:
|
---|
| 1169 | value = D3DTOP_ADD;
|
---|
| 1170 | break;
|
---|
| 1171 | case LBX_ADD_SIGNED:
|
---|
| 1172 | value = D3DTOP_ADDSIGNED;
|
---|
| 1173 | break;
|
---|
| 1174 | case LBX_ADD_SMOOTH:
|
---|
| 1175 | value = D3DTOP_ADDSMOOTH;
|
---|
| 1176 | break;
|
---|
| 1177 | case LBX_SUBTRACT:
|
---|
| 1178 | value = D3DTOP_SUBTRACT;
|
---|
| 1179 | break;
|
---|
| 1180 | case LBX_BLEND_DIFFUSE_ALPHA:
|
---|
| 1181 | value = D3DTOP_BLENDDIFFUSEALPHA;
|
---|
| 1182 | break;
|
---|
| 1183 | case LBX_BLEND_TEXTURE_ALPHA:
|
---|
| 1184 | value = D3DTOP_BLENDTEXTUREALPHA;
|
---|
| 1185 | break;
|
---|
| 1186 | case LBX_BLEND_CURRENT_ALPHA:
|
---|
| 1187 | value = D3DTOP_BLENDCURRENTALPHA;
|
---|
| 1188 | break;
|
---|
| 1189 | case LBX_BLEND_MANUAL:
|
---|
| 1190 | value = D3DTOP_BLENDFACTORALPHA;
|
---|
| 1191 | // Set factor in render state
|
---|
| 1192 | hr = __SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR,
|
---|
| 1193 | D3DRGBA(0,0,0,bm.factor));
|
---|
| 1194 | break;
|
---|
| 1195 | case LBX_DOTPRODUCT:
|
---|
| 1196 | if (mD3DDeviceDesc.dwTextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)
|
---|
| 1197 | value = D3DTOP_DOTPRODUCT3;
|
---|
| 1198 | else
|
---|
| 1199 | value = D3DTOP_MODULATE;
|
---|
| 1200 | break;
|
---|
| 1201 | }
|
---|
| 1202 |
|
---|
| 1203 | // Make call to set operation
|
---|
| 1204 | hr = __SetTextureStageState(stage, tss, value);
|
---|
| 1205 |
|
---|
| 1206 | // Now set up sources
|
---|
| 1207 | D3DCOLOR manualD3D;
|
---|
| 1208 | if (bm.blendType == LBT_COLOUR)
|
---|
| 1209 | {
|
---|
| 1210 | tss = D3DTSS_COLORARG1;
|
---|
| 1211 | manualD3D = D3DRGBA(bm.colourArg1.r,bm.colourArg1.g,bm.colourArg1.b,1.0);
|
---|
| 1212 | mManualBlendColours[stage][0] = bm.colourArg1;
|
---|
| 1213 | }
|
---|
| 1214 | else if (bm.blendType == LBT_ALPHA)
|
---|
| 1215 | {
|
---|
| 1216 | tss = D3DTSS_ALPHAARG1;
|
---|
| 1217 | manualD3D = D3DRGBA(mManualBlendColours[stage][0].r,
|
---|
| 1218 | mManualBlendColours[stage][0].g,
|
---|
| 1219 | mManualBlendColours[stage][0].b,
|
---|
| 1220 | bm.alphaArg1);
|
---|
| 1221 | }
|
---|
| 1222 | LayerBlendSource bs = bm.source1;
|
---|
| 1223 | for (int i = 0; i < 2; ++i)
|
---|
| 1224 | {
|
---|
| 1225 | switch (bs)
|
---|
| 1226 | {
|
---|
| 1227 | case LBS_CURRENT:
|
---|
| 1228 | value = D3DTA_CURRENT;
|
---|
| 1229 | break;
|
---|
| 1230 | case LBS_TEXTURE:
|
---|
| 1231 | value = D3DTA_TEXTURE;
|
---|
| 1232 | break;
|
---|
| 1233 | case LBS_DIFFUSE:
|
---|
| 1234 | value = D3DTA_DIFFUSE;
|
---|
| 1235 | break;
|
---|
| 1236 | case LBS_SPECULAR:
|
---|
| 1237 | value = D3DTA_SPECULAR;
|
---|
| 1238 | break;
|
---|
| 1239 | case LBS_MANUAL:
|
---|
| 1240 | value = D3DTA_TFACTOR;
|
---|
| 1241 | // Set factor in render state
|
---|
| 1242 | hr = __SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, manualD3D);
|
---|
| 1243 | break;
|
---|
| 1244 | }
|
---|
| 1245 |
|
---|
| 1246 | // Set source
|
---|
| 1247 | hr = __SetTextureStageState(stage, tss, value);
|
---|
| 1248 |
|
---|
| 1249 | // Source2
|
---|
| 1250 | bs = bm.source2;
|
---|
| 1251 | if (bm.blendType == LBT_COLOUR)
|
---|
| 1252 | {
|
---|
| 1253 | tss = D3DTSS_COLORARG2;
|
---|
| 1254 | manualD3D = D3DRGBA(bm.colourArg2.r,bm.colourArg2.g,bm.colourArg2.b,1.0);
|
---|
| 1255 | mManualBlendColours[stage][1] = bm.colourArg2;
|
---|
| 1256 | }
|
---|
| 1257 | else if (bm.blendType == LBT_ALPHA)
|
---|
| 1258 | {
|
---|
| 1259 | tss = D3DTSS_ALPHAARG2;
|
---|
| 1260 | manualD3D = D3DRGBA(mManualBlendColours[stage][1].r,
|
---|
| 1261 | mManualBlendColours[stage][1].g,
|
---|
| 1262 | mManualBlendColours[stage][1].b
|
---|
| 1263 | ,bm.alphaArg2);
|
---|
| 1264 | }
|
---|
| 1265 | }
|
---|
| 1266 | }
|
---|
| 1267 | //-----------------------------------------------------------------------
|
---|
| 1268 | void D3DRenderSystem::_setTextureAddressingMode(size_t stage, TextureUnitState::TextureAddressingMode tam)
|
---|
| 1269 | {
|
---|
| 1270 | HRESULT hr;
|
---|
| 1271 | D3DTEXTUREADDRESS d3dType;
|
---|
| 1272 |
|
---|
| 1273 | switch(tam)
|
---|
| 1274 | {
|
---|
| 1275 | case TextureUnitState::TAM_WRAP:
|
---|
| 1276 | d3dType = D3DTADDRESS_WRAP;
|
---|
| 1277 | break;
|
---|
| 1278 | case TextureUnitState::TAM_MIRROR:
|
---|
| 1279 | d3dType = D3DTADDRESS_MIRROR;
|
---|
| 1280 | break;
|
---|
| 1281 | case TextureUnitState::TAM_CLAMP:
|
---|
| 1282 | d3dType = D3DTADDRESS_CLAMP;
|
---|
| 1283 | break;
|
---|
| 1284 | }
|
---|
| 1285 |
|
---|
| 1286 |
|
---|
| 1287 | hr = __SetTextureStageState(stage, D3DTSS_ADDRESS, d3dType);
|
---|
| 1288 | }
|
---|
| 1289 | //-----------------------------------------------------------------------
|
---|
| 1290 | void D3DRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
|
---|
| 1291 | {
|
---|
| 1292 | HRESULT hr;
|
---|
| 1293 | D3DBLEND d3dSrcBlend, d3dDestBlend;
|
---|
| 1294 |
|
---|
| 1295 | D3DBLEND* pBlend = &d3dSrcBlend;
|
---|
| 1296 | SceneBlendFactor ogreBlend = sourceFactor;
|
---|
| 1297 |
|
---|
| 1298 | for (int i = 0 ; i < 2; ++i)
|
---|
| 1299 | {
|
---|
| 1300 | switch(ogreBlend)
|
---|
| 1301 | {
|
---|
| 1302 | case SBF_ONE:
|
---|
| 1303 | *pBlend = D3DBLEND_ONE;
|
---|
| 1304 | break;
|
---|
| 1305 | case SBF_ZERO:
|
---|
| 1306 | *pBlend = D3DBLEND_ZERO;
|
---|
| 1307 | break;
|
---|
| 1308 | case SBF_DEST_COLOUR:
|
---|
| 1309 | *pBlend = D3DBLEND_DESTCOLOR;
|
---|
| 1310 | break;
|
---|
| 1311 | case SBF_SOURCE_COLOUR:
|
---|
| 1312 | *pBlend = D3DBLEND_SRCCOLOR;
|
---|
| 1313 | break;
|
---|
| 1314 | case SBF_ONE_MINUS_DEST_COLOUR:
|
---|
| 1315 | *pBlend = D3DBLEND_INVDESTCOLOR;
|
---|
| 1316 | break;
|
---|
| 1317 | case SBF_ONE_MINUS_SOURCE_COLOUR:
|
---|
| 1318 | *pBlend = D3DBLEND_INVSRCCOLOR;
|
---|
| 1319 | break;
|
---|
| 1320 | case SBF_DEST_ALPHA:
|
---|
| 1321 | *pBlend = D3DBLEND_DESTALPHA;
|
---|
| 1322 | break;
|
---|
| 1323 | case SBF_SOURCE_ALPHA:
|
---|
| 1324 | *pBlend = D3DBLEND_SRCALPHA;
|
---|
| 1325 | break;
|
---|
| 1326 | case SBF_ONE_MINUS_DEST_ALPHA:
|
---|
| 1327 | *pBlend = D3DBLEND_INVDESTALPHA;
|
---|
| 1328 | break;
|
---|
| 1329 | case SBF_ONE_MINUS_SOURCE_ALPHA:
|
---|
| 1330 | *pBlend = D3DBLEND_INVSRCALPHA;
|
---|
| 1331 | break;
|
---|
| 1332 | }
|
---|
| 1333 | ogreBlend = destFactor;
|
---|
| 1334 | pBlend = &d3dDestBlend;
|
---|
| 1335 |
|
---|
| 1336 | }
|
---|
| 1337 |
|
---|
| 1338 | hr = __SetRenderState(D3DRENDERSTATE_SRCBLEND, d3dSrcBlend);
|
---|
| 1339 |
|
---|
| 1340 | hr = __SetRenderState(D3DRENDERSTATE_DESTBLEND, d3dDestBlend);
|
---|
| 1341 |
|
---|
| 1342 | // Save last scene blend, because colour write off is simulated
|
---|
| 1343 | // through scene blend
|
---|
| 1344 | mSavedDestFactor = destFactor;
|
---|
| 1345 | mSavedSrcFactor = sourceFactor;
|
---|
| 1346 |
|
---|
| 1347 |
|
---|
| 1348 | }
|
---|
| 1349 | //-----------------------------------------------------------------------
|
---|
| 1350 | void D3DRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value)
|
---|
| 1351 | {
|
---|
| 1352 | HRESULT hr;
|
---|
| 1353 | if (func != CMPF_ALWAYS_PASS)
|
---|
| 1354 | {
|
---|
| 1355 | if( FAILED( hr = __SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, TRUE ) ) )
|
---|
| 1356 | OGRE_EXCEPT( hr, "Failed to enable alpha testing",
|
---|
| 1357 | "D3DRenderSystem::_setAlphaRejectSettings" );
|
---|
| 1358 | }
|
---|
| 1359 | else
|
---|
| 1360 | {
|
---|
| 1361 | if( FAILED( hr = __SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, FALSE ) ) )
|
---|
| 1362 | OGRE_EXCEPT( hr, "Failed to disable alpha testing",
|
---|
| 1363 | "D3DRenderSystem::_setAlphaRejectSettings" );
|
---|
| 1364 | }
|
---|
| 1365 |
|
---|
| 1366 | // Set always just be sure
|
---|
| 1367 | hr = __SetRenderState(D3DRENDERSTATE_ALPHAFUNC,
|
---|
| 1368 | convertCompareFunction(func));
|
---|
| 1369 |
|
---|
| 1370 | hr = __SetRenderState(D3DRENDERSTATE_ALPHAREF, value);
|
---|
| 1371 | }
|
---|
| 1372 | //-----------------------------------------------------------------------
|
---|
| 1373 | void D3DRenderSystem::_setViewport(Viewport *vp)
|
---|
| 1374 | {
|
---|
| 1375 | if (mDeviceLost)
|
---|
| 1376 | return;
|
---|
| 1377 |
|
---|
| 1378 | // Check if viewport is different
|
---|
| 1379 | if (vp != mActiveViewport || vp->_isUpdated())
|
---|
| 1380 | {
|
---|
| 1381 | mActiveViewport = vp;
|
---|
| 1382 | mActiveRenderTarget = vp->getTarget();
|
---|
| 1383 | // Ok, it's different. Time to set render target (maybe)
|
---|
| 1384 | // and viewport params.
|
---|
| 1385 | D3DVIEWPORT7 d3dvp;
|
---|
| 1386 | HRESULT hr;
|
---|
| 1387 |
|
---|
| 1388 | // Set render target
|
---|
| 1389 | // TODO - maybe only set when required?
|
---|
| 1390 | RenderTarget* target;
|
---|
| 1391 | target = vp->getTarget();
|
---|
| 1392 | // Get DD Back buffer
|
---|
| 1393 | LPDIRECTDRAWSURFACE7 pBack;
|
---|
| 1394 | target->getCustomAttribute("DDBACKBUFFER", &pBack);
|
---|
| 1395 | if (pBack->IsLost())
|
---|
| 1396 | {
|
---|
| 1397 | _notifyDeviceLost();
|
---|
| 1398 | return;
|
---|
| 1399 | }
|
---|
| 1400 |
|
---|
| 1401 | hr = mlpD3DDevice->SetRenderTarget( pBack, 0 );
|
---|
| 1402 |
|
---|
| 1403 | _setCullingMode( mCullingMode );
|
---|
| 1404 |
|
---|
| 1405 | // Set viewport dimensions
|
---|
| 1406 | d3dvp.dwX = vp->getActualLeft();
|
---|
| 1407 | d3dvp.dwY = vp->getActualTop();
|
---|
| 1408 | d3dvp.dwWidth = vp->getActualWidth();
|
---|
| 1409 | d3dvp.dwHeight = vp->getActualHeight();
|
---|
| 1410 |
|
---|
| 1411 | // Z-values from 0.0 to 1.0 (TODO - standardise with OpenGL?)
|
---|
| 1412 | d3dvp.dvMinZ = 0.0f;
|
---|
| 1413 | d3dvp.dvMaxZ = 1.0f;
|
---|
| 1414 |
|
---|
| 1415 | hr = mlpD3DDevice->SetViewport(&d3dvp);
|
---|
| 1416 |
|
---|
| 1417 | if (FAILED(hr))
|
---|
| 1418 | OGRE_EXCEPT(hr, "Error setting D3D viewport.",
|
---|
| 1419 | "D3DRenderSystem::_setViewport");
|
---|
| 1420 |
|
---|
| 1421 | vp->_clearUpdatedFlag();
|
---|
| 1422 |
|
---|
| 1423 | }
|
---|
| 1424 | }
|
---|
| 1425 |
|
---|
| 1426 | //-----------------------------------------------------------------------
|
---|
| 1427 | void D3DRenderSystem::_beginFrame(void)
|
---|
| 1428 | {
|
---|
| 1429 | OgreGuard( "D3DRenderSystem::_beginFrame" );
|
---|
| 1430 |
|
---|
| 1431 | HRESULT hr;
|
---|
| 1432 |
|
---|
| 1433 | // Device lost from somewhere outside?
|
---|
| 1434 | if (mDeviceLost)
|
---|
| 1435 | {
|
---|
| 1436 | _restoreLostDevice();
|
---|
| 1437 | if (mDeviceLost)
|
---|
| 1438 | return; // try later
|
---|
| 1439 | }
|
---|
| 1440 |
|
---|
| 1441 | if (!mActiveViewport)
|
---|
| 1442 | OGRE_EXCEPT(999, "Cannot begin frame - no viewport selected.",
|
---|
| 1443 | "D3DRenderSystem::_beginFrame");
|
---|
| 1444 |
|
---|
| 1445 | // Clear the viewport if required
|
---|
| 1446 | if (mActiveViewport->getClearEveryFrame())
|
---|
| 1447 | {
|
---|
| 1448 | clearFrameBuffer(FBT_COLOUR | FBT_DEPTH,
|
---|
| 1449 | mActiveViewport->getBackgroundColour());
|
---|
| 1450 | }
|
---|
| 1451 |
|
---|
| 1452 | hr = mlpD3DDevice->BeginScene();
|
---|
| 1453 | if (FAILED(hr))
|
---|
| 1454 | {
|
---|
| 1455 | if (hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY)
|
---|
| 1456 | {
|
---|
| 1457 | _notifyDeviceLost();
|
---|
| 1458 | _restoreLostDevice();
|
---|
| 1459 | if (mDeviceLost)
|
---|
| 1460 | return; // try later
|
---|
| 1461 |
|
---|
| 1462 | if (FAILED(hr = mlpD3DDevice->BeginScene()))
|
---|
| 1463 | OGRE_EXCEPT(hr, "Error beginning frame after device restore: "
|
---|
| 1464 | + getErrorDescription(hr),
|
---|
| 1465 | "D3DRenderSystem::_beginFrame");
|
---|
| 1466 | }
|
---|
| 1467 | else
|
---|
| 1468 | {
|
---|
| 1469 | OGRE_EXCEPT(hr, "Error beginning frame: " + getErrorDescription(hr),
|
---|
| 1470 | "D3DRenderSystem::_beginFrame");
|
---|
| 1471 | }
|
---|
| 1472 | }
|
---|
| 1473 |
|
---|
| 1474 | // Moved here from _render, no point checking every rendering call
|
---|
| 1475 | static bool firstTime = true;
|
---|
| 1476 | if (firstTime)
|
---|
| 1477 | {
|
---|
| 1478 | // First-time setup
|
---|
| 1479 | // Set up some defaults
|
---|
| 1480 |
|
---|
| 1481 | // Allow alpha blending
|
---|
| 1482 | hr = __SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
|
---|
| 1483 | if (FAILED(hr))
|
---|
| 1484 | OGRE_EXCEPT(hr, "Error enabling alpha blending option.",
|
---|
| 1485 | "D3DRenderSystem::_beginFrame");
|
---|
| 1486 |
|
---|
| 1487 | // Allow specular effects
|
---|
| 1488 | hr = __SetRenderState(D3DRENDERSTATE_SPECULARENABLE, TRUE);
|
---|
| 1489 | if (FAILED(hr))
|
---|
| 1490 | OGRE_EXCEPT(hr, "Error enabling specular option.",
|
---|
| 1491 | "D3DRenderSystem::_beginFrame");
|
---|
| 1492 |
|
---|
| 1493 | firstTime = false;
|
---|
| 1494 | }
|
---|
| 1495 |
|
---|
| 1496 | OgreUnguard();
|
---|
| 1497 | }
|
---|
| 1498 |
|
---|
| 1499 | //-----------------------------------------------------------------------
|
---|
| 1500 | void D3DRenderSystem::_render(const RenderOperation& op)
|
---|
| 1501 | {
|
---|
| 1502 | OgreGuard( "D3DRenderSystem::_render" );
|
---|
| 1503 | HRESULT hr;
|
---|
| 1504 |
|
---|
| 1505 | if (mDeviceLost)
|
---|
| 1506 | return;
|
---|
| 1507 |
|
---|
| 1508 | // Exit immediately if there is nothing to render
|
---|
| 1509 | // Passing 0 arguments causes problems for Direct3D
|
---|
| 1510 | if (op.vertexData->vertexCount == 0 ||
|
---|
| 1511 | (op.useIndexes && op.indexData->indexCount == 0))
|
---|
| 1512 | return;
|
---|
| 1513 |
|
---|
| 1514 | // call superclass
|
---|
| 1515 | RenderSystem::_render(op);
|
---|
| 1516 | // Set up vertex flags
|
---|
| 1517 | DWORD d3dVertexFormat = 0;
|
---|
| 1518 | unsigned int numTexCoords = 0;
|
---|
| 1519 |
|
---|
| 1520 | // Assume no more than 10 buffers!
|
---|
| 1521 | static unsigned char* pBufPtrs[10];
|
---|
| 1522 |
|
---|
| 1523 | // Lock all the buffers first
|
---|
| 1524 | // They're system memory buffers anyway
|
---|
| 1525 | const VertexBufferBinding::VertexBufferBindingMap binds =
|
---|
| 1526 | op.vertexData->vertexBufferBinding->getBindings();
|
---|
| 1527 | VertexBufferBinding::VertexBufferBindingMap::const_iterator bindi, bindend;
|
---|
| 1528 | bindend = binds.end();
|
---|
| 1529 | for (bindi = binds.begin(); bindi != bindend; ++bindi)
|
---|
| 1530 | {
|
---|
| 1531 | // lock from vertex start only
|
---|
| 1532 | pBufPtrs[bindi->first] = static_cast<unsigned char*>(
|
---|
| 1533 | bindi->second->lock(
|
---|
| 1534 | op.vertexData->vertexStart * bindi->second->getVertexSize(),
|
---|
| 1535 | op.vertexData->vertexCount * bindi->second->getVertexSize(),
|
---|
| 1536 | HardwareBuffer::HBL_READ_ONLY)
|
---|
| 1537 | );
|
---|
| 1538 |
|
---|
| 1539 | }
|
---|
| 1540 |
|
---|
| 1541 | // Determine vertex format
|
---|
| 1542 |
|
---|
| 1543 | // Struct for data pointers
|
---|
| 1544 | D3DDRAWPRIMITIVESTRIDEDDATA strideData;
|
---|
| 1545 |
|
---|
| 1546 | // Iterate over elements
|
---|
| 1547 | VertexDeclaration::VertexElementList::const_iterator elemi, elemend;
|
---|
| 1548 | const VertexDeclaration::VertexElementList elems =
|
---|
| 1549 | op.vertexData->vertexDeclaration->getElements();
|
---|
| 1550 | elemend = elems.end();
|
---|
| 1551 | for (elemi = elems.begin(); elemi != elemend; ++elemi)
|
---|
| 1552 | {
|
---|
| 1553 | // Get a few basic details
|
---|
| 1554 | const VertexElement& elem = *elemi;
|
---|
| 1555 | unsigned short source = elem.getSource();
|
---|
| 1556 | size_t vertexSize = op.vertexData->vertexDeclaration->getVertexSize(source);
|
---|
| 1557 | size_t offset = elem.getOffset();
|
---|
| 1558 | // semantic-specific stuff
|
---|
| 1559 | switch (elem.getSemantic())
|
---|
| 1560 | {
|
---|
| 1561 | case VES_POSITION:
|
---|
| 1562 | d3dVertexFormat |= D3DFVF_XYZ; // Untransformed
|
---|
| 1563 | strideData.position.lpvData = pBufPtrs[source] + offset;
|
---|
| 1564 | strideData.position.dwStride = static_cast<DWORD>(vertexSize);
|
---|
| 1565 | // Set up pointer
|
---|
| 1566 | break;
|
---|
| 1567 | case VES_NORMAL:
|
---|
| 1568 | d3dVertexFormat |= D3DFVF_NORMAL;
|
---|
| 1569 | strideData.normal.lpvData = pBufPtrs[source] + offset;
|
---|
| 1570 | strideData.normal.dwStride = static_cast<DWORD>(vertexSize);
|
---|
| 1571 | break;
|
---|
| 1572 | case VES_DIFFUSE:
|
---|
| 1573 | d3dVertexFormat |= D3DFVF_DIFFUSE;
|
---|
| 1574 | strideData.diffuse.lpvData = pBufPtrs[source] + offset;
|
---|
| 1575 | strideData.diffuse.dwStride = static_cast<DWORD>(vertexSize);
|
---|
| 1576 | break;
|
---|
| 1577 | case VES_SPECULAR:
|
---|
| 1578 | d3dVertexFormat |= D3DFVF_SPECULAR;
|
---|
| 1579 | strideData.specular.lpvData = pBufPtrs[source] + offset;
|
---|
| 1580 | strideData.specular.dwStride = static_cast<DWORD>(vertexSize);
|
---|
| 1581 | break;
|
---|
| 1582 | case VES_TEXTURE_COORDINATES:
|
---|
| 1583 | // texcoords must go in order
|
---|
| 1584 | if (elem.getIndex() != numTexCoords)
|
---|
| 1585 | {
|
---|
| 1586 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid vertex format, texture coordinates"
|
---|
| 1587 | " must be in order wih no gaps.", "D3DRenderSystem::_render");
|
---|
| 1588 | }
|
---|
| 1589 | // Don't add D3DFVF_TEXn flag here, wait until we know how many total
|
---|
| 1590 | // However, specify size
|
---|
| 1591 | switch (elem.getType())
|
---|
| 1592 | {
|
---|
| 1593 | case VET_FLOAT1:
|
---|
| 1594 | d3dVertexFormat |= D3DFVF_TEXCOORDSIZE1(numTexCoords);
|
---|
| 1595 | break;
|
---|
| 1596 | case VET_FLOAT2:
|
---|
| 1597 | d3dVertexFormat |= D3DFVF_TEXCOORDSIZE2(numTexCoords);
|
---|
| 1598 | break;
|
---|
| 1599 | case VET_FLOAT3:
|
---|
| 1600 | d3dVertexFormat |= D3DFVF_TEXCOORDSIZE3(numTexCoords);
|
---|
| 1601 | break;
|
---|
| 1602 | case VET_FLOAT4:
|
---|
| 1603 | d3dVertexFormat |= D3DFVF_TEXCOORDSIZE4(numTexCoords);
|
---|
| 1604 | break;
|
---|
| 1605 | }
|
---|
| 1606 |
|
---|
| 1607 | strideData.textureCoords[numTexCoords].lpvData = pBufPtrs[source] + offset;
|
---|
| 1608 | strideData.textureCoords[numTexCoords].dwStride = static_cast<DWORD>(vertexSize);
|
---|
| 1609 |
|
---|
| 1610 | // Increment number of coords
|
---|
| 1611 | ++numTexCoords;
|
---|
| 1612 | }
|
---|
| 1613 |
|
---|
| 1614 | }
|
---|
| 1615 | // Add combined texture flag
|
---|
| 1616 | switch(numTexCoords)
|
---|
| 1617 | {
|
---|
| 1618 | case 0:
|
---|
| 1619 | // do nothing
|
---|
| 1620 | break;
|
---|
| 1621 | case 1:
|
---|
| 1622 | d3dVertexFormat |= D3DFVF_TEX1;
|
---|
| 1623 | break;
|
---|
| 1624 | case 2:
|
---|
| 1625 | d3dVertexFormat |= D3DFVF_TEX2;
|
---|
| 1626 | break;
|
---|
| 1627 | case 3:
|
---|
| 1628 | d3dVertexFormat |= D3DFVF_TEX3;
|
---|
| 1629 | break;
|
---|
| 1630 | case 4:
|
---|
| 1631 | d3dVertexFormat |= D3DFVF_TEX4;
|
---|
| 1632 | break;
|
---|
| 1633 | case 5:
|
---|
| 1634 | d3dVertexFormat |= D3DFVF_TEX5;
|
---|
| 1635 | break;
|
---|
| 1636 | case 6:
|
---|
| 1637 | d3dVertexFormat |= D3DFVF_TEX6;
|
---|
| 1638 | break;
|
---|
| 1639 | case 7:
|
---|
| 1640 | d3dVertexFormat |= D3DFVF_TEX7;
|
---|
| 1641 | break;
|
---|
| 1642 | case 8:
|
---|
| 1643 | d3dVertexFormat |= D3DFVF_TEX8;
|
---|
| 1644 | break;
|
---|
| 1645 | }
|
---|
| 1646 |
|
---|
| 1647 | // Determine rendering operation
|
---|
| 1648 | D3DPRIMITIVETYPE primType;
|
---|
| 1649 | switch (op.operationType)
|
---|
| 1650 | {
|
---|
| 1651 | case RenderOperation::OT_POINT_LIST:
|
---|
| 1652 | primType = D3DPT_POINTLIST;
|
---|
| 1653 | break;
|
---|
| 1654 | case RenderOperation::OT_LINE_LIST:
|
---|
| 1655 | primType = D3DPT_LINELIST;
|
---|
| 1656 | break;
|
---|
| 1657 | case RenderOperation::OT_LINE_STRIP:
|
---|
| 1658 | primType = D3DPT_LINESTRIP;
|
---|
| 1659 | break;
|
---|
| 1660 | case RenderOperation::OT_TRIANGLE_LIST:
|
---|
| 1661 | primType = D3DPT_TRIANGLELIST;
|
---|
| 1662 | break;
|
---|
| 1663 | case RenderOperation::OT_TRIANGLE_STRIP:
|
---|
| 1664 | primType = D3DPT_TRIANGLESTRIP;
|
---|
| 1665 | break;
|
---|
| 1666 | case RenderOperation::OT_TRIANGLE_FAN:
|
---|
| 1667 | primType = D3DPT_TRIANGLEFAN;
|
---|
| 1668 | break;
|
---|
| 1669 | }
|
---|
| 1670 |
|
---|
| 1671 |
|
---|
| 1672 | if (op.useIndexes)
|
---|
| 1673 | {
|
---|
| 1674 | // Get pointer to index buffer
|
---|
| 1675 | // D3D7 only allows 16-bit indexes, this is enforced in buffer manager
|
---|
| 1676 | unsigned short* pIdx = static_cast<unsigned short*>(
|
---|
| 1677 | op.indexData->indexBuffer->lock(
|
---|
| 1678 | op.indexData->indexStart,
|
---|
| 1679 | op.indexData->indexCount * sizeof(unsigned short),
|
---|
| 1680 | HardwareBuffer::HBL_READ_ONLY) );
|
---|
| 1681 |
|
---|
| 1682 | hr = mlpD3DDevice->DrawIndexedPrimitiveStrided(primType,
|
---|
| 1683 | d3dVertexFormat,
|
---|
| 1684 | &strideData,
|
---|
| 1685 | static_cast<DWORD>(op.vertexData->vertexCount),
|
---|
| 1686 | pIdx,
|
---|
| 1687 | static_cast<DWORD>(op.indexData->indexCount)
|
---|
| 1688 | , 0);
|
---|
| 1689 | }
|
---|
| 1690 | else
|
---|
| 1691 | {
|
---|
| 1692 | hr = mlpD3DDevice->DrawPrimitiveStrided(primType,
|
---|
| 1693 | d3dVertexFormat,
|
---|
| 1694 | &strideData,
|
---|
| 1695 | static_cast<DWORD>(op.vertexData->vertexCount),
|
---|
| 1696 | 0);
|
---|
| 1697 | }
|
---|
| 1698 |
|
---|
| 1699 | // unlock buffers
|
---|
| 1700 | for (bindi = binds.begin(); bindi != bindend; ++bindi)
|
---|
| 1701 | {
|
---|
| 1702 | bindi->second->unlock();
|
---|
| 1703 | }
|
---|
| 1704 |
|
---|
| 1705 | // Ignore errors - lost device issues can occur late in RTTs
|
---|
| 1706 |
|
---|
| 1707 |
|
---|
| 1708 |
|
---|
| 1709 | OgreUnguard();
|
---|
| 1710 | }
|
---|
| 1711 |
|
---|
| 1712 | //-----------------------------------------------------------------------
|
---|
| 1713 | void D3DRenderSystem::_endFrame(void)
|
---|
| 1714 | {
|
---|
| 1715 | OgreGuard( "D3DRenderSystem::_endFrame" );
|
---|
| 1716 |
|
---|
| 1717 | if (mDeviceLost)
|
---|
| 1718 | {
|
---|
| 1719 | // Don't allow until next begin that restores
|
---|
| 1720 | return;
|
---|
| 1721 | }
|
---|
| 1722 |
|
---|
| 1723 | HRESULT hr;
|
---|
| 1724 | hr = mlpD3DDevice->EndScene();
|
---|
| 1725 |
|
---|
| 1726 | if (FAILED(hr))
|
---|
| 1727 | {
|
---|
| 1728 | if (hr == DDERR_SURFACELOST)
|
---|
| 1729 | {
|
---|
| 1730 | // Device lost
|
---|
| 1731 | _notifyDeviceLost();
|
---|
| 1732 | }
|
---|
| 1733 | else
|
---|
| 1734 | {
|
---|
| 1735 | // ignore other errors, may not find out about device lost
|
---|
| 1736 | // early enough in RTT situation
|
---|
| 1737 | }
|
---|
| 1738 | }
|
---|
| 1739 |
|
---|
| 1740 | OgreUnguard();
|
---|
| 1741 | }
|
---|
| 1742 | //-----------------------------------------------------------------------
|
---|
| 1743 | void D3DRenderSystem::_notifyDeviceLost(void)
|
---|
| 1744 | {
|
---|
| 1745 | LogManager::getSingleton().logMessage("!!! Direct3D Device Lost!");
|
---|
| 1746 | mDeviceLost = true;
|
---|
| 1747 |
|
---|
| 1748 | fireEvent("DeviceLost");
|
---|
| 1749 | }
|
---|
| 1750 | //-----------------------------------------------------------------------
|
---|
| 1751 | void D3DRenderSystem::_restoreLostDevice(void)
|
---|
| 1752 | {
|
---|
| 1753 | HRESULT hr = mActiveDDDriver->directDraw()->TestCooperativeLevel();
|
---|
| 1754 | if (SUCCEEDED(hr))
|
---|
| 1755 | {
|
---|
| 1756 | _restoreSurfaces();
|
---|
| 1757 | }
|
---|
| 1758 | else if (hr == DDERR_WRONGMODE)
|
---|
| 1759 | {
|
---|
| 1760 | // display mode change
|
---|
| 1761 | _recreateContext();
|
---|
| 1762 | }
|
---|
| 1763 | else if (hr == DDERR_EXCLUSIVEMODEALREADYSET)
|
---|
| 1764 | {
|
---|
| 1765 | // This means that some app took exclusive mode access
|
---|
| 1766 | // we need to sit in a loop till we get back to the right mode.
|
---|
| 1767 | do
|
---|
| 1768 | {
|
---|
| 1769 | Sleep(1000);
|
---|
| 1770 | }
|
---|
| 1771 | while (DDERR_EXCLUSIVEMODEALREADYSET == (hr = mActiveDDDriver->directDraw()->TestCooperativeLevel()));
|
---|
| 1772 | if (SUCCEEDED(hr))
|
---|
| 1773 | {
|
---|
| 1774 | // This means that the exclusive mode app relinquished its
|
---|
| 1775 | // control and we are back to the safe mode, so simply restore.
|
---|
| 1776 | _restoreSurfaces();
|
---|
| 1777 | }
|
---|
| 1778 | else if (hr == DDERR_WRONGMODE)
|
---|
| 1779 | {
|
---|
| 1780 | // This means that the exclusive mode app relinquished its
|
---|
| 1781 | // control BUT we are back to some strange mode, so destroy
|
---|
| 1782 | // and recreate.
|
---|
| 1783 | _recreateContext();
|
---|
| 1784 | }
|
---|
| 1785 | else
|
---|
| 1786 | {
|
---|
| 1787 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
|
---|
| 1788 | getErrorDescription(hr),
|
---|
| 1789 | "D3DRenderSystem::_restoreLostDevice");
|
---|
| 1790 | }
|
---|
| 1791 | }
|
---|
| 1792 | else if (hr == DDERR_NOEXCLUSIVEMODE)
|
---|
| 1793 | {
|
---|
| 1794 | // Not sure what to do here, it tends to fix itself after a few tries.
|
---|
| 1795 | return;
|
---|
| 1796 | }
|
---|
| 1797 | else
|
---|
| 1798 | {
|
---|
| 1799 | // Some other error has occurred which we haven't handled.
|
---|
| 1800 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
|
---|
| 1801 | getErrorDescription(hr),
|
---|
| 1802 | "D3DRenderSystem::_restoreLostDevice");
|
---|
| 1803 | }
|
---|
| 1804 |
|
---|
| 1805 | LogManager::getSingleton().logMessage("!!! Direct3D Device successfully restored.");
|
---|
| 1806 | mDeviceLost = false;
|
---|
| 1807 | fireEvent("DeviceRestored");
|
---|
| 1808 | }
|
---|
| 1809 | //-----------------------------------------------------------------------------
|
---|
| 1810 | void D3DRenderSystem::_restoreSurfaces(void)
|
---|
| 1811 | {
|
---|
| 1812 | HRESULT hr = mActiveDDDriver->directDraw()->RestoreAllSurfaces();
|
---|
| 1813 | if (FAILED(hr))
|
---|
| 1814 | {
|
---|
| 1815 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
|
---|
| 1816 | getErrorDescription(hr),
|
---|
| 1817 | "D3DRenderSystem::_restoreLostDevice");
|
---|
| 1818 | }
|
---|
| 1819 |
|
---|
| 1820 | // Need to reload all textures since surfaces are now blank
|
---|
| 1821 | static_cast<D3DTextureManager*>(mTextureManager)
|
---|
| 1822 | ->reloadAfterLostDevice();
|
---|
| 1823 |
|
---|
| 1824 | }
|
---|
| 1825 | //-----------------------------------------------------------------------------
|
---|
| 1826 | void D3DRenderSystem::_recreateContext(void)
|
---|
| 1827 | {
|
---|
| 1828 | // restore primary render window if fullscreen
|
---|
| 1829 | for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
|
---|
| 1830 | {
|
---|
| 1831 | RenderTarget* rt = i->second;
|
---|
| 1832 | if (rt->isPrimary())
|
---|
| 1833 | {
|
---|
| 1834 | D3D7RenderWindow* d3dwin = static_cast<D3D7RenderWindow*>(rt);
|
---|
| 1835 | d3dwin->releaseDDSurfaces();
|
---|
| 1836 | d3dwin->createDDSurfaces();
|
---|
| 1837 | d3dwin->createDepthBuffer();
|
---|
| 1838 | break;
|
---|
| 1839 | }
|
---|
| 1840 | }
|
---|
| 1841 | }
|
---|
| 1842 | //-----------------------------------------------------------------------
|
---|
| 1843 | void D3DRenderSystem::_setCullingMode(CullingMode mode)
|
---|
| 1844 | {
|
---|
| 1845 | HRESULT hr;
|
---|
| 1846 | DWORD d3dMode;
|
---|
| 1847 |
|
---|
| 1848 | mCullingMode = mode;
|
---|
| 1849 |
|
---|
| 1850 | if (mode == CULL_NONE)
|
---|
| 1851 | {
|
---|
| 1852 | d3dMode = D3DCULL_NONE;
|
---|
| 1853 | }
|
---|
| 1854 | else if( mode == CULL_CLOCKWISE )
|
---|
| 1855 | {
|
---|
| 1856 | if( (mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
|
---|
| 1857 | (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding))
|
---|
| 1858 | d3dMode = D3DCULL_CCW;
|
---|
| 1859 | else
|
---|
| 1860 | d3dMode = D3DCULL_CW;
|
---|
| 1861 | }
|
---|
| 1862 | else if (mode == CULL_ANTICLOCKWISE)
|
---|
| 1863 | {
|
---|
| 1864 | if( (mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
|
---|
| 1865 | (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding))
|
---|
| 1866 | d3dMode = D3DCULL_CW;
|
---|
| 1867 | else
|
---|
| 1868 | d3dMode = D3DCULL_CCW;
|
---|
| 1869 | }
|
---|
| 1870 |
|
---|
| 1871 | hr = __SetRenderState(D3DRENDERSTATE_CULLMODE, d3dMode);
|
---|
| 1872 | if (FAILED(hr))
|
---|
| 1873 | OGRE_EXCEPT(hr, "Unable to set D3D culling mode.",
|
---|
| 1874 | "D3DRenderSystem::_setCullingMode");
|
---|
| 1875 |
|
---|
| 1876 | }
|
---|
| 1877 |
|
---|
| 1878 | //-----------------------------------------------------------------------
|
---|
| 1879 | void D3DRenderSystem::_setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
|
---|
| 1880 | {
|
---|
| 1881 | _setDepthBufferCheckEnabled(depthTest);
|
---|
| 1882 | _setDepthBufferWriteEnabled(depthWrite);
|
---|
| 1883 | _setDepthBufferFunction(depthFunction);
|
---|
| 1884 |
|
---|
| 1885 | }
|
---|
| 1886 | //-----------------------------------------------------------------------
|
---|
| 1887 | void D3DRenderSystem::_setDepthBufferCheckEnabled(bool enabled)
|
---|
| 1888 | {
|
---|
| 1889 | HRESULT hr;
|
---|
| 1890 |
|
---|
| 1891 | if (enabled)
|
---|
| 1892 | {
|
---|
| 1893 | // Use w-buffer if available and enabled
|
---|
| 1894 | if (mWBuffer && mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_WBUFFER)
|
---|
| 1895 | hr = __SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_USEW);
|
---|
| 1896 | else
|
---|
| 1897 | hr = __SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
|
---|
| 1898 | if (FAILED(hr))
|
---|
| 1899 | OGRE_EXCEPT(hr, "Error setting depth buffer test state.",
|
---|
| 1900 | "D3DRenderSystem::_setDepthBufferCheckEnabled");
|
---|
| 1901 | }
|
---|
| 1902 | else
|
---|
| 1903 | {
|
---|
| 1904 | hr = __SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
|
---|
| 1905 | if (FAILED(hr))
|
---|
| 1906 | OGRE_EXCEPT(hr, "Error setting depth buffer test state.",
|
---|
| 1907 | "D3DRenderSystem::_setDepthBufferCheckEnabled");
|
---|
| 1908 | }
|
---|
| 1909 | }
|
---|
| 1910 | //-----------------------------------------------------------------------
|
---|
| 1911 | void D3DRenderSystem::_setDepthBufferWriteEnabled(bool enabled)
|
---|
| 1912 | {
|
---|
| 1913 | HRESULT hr;
|
---|
| 1914 |
|
---|
| 1915 | hr = __SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, enabled);
|
---|
| 1916 | if (FAILED(hr))
|
---|
| 1917 | OGRE_EXCEPT(hr, "Error setting depth buffer write state.",
|
---|
| 1918 | "D3DRenderSystem::_setDepthBufferWriteEnabled");
|
---|
| 1919 | }
|
---|
| 1920 | //-----------------------------------------------------------------------
|
---|
| 1921 | void D3DRenderSystem::_setDepthBufferFunction(CompareFunction func)
|
---|
| 1922 | {
|
---|
| 1923 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_ZFUNC,
|
---|
| 1924 | convertCompareFunction(func));
|
---|
| 1925 | if (FAILED(hr))
|
---|
| 1926 | OGRE_EXCEPT(hr, "Error setting depth buffer test function.",
|
---|
| 1927 | "D3DRenderSystem::_setDepthBufferFunction");
|
---|
| 1928 | }
|
---|
| 1929 | //-----------------------------------------------------------------------
|
---|
| 1930 | void D3DRenderSystem::_setDepthBias(ushort bias)
|
---|
| 1931 | {
|
---|
| 1932 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_ZBIAS,
|
---|
| 1933 | bias);
|
---|
| 1934 | if (FAILED(hr))
|
---|
| 1935 | OGRE_EXCEPT(hr, "Error setting depth bias.",
|
---|
| 1936 | "D3DRenderSystem::_setDepthBias");
|
---|
| 1937 | }
|
---|
| 1938 | //-----------------------------------------------------------------------
|
---|
| 1939 | String D3DRenderSystem::getErrorDescription(long errCode) const
|
---|
| 1940 | {
|
---|
| 1941 | char* errDesc;
|
---|
| 1942 | DWORD i;
|
---|
| 1943 |
|
---|
| 1944 | errDesc = new char[255];
|
---|
| 1945 | // Try windows errors first
|
---|
| 1946 | i = FormatMessage(
|
---|
| 1947 | FORMAT_MESSAGE_FROM_HMODULE |
|
---|
| 1948 | FORMAT_MESSAGE_FROM_SYSTEM |
|
---|
| 1949 | FORMAT_MESSAGE_IGNORE_INSERTS,
|
---|
| 1950 | NULL,
|
---|
| 1951 | DDERR_SURFACELOST,
|
---|
| 1952 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
---|
| 1953 | (LPTSTR) errDesc,
|
---|
| 1954 | 255,
|
---|
| 1955 | NULL
|
---|
| 1956 | );
|
---|
| 1957 |
|
---|
| 1958 |
|
---|
| 1959 | if (i == 0)
|
---|
| 1960 | {
|
---|
| 1961 | // Not found in windows message descriptions
|
---|
| 1962 | switch (errCode)
|
---|
| 1963 | {
|
---|
| 1964 | case DD_OK:
|
---|
| 1965 | strcpy(errDesc, "DD_OK: The request completed successfully.");
|
---|
| 1966 | break;
|
---|
| 1967 | case DDERR_ALREADYINITIALIZED:
|
---|
| 1968 | strcpy(errDesc, "DDERR_ALREADYINITIALIZED: The object has already been initialized.");
|
---|
| 1969 | break;
|
---|
| 1970 | case DDERR_BLTFASTCANTCLIP :
|
---|
| 1971 | strcpy(errDesc, "DDERR_BLTFASTCANTCLIP: A DirectDrawClipper object is attached to a source surface that has passed into a call to the IDirectDrawSurface7::BltFast method.");
|
---|
| 1972 | break;
|
---|
| 1973 | case DDERR_CANNOTATTACHSURFACE:
|
---|
| 1974 | strcpy(errDesc, "DDERR_CANNOTATTACHSURFACE: A surface cannot be attached to another requested surface.");
|
---|
| 1975 | break;
|
---|
| 1976 | case DDERR_CANNOTDETACHSURFACE:
|
---|
| 1977 | strcpy(errDesc, "DDERR_CANNOTATTACHSURFACE: A surface cannot be detached from another requested surface.");
|
---|
| 1978 | break;
|
---|
| 1979 | case DDERR_CANTCREATEDC:
|
---|
| 1980 | 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.");
|
---|
| 1981 | break;
|
---|
| 1982 | case DDERR_CANTDUPLICATE:
|
---|
| 1983 | strcpy(errDesc, "DDERR_CANTDUPLICATE: Primary and 3-D surfaces, or surfaces that are implicitly created, cannot be duplicated.");
|
---|
| 1984 | break;
|
---|
| 1985 | case DDERR_CANTLOCKSURFACE:
|
---|
| 1986 | strcpy(errDesc, "DDERR_CANTLOCKSURFACE: Access to this surface is refused because an attempt was made to lock the primary surface without DCI support.");
|
---|
| 1987 | break;
|
---|
| 1988 | case DDERR_CANTPAGELOCK:
|
---|
| 1989 | 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.");
|
---|
| 1990 | break;
|
---|
| 1991 | case DDERR_CANTPAGEUNLOCK:
|
---|
| 1992 | 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.");
|
---|
| 1993 | break;
|
---|
| 1994 | case DDERR_CLIPPERISUSINGHWND:
|
---|
| 1995 | strcpy(errDesc, "DDERR_CLIPPERISUSINGHWND: An attempt was made to set a clip list for a DirectDrawClipper object that is already monitoring a window handle.");
|
---|
| 1996 | break;
|
---|
| 1997 | case DDERR_COLORKEYNOTSET:
|
---|
| 1998 | strcpy(errDesc, "DDERR_COLORKEYNOTSET: No source color key is specified for this operation.");
|
---|
| 1999 | break;
|
---|
| 2000 | case DDERR_CURRENTLYNOTAVAIL:
|
---|
| 2001 | strcpy(errDesc, "DDERR_CURRENTLYNOTAVAIL: No support is currently available.");
|
---|
| 2002 | break;
|
---|
| 2003 | case DDERR_DCALREADYCREATED:
|
---|
| 2004 | strcpy(errDesc, "DDERR_DCALREADYCREATED: A device context (DC) has already been returned for this surface. Only one DC can be retrieved for each surface.");
|
---|
| 2005 | break;
|
---|
| 2006 | case DDERR_DEVICEDOESNTOWNSURFACE:
|
---|
| 2007 | strcpy(errDesc, "DDERR_DEVICEDOESNTOWNSURFACE: Surfaces created by one DirectDraw device cannot be used directly by another DirectDraw device.");
|
---|
| 2008 | break;
|
---|
| 2009 | case DDERR_DIRECTDRAWALREADYCREATED:
|
---|
| 2010 | strcpy(errDesc, "DDERR_DIRECTDRAWALREADYCREATED: A DirectDraw object representing this driver has already been created for this process.");
|
---|
| 2011 | break;
|
---|
| 2012 | case DDERR_EXCEPTION:
|
---|
| 2013 | strcpy(errDesc, "DDERR_EXCEPTION: An exception was encountered while performing the requested operation.");
|
---|
| 2014 | break;
|
---|
| 2015 | case DDERR_EXCLUSIVEMODEALREADYSET:
|
---|
| 2016 | strcpy(errDesc, "DDERR_EXCLUSIVEMODEALREADYSET: An attempt was made to set the cooperative level when it was already set to exclusive.");
|
---|
| 2017 | break;
|
---|
| 2018 | case DDERR_EXPIRED:
|
---|
| 2019 | strcpy(errDesc, "DDERR_EXPIRED: The data has expired and is therefore no longer valid.");
|
---|
| 2020 | break;
|
---|
| 2021 | case DDERR_GENERIC:
|
---|
| 2022 | strcpy(errDesc, "DDERR_GENERIC: There is an undefined error condition.");
|
---|
| 2023 | break;
|
---|
| 2024 | case DDERR_HEIGHTALIGN:
|
---|
| 2025 | strcpy(errDesc, "DDERR_HEIGHTALIGN: The height of the provided rectangle is not a multiple of the required alignment.");
|
---|
| 2026 | break;
|
---|
| 2027 | case DDERR_HWNDALREADYSET:
|
---|
| 2028 | 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.");
|
---|
| 2029 | break;
|
---|
| 2030 | case DDERR_HWNDSUBCLASSED:
|
---|
| 2031 | strcpy(errDesc, "DDERR_HWNDSUBCLASSED: DirectDraw is prevented from restoring state because the DirectDraw cooperative level window handle has been subclassed.");
|
---|
| 2032 | break;
|
---|
| 2033 | case DDERR_IMPLICITLYCREATED:
|
---|
| 2034 | strcpy(errDesc, "DDERR_IMPLICITLYCREATED: The surface cannot be restored because it is an implicitly created surface.");
|
---|
| 2035 | break;
|
---|
| 2036 | case DDERR_INCOMPATIBLEPRIMARY:
|
---|
| 2037 | strcpy(errDesc, "DDERR_INCOMPATIBLEPRIMARY: The primary surface creation request does not match with the existing primary surface.");
|
---|
| 2038 | break;
|
---|
| 2039 | case DDERR_INVALIDCAPS:
|
---|
| 2040 | strcpy(errDesc, "DDERR_INVALIDCAPS: One or more of the capability bits passed to the callback function are incorrect.");
|
---|
| 2041 | break;
|
---|
| 2042 | case DDERR_INVALIDCLIPLIST:
|
---|
| 2043 | strcpy(errDesc, "DDERR_INVALIDCLIPLIST: DirectDraw does not support the provided clip list.");
|
---|
| 2044 | break;
|
---|
| 2045 | case DDERR_INVALIDDIRECTDRAWGUID:
|
---|
| 2046 | strcpy(errDesc, "DDERR_INVALIDDIRECTDRAWGUID: The globally unique identifier (GUID) passed to the DirectDrawCreate function is not a valid DirectDraw driver identifier.");
|
---|
| 2047 | break;
|
---|
| 2048 | case DDERR_INVALIDMODE:
|
---|
| 2049 | strcpy(errDesc, "DDERR_INVALIDMODE: DirectDraw does not support the requested mode.");
|
---|
| 2050 | break;
|
---|
| 2051 | case DDERR_INVALIDOBJECT:
|
---|
| 2052 | strcpy(errDesc, "DDERR_INVALIDOBJECT: DirectDraw received a pointer that was an invalid DirectDraw object.");
|
---|
| 2053 | break;
|
---|
| 2054 | case DDERR_INVALIDPARAMS:
|
---|
| 2055 | strcpy(errDesc, "DDERR_INVALIDPARAMS: One or more of the parameters passed to the method are incorrect.");
|
---|
| 2056 | break;
|
---|
| 2057 | case DDERR_INVALIDPIXELFORMAT:
|
---|
| 2058 | strcpy(errDesc, "DDERR_INVALIDPIXELFORMAT: The pixel format was invalid as specified.");
|
---|
| 2059 | break;
|
---|
| 2060 | case DDERR_INVALIDPOSITION:
|
---|
| 2061 | strcpy(errDesc, "DDERR_INVALIDPOSITION: The position of the overlay on the destination is no longer legal.");
|
---|
| 2062 | break;
|
---|
| 2063 | case DDERR_INVALIDRECT:
|
---|
| 2064 | strcpy(errDesc, "DDERR_INVALIDRECT: The provided rectangle was invalid.");
|
---|
| 2065 | break;
|
---|
| 2066 | case DDERR_INVALIDSTREAM:
|
---|
| 2067 | strcpy(errDesc, "DDERR_INVALIDSTREAM: The specified stream contains invalid data.");
|
---|
| 2068 | break;
|
---|
| 2069 | case DDERR_INVALIDSURFACETYPE:
|
---|
| 2070 | strcpy(errDesc, "DDERR_INVALIDSURFACETYPE: The requested operation could not be performed because the surface was of the wrong type.");
|
---|
| 2071 | break;
|
---|
| 2072 | case DDERR_LOCKEDSURFACES:
|
---|
| 2073 | strcpy(errDesc, "DDERR_LOCKEDSURFACES: One or more surfaces are locked, causing the failure of the requested operation.");
|
---|
| 2074 | break;
|
---|
| 2075 | case DDERR_MOREDATA:
|
---|
| 2076 | strcpy(errDesc, "DDERR_MOREDATA: There is more data available than the specified buffer size can hold.");
|
---|
| 2077 | break;
|
---|
| 2078 | case DDERR_NO3D:
|
---|
| 2079 | strcpy(errDesc, "DDERR_NO3D: No 3-D hardware or emulation is present.");
|
---|
| 2080 | break;
|
---|
| 2081 | case DDERR_NOALPHAHW:
|
---|
| 2082 | strcpy(errDesc, "DDERR_NOALPHAHW: No alpha acceleration hardware is present or available, causing the failure of the requested operation.");
|
---|
| 2083 | break;
|
---|
| 2084 | case DDERR_NOBLTHW:
|
---|
| 2085 | strcpy(errDesc, "DDERR_NOBLTHW: No blitter hardware is present.");
|
---|
| 2086 | break;
|
---|
| 2087 | case DDERR_NOCLIPLIST:
|
---|
| 2088 | strcpy(errDesc, "DDERR_NOCLIPLIST: No clip list is available.");
|
---|
| 2089 | break;
|
---|
| 2090 | case DDERR_NOCLIPPERATTACHED:
|
---|
| 2091 | strcpy(errDesc, "DDERR_NOCLIPPERATTACHED: No DirectDrawClipper object is attached to the surface object.");
|
---|
| 2092 | break;
|
---|
| 2093 | case DDERR_NOCOLORCONVHW:
|
---|
| 2094 | strcpy(errDesc, "DDERR_NOCOLORCONVHW: The operation cannot be carried out because no color-conversion hardware is present or available.");
|
---|
| 2095 | break;
|
---|
| 2096 | case DDERR_NOCOLORKEY:
|
---|
| 2097 | strcpy(errDesc, "DDERR_NOCOLORKEY: The surface does not currently have a color key.");
|
---|
| 2098 | break;
|
---|
| 2099 | case DDERR_NOCOLORKEYHW:
|
---|
| 2100 | strcpy(errDesc, "DDERR_NOCOLORKEYHW: The operation cannot be carried out because there is no hardware support for the destination color key.");
|
---|
| 2101 | break;
|
---|
| 2102 | case DDERR_NOCOOPERATIVELEVELSET:
|
---|
| 2103 | strcpy(errDesc, "DDERR_NOCOOPERATIVELEVELSET: A create function is called without the IDirectDraw7::SetCooperativeLevel method being called.");
|
---|
| 2104 | break;
|
---|
| 2105 | case DDERR_NODC:
|
---|
| 2106 | strcpy(errDesc, "DDERR_NODC: No DC has ever been created for this surface.");
|
---|
| 2107 | break;
|
---|
| 2108 | case DDERR_NODDROPSHW:
|
---|
| 2109 | strcpy(errDesc, "DDERR_NODDROPSHW: No DirectDraw raster operation (ROP) hardware is available.");
|
---|
| 2110 | break;
|
---|
| 2111 | case DDERR_NODIRECTDRAWHW:
|
---|
| 2112 | strcpy(errDesc, "DDERR_NODIRECTDRAWHW: Hardware-only DirectDraw object creation is not possible; the driver does not support any hardware.");
|
---|
| 2113 | break;
|
---|
| 2114 | case DDERR_NODIRECTDRAWSUPPORT:
|
---|
| 2115 | strcpy(errDesc, "DDERR_NODIRECTDRAWSUPPORT: DirectDraw support is not possible with the current display driver.");
|
---|
| 2116 | break;
|
---|
| 2117 | case DDERR_NOEMULATION:
|
---|
| 2118 | strcpy(errDesc, "DDERR_NOEMULATION: Software emulation is not available.");
|
---|
| 2119 | break;
|
---|
| 2120 | case DDERR_NOEXCLUSIVEMODE:
|
---|
| 2121 | strcpy(errDesc, "DDERR_NOEXCLUSIVEMODE: The operation requires the application to have exclusive mode, but the application does not have exclusive mode.");
|
---|
| 2122 | break;
|
---|
| 2123 | case DDERR_NOFLIPHW:
|
---|
| 2124 | strcpy(errDesc, "DDERR_NOFLIPHW: Flipping visible surfaces is not supported.");
|
---|
| 2125 | break;
|
---|
| 2126 | case DDERR_NOFOCUSWINDOW:
|
---|
| 2127 | strcpy(errDesc, "DDERR_NOFOCUSWINDOW: An attempt was made to create or set a device window without first setting the focus window.");
|
---|
| 2128 | break;
|
---|
| 2129 | case DDERR_NOGDI:
|
---|
| 2130 | strcpy(errDesc, "DDERR_NOGDI: No GDI is present.");
|
---|
| 2131 | break;
|
---|
| 2132 | case DDERR_NOHWND:
|
---|
| 2133 | strcpy(errDesc, "DDERR_NOHWND: Clipper notification requires a window handle, or no window handle has been previously set as the cooperative level window handle.");
|
---|
| 2134 | break;
|
---|
| 2135 | case DDERR_NOMIPMAPHW:
|
---|
| 2136 | strcpy(errDesc, "DDERR_NOMIPMAPHW: The operation cannot be carried out because no mipmap capable texture mapping hardware is present or available.");
|
---|
| 2137 | break;
|
---|
| 2138 | case DDERR_NOMIRRORHW:
|
---|
| 2139 | strcpy(errDesc, "DDERR_NOMIRRORHW: The operation cannot be carried out because no mirroring hardware is present or available.");
|
---|
| 2140 | break;
|
---|
| 2141 | case DDERR_NONONLOCALVIDMEM:
|
---|
| 2142 | 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.");
|
---|
| 2143 | break;
|
---|
| 2144 | case DDERR_NOOPTIMIZEHW:
|
---|
| 2145 | strcpy(errDesc, "DDERR_NOOPTIMIZEHW: The device does not support optimized surfaces.");
|
---|
| 2146 | break;
|
---|
| 2147 | case DDERR_NOOVERLAYDEST:
|
---|
| 2148 | 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.");
|
---|
| 2149 | break;
|
---|
| 2150 | case DDERR_NOOVERLAYHW:
|
---|
| 2151 | strcpy(errDesc, "DDERR_NOOVERLAYHW: The operation cannot be carried out because no overlay hardware is present or available.");
|
---|
| 2152 | break;
|
---|
| 2153 | case DDERR_NOPALETTEATTACHED:
|
---|
| 2154 | strcpy(errDesc, "DDERR_NOPALETTEATTACHED: No palette object is attached to this surface.");
|
---|
| 2155 | break;
|
---|
| 2156 | case DDERR_NOPALETTEHW:
|
---|
| 2157 | strcpy(errDesc, "DDERR_NOPALETTEHW: There is no hardware support for 16- or 256-color palettes.");
|
---|
| 2158 | break;
|
---|
| 2159 | case DDERR_NORASTEROPHW:
|
---|
| 2160 | strcpy(errDesc, "DDERR_NORASTEROPHW: The operation cannot be carried out because no appropriate raster operation hardware is present or available.");
|
---|
| 2161 | break;
|
---|
| 2162 | case DDERR_NOROTATIONHW:
|
---|
| 2163 | strcpy(errDesc, "DDERR_NOROTATIONHW: The operation cannot be carried out because no rotation hardware is present or available.");
|
---|
| 2164 | break;
|
---|
| 2165 | case DDERR_NOSTRETCHHW:
|
---|
| 2166 | strcpy(errDesc, "DDERR_NOSTRETCHHW: The operation cannot be carried out because there is no hardware support for stretching.");
|
---|
| 2167 | break;
|
---|
| 2168 | case DDERR_NOT4BITCOLOR:
|
---|
| 2169 | 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.");
|
---|
| 2170 | break;
|
---|
| 2171 | case DDERR_NOT4BITCOLORINDEX:
|
---|
| 2172 | 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.");
|
---|
| 2173 | break;
|
---|
| 2174 | case DDERR_NOT8BITCOLOR:
|
---|
| 2175 | 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.");
|
---|
| 2176 | break;
|
---|
| 2177 | case DDERR_NOTAOVERLAYSURFACE:
|
---|
| 2178 | strcpy(errDesc, "DDERR_NOTAOVERLAYSURFACE: An overlay component is called for a non-overlay surface.");
|
---|
| 2179 | break;
|
---|
| 2180 | case DDERR_NOTEXTUREHW:
|
---|
| 2181 | strcpy(errDesc, "DDERR_NOTEXTUREHW: The operation cannot be carried out because no texture-mapping hardware is present or available.");
|
---|
| 2182 | break;
|
---|
| 2183 | case DDERR_NOTFLIPPABLE:
|
---|
| 2184 | strcpy(errDesc, "DDERR_NOTFLIPPABLE: An attempt has been made to flip a surface that cannot be flipped.");
|
---|
| 2185 | break;
|
---|
| 2186 | case DDERR_NOTFOUND:
|
---|
| 2187 | strcpy(errDesc, "DDERR_NOTFOUND: The requested item was not found.");
|
---|
| 2188 | break;
|
---|
| 2189 | case DDERR_NOTINITIALIZED:
|
---|
| 2190 | 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.");
|
---|
| 2191 | break;
|
---|
| 2192 | case DDERR_NOTLOADED:
|
---|
| 2193 | strcpy(errDesc, "DDERR_NOTLOADED: The surface is an optimized surface, but it has not yet been allocated any memory.");
|
---|
| 2194 | break;
|
---|
| 2195 | case DDERR_NOTLOCKED:
|
---|
| 2196 | strcpy(errDesc, "DDERR_NOTLOCKED: An attempt is made to unlock a surface that was not locked.");
|
---|
| 2197 | break;
|
---|
| 2198 | case DDERR_NOTPAGELOCKED:
|
---|
| 2199 | strcpy(errDesc, "DDERR_NOTPAGELOCKED: An attempt is made to page unlock a surface with no outstanding page locks.");
|
---|
| 2200 | break;
|
---|
| 2201 | case DDERR_NOTPALETTIZED:
|
---|
| 2202 | strcpy(errDesc, "DDERR_NOTPALETTIZED: The surface being used is not a palette-based surface.");
|
---|
| 2203 | break;
|
---|
| 2204 | case DDERR_NOVSYNCHW:
|
---|
| 2205 | strcpy(errDesc, "DDERR_NOVSYNCHW: The operation cannot be carried out because there is no hardware support for vertical blank synchronized operations.");
|
---|
| 2206 | break;
|
---|
| 2207 | case DDERR_NOZBUFFERHW:
|
---|
| 2208 | 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.");
|
---|
| 2209 | break;
|
---|
| 2210 | case DDERR_NOZOVERLAYHW:
|
---|
| 2211 | 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.");
|
---|
| 2212 | break;
|
---|
| 2213 | case DDERR_OUTOFCAPS:
|
---|
| 2214 | strcpy(errDesc, "DDERR_OUTOFCAPS: The hardware needed for the requested operation has already been allocated.");
|
---|
| 2215 | break;
|
---|
| 2216 | case DDERR_OUTOFMEMORY:
|
---|
| 2217 | strcpy(errDesc, "DDERR_OUTOFMEMORY: DirectDraw does not have enough memory to perform the operation.");
|
---|
| 2218 | break;
|
---|
| 2219 | case DDERR_OUTOFVIDEOMEMORY:
|
---|
| 2220 | strcpy(errDesc, "DDERR_OUTOFVIDEOMEMORY: DirectDraw does not have enough display memory to perform the operation.");
|
---|
| 2221 | break;
|
---|
| 2222 | case DDERR_OVERLAPPINGRECTS:
|
---|
| 2223 | 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.");
|
---|
| 2224 | break;
|
---|
| 2225 | case DDERR_OVERLAYCANTCLIP:
|
---|
| 2226 | strcpy(errDesc, "DDERR_OVERLAYCANTCLIP: The hardware does not support clipped overlays.");
|
---|
| 2227 | break;
|
---|
| 2228 | case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:
|
---|
| 2229 | strcpy(errDesc, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE: An attempt was made to have more than one color key active on an overlay.");
|
---|
| 2230 | break;
|
---|
| 2231 | case DDERR_OVERLAYNOTVISIBLE:
|
---|
| 2232 | strcpy(errDesc, "DDERR_OVERLAYNOTVISIBLE: The IDirectDrawSurface7::GetOverlayPosition method is called on a hidden overlay.");
|
---|
| 2233 | break;
|
---|
| 2234 | case DDERR_PALETTEBUSY:
|
---|
| 2235 | strcpy(errDesc, "DDERR_PALETTEBUSY: Access to this palette is refused because the palette is locked by another thread.");
|
---|
| 2236 | break;
|
---|
| 2237 | case DDERR_PRIMARYSURFACEALREADYEXISTS:
|
---|
| 2238 | strcpy(errDesc, "DDERR_PRIMARYSURFACEALREADYEXISTS: This process has already created a primary surface.");
|
---|
| 2239 | break;
|
---|
| 2240 | case DDERR_REGIONTOOSMALL:
|
---|
| 2241 | strcpy(errDesc, "DDERR_REGIONTOOSMALL: The region passed to the IDirectDrawClipper::GetClipList method is too small.");
|
---|
| 2242 | break;
|
---|
| 2243 | case DDERR_SURFACEALREADYATTACHED:
|
---|
| 2244 | strcpy(errDesc, "DDERR_SURFACEALREADYATTACHED: An attempt was made to attach a surface to another surface to which it is already attached.");
|
---|
| 2245 | break;
|
---|
| 2246 | case DDERR_SURFACEALREADYDEPENDENT:
|
---|
| 2247 | strcpy(errDesc, "DDERR_SURFACEALREADYDEPENDENT: An attempt was made to make a surface a dependency of another surface to which it is already dependent.");
|
---|
| 2248 | break;
|
---|
| 2249 | case DDERR_SURFACEBUSY:
|
---|
| 2250 | strcpy(errDesc, "DDERR_SURFACEBUSY: Access to the surface is refused because the surface is locked by another thread.");
|
---|
| 2251 | break;
|
---|
| 2252 | case DDERR_SURFACEISOBSCURED:
|
---|
| 2253 | strcpy(errDesc, "DDERR_SURFACEISOBSCURED: Access to the surface is refused because the surface is obscured.");
|
---|
| 2254 | break;
|
---|
| 2255 | case DDERR_SURFACELOST:
|
---|
| 2256 | 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.");
|
---|
| 2257 | break;
|
---|
| 2258 | case DDERR_SURFACENOTATTACHED:
|
---|
| 2259 | strcpy(errDesc, "DDERR_SURFACENOTATTACHED: The requested surface is not attached.");
|
---|
| 2260 | break;
|
---|
| 2261 | case DDERR_TOOBIGHEIGHT:
|
---|
| 2262 | strcpy(errDesc, "DDERR_TOOBIGHEIGHT: The height requested by DirectDraw is too large.");
|
---|
| 2263 | break;
|
---|
| 2264 | case DDERR_TOOBIGSIZE:
|
---|
| 2265 | strcpy(errDesc, "DDERR_TOOBIGSIZE: The size requested by DirectDraw is too large. However, the individual height and width are valid sizes.");
|
---|
| 2266 | break;
|
---|
| 2267 | case DDERR_TOOBIGWIDTH:
|
---|
| 2268 | strcpy(errDesc, "DDERR_TOOBIGWIDTH: The width requested by DirectDraw is too large.");
|
---|
| 2269 | break;
|
---|
| 2270 | case DDERR_UNSUPPORTED:
|
---|
| 2271 | strcpy(errDesc, "DDERR_UNSUPPORTED: The operation is not supported.");
|
---|
| 2272 | break;
|
---|
| 2273 | case DDERR_UNSUPPORTEDFORMAT:
|
---|
| 2274 | strcpy(errDesc, "DDERR_UNSUPPORTEDFORMAT: The FourCC format requested is not supported by DirectDraw.");
|
---|
| 2275 | break;
|
---|
| 2276 | case DDERR_UNSUPPORTEDMASK:
|
---|
| 2277 | strcpy(errDesc, "DDERR_UNSUPPORTEDMASK: The bitmask in the pixel format requested is not supported by DirectDraw.");
|
---|
| 2278 | break;
|
---|
| 2279 | case DDERR_UNSUPPORTEDMODE:
|
---|
| 2280 | strcpy(errDesc, "DDERR_UNSUPPORTEDMODE: The display is currently in an unsupported mode.");
|
---|
| 2281 | break;
|
---|
| 2282 | case DDERR_VERTICALBLANKINPROGRESS:
|
---|
| 2283 | strcpy(errDesc, "DDERR_VERTICALBLANKINPROGRESS: A vertical blank is in progress.");
|
---|
| 2284 | break;
|
---|
| 2285 | case DDERR_VIDEONOTACTIVE:
|
---|
| 2286 | strcpy(errDesc, "DDERR_VIDEONOTACTIVE: The video port is not active.");
|
---|
| 2287 | break;
|
---|
| 2288 | case DDERR_WASSTILLDRAWING:
|
---|
| 2289 | strcpy(errDesc, "DDERR_WASSTILLDRAWING: The previous blit operation that is transferring information to or from this surface is incomplete.");
|
---|
| 2290 | break;
|
---|
| 2291 | case DDERR_WRONGMODE:
|
---|
| 2292 | strcpy(errDesc, "DDERR_WRONGMODE: This surface cannot be restored because it was created in a different mode.");
|
---|
| 2293 | break;
|
---|
| 2294 | case DDERR_XALIGN:
|
---|
| 2295 | strcpy(errDesc, "DDERR_XALIGN: The provided rectangle was not horizontally aligned on a required boundary.");
|
---|
| 2296 | break;
|
---|
| 2297 | default:
|
---|
| 2298 | strcpy(errDesc, "Unknown error code.");
|
---|
| 2299 | }
|
---|
| 2300 | }
|
---|
| 2301 | return errDesc;
|
---|
| 2302 | }
|
---|
| 2303 |
|
---|
| 2304 | /*
|
---|
| 2305 | D3D_OK
|
---|
| 2306 | D3DERR_BADMAJORVERSION
|
---|
| 2307 | D3DERR_BADMINORVERSION
|
---|
| 2308 | D3DERR_COLORKEYATTACHED
|
---|
| 2309 | D3DERR_CONFLICTINGTEXTUREFILTER
|
---|
| 2310 | D3DERR_CONFLICTINGTEXTUREPALETTE
|
---|
| 2311 | D3DERR_CONFLICTINGRENDERSTATE
|
---|
| 2312 | D3DERR_DEVICEAGGREGATED (new for DirectX 5.0)
|
---|
| 2313 | D3DERR_EXECUTE_CLIPPED_FAILED
|
---|
| 2314 | D3DERR_EXECUTE_CREATE_FAILED
|
---|
| 2315 | D3DERR_EXECUTE_DESTROY_FAILED
|
---|
| 2316 | D3DERR_EXECUTE_FAILED
|
---|
| 2317 | D3DERR_EXECUTE_LOCK_FAILED
|
---|
| 2318 | D3DERR_EXECUTE_LOCKED
|
---|
| 2319 | D3DERR_EXECUTE_NOT_LOCKED
|
---|
| 2320 | D3DERR_EXECUTE_UNLOCK_FAILED
|
---|
| 2321 | D3DERR_INITFAILED (new for DirectX 5.0)
|
---|
| 2322 | D3DERR_INBEGIN (new for DirectX 5.0)
|
---|
| 2323 | D3DERR_INVALID_DEVICE (new for DirectX 5.0)
|
---|
| 2324 | D3DERR_INVALIDCURRENTVIEWPORT (new for DirectX 5.0)
|
---|
| 2325 | D3DERR_INVALIDMATRIX
|
---|
| 2326 | D3DERR_INVALIDPALETTE(new for DirectX 5.0)
|
---|
| 2327 | D3DERR_INVALIDPRIMITIVETYPE (new for DirectX 5.0)
|
---|
| 2328 | D3DERR_INVALIDRAMPTEXTURE (new for DirectX 5.0)
|
---|
| 2329 | D3DERR_INVALIDVERTEXFORMAT (new for DirectX 6.0)
|
---|
| 2330 | D3DERR_INVALIDVERTEXTYPE (new for DirectX 5.0)
|
---|
| 2331 | D3DERR_LIGHT_SET_FAILED
|
---|
| 2332 | D3DERR_LIGHTHASVIEWPORT (new for DirectX 5.0)
|
---|
| 2333 | D3DERR_LIGHTNOTINTHISVIEWPORT (new for DirectX 5.0)
|
---|
| 2334 | D3DERR_MATERIAL_CREATE_FAILED
|
---|
| 2335 | D3DERR_MATERIAL_DESTROY_FAILED
|
---|
| 2336 | D3DERR_MATERIAL_GETDATA_FAILED
|
---|
| 2337 | D3DERR_MATERIAL_SETDATA_FAILED
|
---|
| 2338 | D3DERR_MATRIX_CREATE_FAILED
|
---|
| 2339 | D3DERR_MATRIX_DESTROY_FAILED
|
---|
| 2340 | D3DERR_MATRIX_GETDATA_FAILED
|
---|
| 2341 | D3DERR_MATRIX_SETDATA_FAILED
|
---|
| 2342 | D3DERR_NOCURRENTVIEWPORT (new for DirectX 5.0)
|
---|
| 2343 | D3DERR_NOTINBEGIN (new for DirectX 5.0)
|
---|
| 2344 | D3DERR_NOVIEWPORTS (new for DirectX 5.0)
|
---|
| 2345 | D3DERR_SCENE_BEGIN_FAILED
|
---|
| 2346 | D3DERR_SCENE_END_FAILED
|
---|
| 2347 | D3DERR_SCENE_IN_SCENE
|
---|
| 2348 | D3DERR_SCENE_NOT_IN_SCENE
|
---|
| 2349 | D3DERR_SETVIEWPORTDATA_FAILED
|
---|
| 2350 | D3DERR_STENCILBUFFER_NOTPRESENT
|
---|
| 2351 | D3DERR_SURFACENOTINVIDMEM (new for DirectX 5.0)
|
---|
| 2352 | D3DERR_TEXTURE_BADSIZE (new for DirectX 5.0)
|
---|
| 2353 | D3DERR_TEXTURE_CREATE_FAILED
|
---|
| 2354 | D3DERR_TEXTURE_DESTROY_FAILED
|
---|
| 2355 | D3DERR_TEXTURE_GETSURF_FAILED
|
---|
| 2356 | D3DERR_TEXTURE_LOAD_FAILED
|
---|
| 2357 | D3DERR_TEXTURE_LOCK_FAILED
|
---|
| 2358 | D3DERR_TEXTURE_LOCKED
|
---|
| 2359 | D3DERR_TEXTURE_NO_SUPPORT
|
---|
| 2360 | D3DERR_TEXTURE_NOT_LOCKED
|
---|
| 2361 | D3DERR_TEXTURE_SWAP_FAILED
|
---|
| 2362 | D3DERR_TEXTURE_UNLOCK_FAILED
|
---|
| 2363 | D3DERR_TOOMANYOPERATIONS
|
---|
| 2364 | D3DERR_TOOMANYPRIMITIVES
|
---|
| 2365 | D3DERR_UNSUPPORTEDALPHAARG
|
---|
| 2366 | D3DERR_UNSUPPORTEDALPHAOPERATION
|
---|
| 2367 | D3DERR_UNSUPPORTEDCOLORARG
|
---|
| 2368 | D3DERR_UNSUPPORTEDCOLOROPERATION
|
---|
| 2369 | D3DERR_UNSUPPORTEDFACTORVALUE
|
---|
| 2370 | D3DERR_UNSUPPORTEDTEXTUREFILTER
|
---|
| 2371 | D3DERR_VBUF_CREATE_FAILED
|
---|
| 2372 | D3DERR_VERTEXBUFFERLOCKED
|
---|
| 2373 | D3DERR_VERTEXBUFFEROPTIMIZED
|
---|
| 2374 | D3DERR_VIEWPORTDATANOTSET (new for DirectX 5.0)
|
---|
| 2375 | D3DERR_VIEWPORTHASNODEVICE (new for DirectX 5.0)
|
---|
| 2376 | D3DERR_WRONGTEXTUREFORMAT
|
---|
| 2377 | D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY (new for DirectX 5.0)
|
---|
| 2378 | D3DERR_ZBUFF_NEEDS_VIDEOMEMORY (new for DirectX 5.0)
|
---|
| 2379 | D3DERR_ZBUFFER_NOTPRESENT
|
---|
| 2380 | */
|
---|
| 2381 |
|
---|
| 2382 | //-----------------------------------------------------------------------
|
---|
| 2383 | DDDriverList* D3DRenderSystem::getDirectDrawDrivers(void)
|
---|
| 2384 | {
|
---|
| 2385 | if (!mDriverList)
|
---|
| 2386 | {
|
---|
| 2387 | mDriverList = new DDDriverList;
|
---|
| 2388 | }
|
---|
| 2389 |
|
---|
| 2390 | return mDriverList;
|
---|
| 2391 | }
|
---|
| 2392 | //-----------------------------------------------------------------------
|
---|
| 2393 | void D3DRenderSystem::setLightingEnabled(bool enabled)
|
---|
| 2394 | {
|
---|
| 2395 | // Call D3D
|
---|
| 2396 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_LIGHTING, enabled);
|
---|
| 2397 | if (FAILED(hr))
|
---|
| 2398 | OGRE_EXCEPT(hr, "Error lighting status.", "D3DRenderSystem::setLightingEnabled");
|
---|
| 2399 | }
|
---|
| 2400 | //-----------------------------------------------------------------------
|
---|
| 2401 | void D3DRenderSystem::_setFog(FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
|
---|
| 2402 | {
|
---|
| 2403 | HRESULT hr;
|
---|
| 2404 |
|
---|
| 2405 | D3DRENDERSTATETYPE fogType, fogTypeNot;
|
---|
| 2406 |
|
---|
| 2407 | if (mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE)
|
---|
| 2408 | {
|
---|
| 2409 | fogType = D3DRENDERSTATE_FOGTABLEMODE;
|
---|
| 2410 | fogTypeNot = D3DRENDERSTATE_FOGVERTEXMODE;
|
---|
| 2411 | }
|
---|
| 2412 | else
|
---|
| 2413 | {
|
---|
| 2414 | fogType = D3DRENDERSTATE_FOGVERTEXMODE;
|
---|
| 2415 | fogTypeNot = D3DRENDERSTATE_FOGTABLEMODE;
|
---|
| 2416 | }
|
---|
| 2417 |
|
---|
| 2418 | if( mode == FOG_NONE)
|
---|
| 2419 | {
|
---|
| 2420 | // just disable
|
---|
| 2421 | hr = __SetRenderState(fogType, D3DFOG_NONE );
|
---|
| 2422 | hr = __SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE);
|
---|
| 2423 | }
|
---|
| 2424 | else
|
---|
| 2425 | {
|
---|
| 2426 | // Allow fog
|
---|
| 2427 | hr = __SetRenderState( D3DRENDERSTATE_FOGENABLE, TRUE );
|
---|
| 2428 | hr = __SetRenderState( fogTypeNot, D3DFOG_NONE );
|
---|
| 2429 | switch(mode)
|
---|
| 2430 | {
|
---|
| 2431 | case FOG_EXP:
|
---|
| 2432 | hr = __SetRenderState( fogType, D3DFOG_EXP);
|
---|
| 2433 | break;
|
---|
| 2434 | case FOG_EXP2:
|
---|
| 2435 | hr = __SetRenderState( fogType, D3DFOG_EXP2);
|
---|
| 2436 | break;
|
---|
| 2437 | case FOG_LINEAR:
|
---|
| 2438 | hr = __SetRenderState( fogType, D3DFOG_LINEAR);
|
---|
| 2439 | break;
|
---|
| 2440 |
|
---|
| 2441 | }
|
---|
| 2442 |
|
---|
| 2443 | hr = __SetRenderState( D3DRENDERSTATE_FOGCOLOR, colour.getAsARGB() );
|
---|
| 2444 | hr = __SetRenderState( D3DRENDERSTATE_FOGSTART, *((LPDWORD)(&start)) );
|
---|
| 2445 | hr = __SetRenderState( D3DRENDERSTATE_FOGEND, *((LPDWORD)(&end)) );
|
---|
| 2446 | hr = __SetRenderState( D3DRENDERSTATE_FOGDENSITY, *((LPDWORD)(&density)) );
|
---|
| 2447 | }
|
---|
| 2448 |
|
---|
| 2449 |
|
---|
| 2450 | }
|
---|
| 2451 |
|
---|
| 2452 | //---------------------------------------------------------------------
|
---|
| 2453 | void D3DRenderSystem::convertColourValue(const ColourValue& colour, uint32* pDest)
|
---|
| 2454 | {
|
---|
| 2455 | *pDest = colour.getAsARGB();
|
---|
| 2456 | }
|
---|
| 2457 | //---------------------------------------------------------------------
|
---|
| 2458 | void D3DRenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect,
|
---|
| 2459 | Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram)
|
---|
| 2460 | {
|
---|
| 2461 | Radian theta(fovy * 0.5);
|
---|
| 2462 | Real h = 1 / Math::Tan(theta);
|
---|
| 2463 | Real w = h / aspect;
|
---|
| 2464 | Real q, qn;
|
---|
| 2465 | if (farPlane == 0)
|
---|
| 2466 | {
|
---|
| 2467 | q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST;
|
---|
| 2468 | qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1);
|
---|
| 2469 | }
|
---|
| 2470 | else
|
---|
| 2471 | {
|
---|
| 2472 | q = farPlane / ( farPlane - nearPlane );
|
---|
| 2473 | qn = -q * nearPlane;
|
---|
| 2474 | }
|
---|
| 2475 |
|
---|
| 2476 | dest = Matrix4::ZERO;
|
---|
| 2477 | dest[0][0] = w;
|
---|
| 2478 | dest[1][1] = h;
|
---|
| 2479 |
|
---|
| 2480 | if (forGpuProgram)
|
---|
| 2481 | {
|
---|
| 2482 | dest[2][2] = -q;
|
---|
| 2483 | dest[3][2] = -1.0f;
|
---|
| 2484 | }
|
---|
| 2485 | else
|
---|
| 2486 | {
|
---|
| 2487 | dest[2][2] = q;
|
---|
| 2488 | dest[3][2] = 1.0f;
|
---|
| 2489 | }
|
---|
| 2490 |
|
---|
| 2491 | dest[2][3] = qn;
|
---|
| 2492 |
|
---|
| 2493 | }
|
---|
| 2494 | //---------------------------------------------------------------------
|
---|
| 2495 | void D3DRenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane,
|
---|
| 2496 | Matrix4& dest, bool forGpuProgram )
|
---|
| 2497 | {
|
---|
| 2498 | Radian thetaY (fovy / 2.0f);
|
---|
| 2499 | Real tanThetaY = Math::Tan(thetaY);
|
---|
| 2500 |
|
---|
| 2501 | //Real thetaX = thetaY * aspect;
|
---|
| 2502 | Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX);
|
---|
| 2503 | Real half_w = tanThetaX * nearPlane;
|
---|
| 2504 | Real half_h = tanThetaY * nearPlane;
|
---|
| 2505 | Real iw = 1.0 / half_w;
|
---|
| 2506 | Real ih = 1.0 / half_h;
|
---|
| 2507 | Real q;
|
---|
| 2508 | if (farPlane == 0)
|
---|
| 2509 | {
|
---|
| 2510 | q = 0;
|
---|
| 2511 | }
|
---|
| 2512 | else
|
---|
| 2513 | {
|
---|
| 2514 | q = 1.0 / (farPlane - nearPlane);
|
---|
| 2515 | }
|
---|
| 2516 |
|
---|
| 2517 | dest = Matrix4::ZERO;
|
---|
| 2518 | dest[0][0] = iw;
|
---|
| 2519 | dest[1][1] = ih;
|
---|
| 2520 | dest[2][2] = q;
|
---|
| 2521 | dest[2][3] = -nearPlane / (farPlane - nearPlane);
|
---|
| 2522 | dest[3][3] = 1;
|
---|
| 2523 |
|
---|
| 2524 | if (forGpuProgram)
|
---|
| 2525 | {
|
---|
| 2526 | dest[2][2] = -dest[2][2];
|
---|
| 2527 | }
|
---|
| 2528 | }
|
---|
| 2529 | //---------------------------------------------------------------------
|
---|
| 2530 | void D3DRenderSystem::_setRasterisationMode(SceneDetailLevel level)
|
---|
| 2531 | {
|
---|
| 2532 | D3DFILLMODE d3dmode;
|
---|
| 2533 |
|
---|
| 2534 | switch(level)
|
---|
| 2535 | {
|
---|
| 2536 | case SDL_POINTS:
|
---|
| 2537 | d3dmode = D3DFILL_POINT;
|
---|
| 2538 | break;
|
---|
| 2539 | case SDL_WIREFRAME:
|
---|
| 2540 | d3dmode = D3DFILL_WIREFRAME;
|
---|
| 2541 | break;
|
---|
| 2542 | case SDL_SOLID:
|
---|
| 2543 | d3dmode = D3DFILL_SOLID;
|
---|
| 2544 | break;
|
---|
| 2545 |
|
---|
| 2546 | }
|
---|
| 2547 |
|
---|
| 2548 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_FILLMODE, d3dmode);
|
---|
| 2549 | if (FAILED(hr))
|
---|
| 2550 | {
|
---|
| 2551 | OGRE_EXCEPT(hr, "Error setting rasterisation mode.",
|
---|
| 2552 | "D3DRenderSystem::setRasterisationMode");
|
---|
| 2553 | }
|
---|
| 2554 |
|
---|
| 2555 |
|
---|
| 2556 | }
|
---|
| 2557 | //---------------------------------------------------------------------
|
---|
| 2558 | void D3DRenderSystem::setStencilCheckEnabled(bool enabled)
|
---|
| 2559 | {
|
---|
| 2560 | // Allow stencilling
|
---|
| 2561 | HRESULT hr = __SetRenderState(D3DRENDERSTATE_STENCILENABLE, enabled);
|
---|
| 2562 | if (FAILED(hr))
|
---|
| 2563 | OGRE_EXCEPT(hr, "Error enabling / disabling stencilling.",
|
---|
| 2564 | "D3DRenderSystem::setStencilCheckEnabled");
|
---|
| 2565 |
|
---|
| 2566 | }
|
---|
| 2567 | //---------------------------------------------------------------------
|
---|
| 2568 | void D3DRenderSystem::setStencilBufferParams(CompareFunction func,
|
---|
| 2569 | uint32 refValue, uint32 mask, StencilOperation stencilFailOp,
|
---|
| 2570 | StencilOperation depthFailOp, StencilOperation passOp,
|
---|
| 2571 | bool twoSidedOperation)
|
---|
| 2572 | {
|
---|
| 2573 | HRESULT hr;
|
---|
| 2574 |
|
---|
| 2575 | // D3D7 does not support 2-sided stencil operations
|
---|
| 2576 | if (twoSidedOperation)
|
---|
| 2577 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Direct3D7 does not support 2-sided stencil ops",
|
---|
| 2578 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2579 |
|
---|
| 2580 | // Function
|
---|
| 2581 | hr = __SetRenderState(D3DRENDERSTATE_STENCILFUNC,
|
---|
| 2582 | convertCompareFunction(func));
|
---|
| 2583 |
|
---|
| 2584 | if (FAILED(hr))
|
---|
| 2585 | OGRE_EXCEPT(hr, "Error setting stencil buffer test function.",
|
---|
| 2586 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2587 |
|
---|
| 2588 | // reference value
|
---|
| 2589 | hr = __SetRenderState(D3DRENDERSTATE_STENCILREF, refValue);
|
---|
| 2590 | if (FAILED(hr))
|
---|
| 2591 | OGRE_EXCEPT(hr, "Error setting stencil buffer reference value.",
|
---|
| 2592 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2593 |
|
---|
| 2594 | // mask
|
---|
| 2595 | hr = __SetRenderState(D3DRENDERSTATE_STENCILMASK, mask);
|
---|
| 2596 | if (FAILED(hr))
|
---|
| 2597 | OGRE_EXCEPT(hr, "Error setting stencil buffer mask.",
|
---|
| 2598 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2599 |
|
---|
| 2600 | // fail op
|
---|
| 2601 | hr = __SetRenderState(D3DRENDERSTATE_STENCILFAIL,
|
---|
| 2602 | convertStencilOp(stencilFailOp));
|
---|
| 2603 | if (FAILED(hr))
|
---|
| 2604 | OGRE_EXCEPT(hr, "Error setting stencil fail operation.",
|
---|
| 2605 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2606 |
|
---|
| 2607 | // depth fail op
|
---|
| 2608 | hr = __SetRenderState(D3DRENDERSTATE_STENCILZFAIL,
|
---|
| 2609 | convertStencilOp(depthFailOp));
|
---|
| 2610 | if (FAILED(hr))
|
---|
| 2611 | OGRE_EXCEPT(hr, "Error setting stencil depth fail operation.",
|
---|
| 2612 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2613 |
|
---|
| 2614 | // pass op
|
---|
| 2615 | hr = __SetRenderState(D3DRENDERSTATE_STENCILPASS,
|
---|
| 2616 | convertStencilOp(passOp));
|
---|
| 2617 | if (FAILED(hr))
|
---|
| 2618 | OGRE_EXCEPT(hr, "Error setting stencil pass operation.",
|
---|
| 2619 | "D3DRenderSystem::setStencilBufferParams");
|
---|
| 2620 | }
|
---|
| 2621 | //---------------------------------------------------------------------
|
---|
| 2622 | D3DCMPFUNC D3DRenderSystem::convertCompareFunction(CompareFunction func)
|
---|
| 2623 | {
|
---|
| 2624 | switch(func)
|
---|
| 2625 | {
|
---|
| 2626 | case CMPF_ALWAYS_FAIL:
|
---|
| 2627 | return D3DCMP_NEVER;
|
---|
| 2628 | case CMPF_ALWAYS_PASS:
|
---|
| 2629 | return D3DCMP_ALWAYS;
|
---|
| 2630 | case CMPF_LESS:
|
---|
| 2631 | return D3DCMP_LESS;
|
---|
| 2632 | case CMPF_LESS_EQUAL:
|
---|
| 2633 | return D3DCMP_LESSEQUAL;
|
---|
| 2634 | case CMPF_EQUAL:
|
---|
| 2635 | return D3DCMP_EQUAL;
|
---|
| 2636 | case CMPF_NOT_EQUAL:
|
---|
| 2637 | return D3DCMP_NOTEQUAL;
|
---|
| 2638 | case CMPF_GREATER_EQUAL:
|
---|
| 2639 | return D3DCMP_GREATEREQUAL;
|
---|
| 2640 | case CMPF_GREATER:
|
---|
| 2641 | return D3DCMP_GREATER;
|
---|
| 2642 | };
|
---|
| 2643 | // to shut the compiler up
|
---|
| 2644 | return D3DCMP_ALWAYS;
|
---|
| 2645 | }
|
---|
| 2646 | //---------------------------------------------------------------------
|
---|
| 2647 | D3DSTENCILOP D3DRenderSystem::convertStencilOp(StencilOperation op)
|
---|
| 2648 | {
|
---|
| 2649 | switch(op)
|
---|
| 2650 | {
|
---|
| 2651 | case SOP_KEEP:
|
---|
| 2652 | return D3DSTENCILOP_KEEP;
|
---|
| 2653 | case SOP_ZERO:
|
---|
| 2654 | return D3DSTENCILOP_ZERO;
|
---|
| 2655 | case SOP_REPLACE:
|
---|
| 2656 | return D3DSTENCILOP_REPLACE;
|
---|
| 2657 | case SOP_INCREMENT:
|
---|
| 2658 | return D3DSTENCILOP_INCRSAT;
|
---|
| 2659 | case SOP_DECREMENT:
|
---|
| 2660 | return D3DSTENCILOP_DECRSAT;
|
---|
| 2661 | case SOP_INCREMENT_WRAP:
|
---|
| 2662 | return D3DSTENCILOP_INCR;
|
---|
| 2663 | case SOP_DECREMENT_WRAP:
|
---|
| 2664 | return D3DSTENCILOP_DECR;
|
---|
| 2665 | case SOP_INVERT:
|
---|
| 2666 | return D3DSTENCILOP_INVERT;
|
---|
| 2667 | };
|
---|
| 2668 | // To shut the compiler up
|
---|
| 2669 | return D3DSTENCILOP_KEEP;
|
---|
| 2670 | }
|
---|
| 2671 |
|
---|
| 2672 | DWORD D3DRenderSystem::_getCurrentAnisotropy(size_t unit)
|
---|
| 2673 | {
|
---|
| 2674 | DWORD oldVal;
|
---|
| 2675 | mlpD3DDevice->GetTextureStageState(unit, D3DTSS_MAXANISOTROPY, &oldVal);
|
---|
| 2676 | return oldVal;
|
---|
| 2677 | }
|
---|
| 2678 |
|
---|
| 2679 |
|
---|
| 2680 | void D3DRenderSystem::_setTextureUnitFiltering(size_t unit,
|
---|
| 2681 | FilterType ftype, FilterOptions filter)
|
---|
| 2682 | {
|
---|
| 2683 | __SetTextureStageState(unit, _getFilterCode(ftype), _getFilter(ftype, filter));
|
---|
| 2684 | }
|
---|
| 2685 |
|
---|
| 2686 | void D3DRenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
|
---|
| 2687 | {
|
---|
| 2688 | if ((DWORD)maxAnisotropy > mD3DDeviceDesc.dwMaxAnisotropy)
|
---|
| 2689 | maxAnisotropy = mD3DDeviceDesc.dwMaxAnisotropy;
|
---|
| 2690 |
|
---|
| 2691 | if (_getCurrentAnisotropy(unit) != maxAnisotropy)
|
---|
| 2692 | __SetTextureStageState( unit, D3DTSS_MAXANISOTROPY, maxAnisotropy );
|
---|
| 2693 | }
|
---|
| 2694 |
|
---|
| 2695 | void D3DRenderSystem::setVertexDeclaration(VertexDeclaration* decl)
|
---|
| 2696 | {
|
---|
| 2697 | // TODO
|
---|
| 2698 | }
|
---|
| 2699 |
|
---|
| 2700 | void D3DRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
|
---|
| 2701 | {
|
---|
| 2702 | // TODO
|
---|
| 2703 | }
|
---|
| 2704 | //-----------------------------------------------------------------------
|
---|
| 2705 | D3DTEXTURESTAGESTATETYPE D3DRenderSystem::_getFilterCode(FilterType ft) const
|
---|
| 2706 | {
|
---|
| 2707 | switch (ft)
|
---|
| 2708 | {
|
---|
| 2709 | case FT_MIN:
|
---|
| 2710 | return D3DTSS_MINFILTER;
|
---|
| 2711 | break;
|
---|
| 2712 | case FT_MAG:
|
---|
| 2713 | return D3DTSS_MAGFILTER;
|
---|
| 2714 | break;
|
---|
| 2715 | case FT_MIP:
|
---|
| 2716 | return D3DTSS_MIPFILTER;
|
---|
| 2717 | break;
|
---|
| 2718 | }
|
---|
| 2719 |
|
---|
| 2720 | // to keep compiler happy
|
---|
| 2721 | return D3DTSS_MINFILTER;
|
---|
| 2722 | }
|
---|
| 2723 | //-----------------------------------------------------------------------
|
---|
| 2724 | DWORD D3DRenderSystem::_getFilter(FilterType ft, FilterOptions fo) const
|
---|
| 2725 | {
|
---|
| 2726 | switch (ft)
|
---|
| 2727 | {
|
---|
| 2728 | case FT_MIN:
|
---|
| 2729 | switch( fo )
|
---|
| 2730 | {
|
---|
| 2731 | // NOTE: Fall through if device doesn't support requested type
|
---|
| 2732 | case FO_ANISOTROPIC:
|
---|
| 2733 | if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC )
|
---|
| 2734 | {
|
---|
| 2735 | return D3DTFN_ANISOTROPIC;
|
---|
| 2736 | break;
|
---|
| 2737 | }
|
---|
| 2738 | case FO_LINEAR:
|
---|
| 2739 | if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR )
|
---|
| 2740 | {
|
---|
| 2741 | return D3DTFN_LINEAR;
|
---|
| 2742 | break;
|
---|
| 2743 | }
|
---|
| 2744 | case FO_POINT:
|
---|
| 2745 | case FO_NONE:
|
---|
| 2746 | return D3DTFN_POINT;
|
---|
| 2747 | break;
|
---|
| 2748 | }
|
---|
| 2749 | break;
|
---|
| 2750 | case FT_MAG:
|
---|
| 2751 | switch( fo )
|
---|
| 2752 | {
|
---|
| 2753 | // NOTE: Fall through if device doesn't support requested type
|
---|
| 2754 | case FO_ANISOTROPIC:
|
---|
| 2755 | if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC )
|
---|
| 2756 | {
|
---|
| 2757 | return D3DTFG_ANISOTROPIC;
|
---|
| 2758 | break;
|
---|
| 2759 | }
|
---|
| 2760 | case FO_LINEAR:
|
---|
| 2761 | if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR )
|
---|
| 2762 | {
|
---|
| 2763 | return D3DTFG_LINEAR;
|
---|
| 2764 | break;
|
---|
| 2765 | }
|
---|
| 2766 | case FO_POINT:
|
---|
| 2767 | case FO_NONE:
|
---|
| 2768 | return D3DTFG_POINT;
|
---|
| 2769 | break;
|
---|
| 2770 | }
|
---|
| 2771 | break;
|
---|
| 2772 | case FT_MIP:
|
---|
| 2773 | switch( fo )
|
---|
| 2774 | {
|
---|
| 2775 | case FO_ANISOTROPIC:
|
---|
| 2776 | case FO_LINEAR:
|
---|
| 2777 | if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR )
|
---|
| 2778 | {
|
---|
| 2779 | return D3DTFP_LINEAR;
|
---|
| 2780 | break;
|
---|
| 2781 | }
|
---|
| 2782 | case FO_POINT:
|
---|
| 2783 | if( mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR )
|
---|
| 2784 | {
|
---|
| 2785 | return D3DTFP_POINT;
|
---|
| 2786 | break;
|
---|
| 2787 | }
|
---|
| 2788 | case FO_NONE:
|
---|
| 2789 | return D3DTFP_NONE;
|
---|
| 2790 | break;
|
---|
| 2791 | }
|
---|
| 2792 | break;
|
---|
| 2793 | }
|
---|
| 2794 |
|
---|
| 2795 | // should never get here
|
---|
| 2796 | return 0;
|
---|
| 2797 | }
|
---|
| 2798 | //---------------------------------------------------------------------
|
---|
| 2799 | void D3DRenderSystem::setNormaliseNormals(bool normalise)
|
---|
| 2800 | {
|
---|
| 2801 | __SetRenderState(D3DRENDERSTATE_NORMALIZENORMALS,
|
---|
| 2802 | normalise ? TRUE : FALSE);
|
---|
| 2803 | }
|
---|
| 2804 | //---------------------------------------------------------------------
|
---|
| 2805 | HRESULT D3DRenderSystem::__SetRenderState(D3DRENDERSTATETYPE state, DWORD value)
|
---|
| 2806 | {
|
---|
| 2807 | HRESULT hr;
|
---|
| 2808 | DWORD oldVal;
|
---|
| 2809 |
|
---|
| 2810 | if ( FAILED( hr = mlpD3DDevice->GetRenderState(state, &oldVal) ) )
|
---|
| 2811 | return hr;
|
---|
| 2812 | if ( oldVal == value )
|
---|
| 2813 | return D3D_OK;
|
---|
| 2814 | else
|
---|
| 2815 | return mlpD3DDevice->SetRenderState(state, value);
|
---|
| 2816 | }
|
---|
| 2817 | //---------------------------------------------------------------------
|
---|
| 2818 | HRESULT D3DRenderSystem::__SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
|
---|
| 2819 | {
|
---|
| 2820 | HRESULT hr;
|
---|
| 2821 | DWORD oldVal;
|
---|
| 2822 |
|
---|
| 2823 | if ( FAILED( hr = mlpD3DDevice->GetTextureStageState(stage, type, &oldVal) ) )
|
---|
| 2824 | return hr;
|
---|
| 2825 | if ( oldVal == value )
|
---|
| 2826 | return D3D_OK;
|
---|
| 2827 | else
|
---|
| 2828 | return mlpD3DDevice->SetTextureStageState(stage, type, value);
|
---|
| 2829 | }
|
---|
| 2830 |
|
---|
| 2831 | //---------------------------------------------------------------------
|
---|
| 2832 | void D3DRenderSystem::clearFrameBuffer(unsigned int buffers,
|
---|
| 2833 | const ColourValue& colour, Real depth, unsigned short stencil)
|
---|
| 2834 | {
|
---|
| 2835 | if (mDeviceLost)
|
---|
| 2836 | return;
|
---|
| 2837 |
|
---|
| 2838 | DWORD flags = 0;
|
---|
| 2839 | if (buffers & FBT_COLOUR)
|
---|
| 2840 | {
|
---|
| 2841 | flags |= D3DCLEAR_TARGET;
|
---|
| 2842 | }
|
---|
| 2843 | if (buffers & FBT_DEPTH)
|
---|
| 2844 | {
|
---|
| 2845 | flags |= D3DCLEAR_ZBUFFER;
|
---|
| 2846 | }
|
---|
| 2847 | // Only try to clear the stencil if supported, otherwise it will fail
|
---|
| 2848 | if (buffers & FBT_STENCIL && mCapabilities->hasCapability(RSC_HWSTENCIL))
|
---|
| 2849 | {
|
---|
| 2850 | flags |= D3DCLEAR_STENCIL;
|
---|
| 2851 | }
|
---|
| 2852 | HRESULT hr;
|
---|
| 2853 | if( FAILED( hr = mlpD3DDevice->Clear(
|
---|
| 2854 | 0,
|
---|
| 2855 | NULL,
|
---|
| 2856 | flags,
|
---|
| 2857 | colour.getAsARGB(),
|
---|
| 2858 | depth,
|
---|
| 2859 | stencil ) ) )
|
---|
| 2860 | {
|
---|
| 2861 | String msg = getErrorDescription(hr);
|
---|
| 2862 | OGRE_EXCEPT( hr, "Error clearing frame buffer : "
|
---|
| 2863 | + msg, "D3DRenderSystem::clearFrameBuffer" );
|
---|
| 2864 | }
|
---|
| 2865 | }
|
---|
| 2866 | //---------------------------------------------------------------------
|
---|
| 2867 | void D3DRenderSystem::_makeProjectionMatrix(Real left, Real right,
|
---|
| 2868 | Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest,
|
---|
| 2869 | bool forGpuProgram)
|
---|
| 2870 | {
|
---|
| 2871 | Real width = right - left;
|
---|
| 2872 | Real height = top - bottom;
|
---|
| 2873 | Real q, qn;
|
---|
| 2874 | if (farPlane == 0)
|
---|
| 2875 | {
|
---|
| 2876 | q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST;
|
---|
| 2877 | qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1);
|
---|
| 2878 | }
|
---|
| 2879 | else
|
---|
| 2880 | {
|
---|
| 2881 | q = farPlane / ( farPlane - nearPlane );
|
---|
| 2882 | qn = -q * nearPlane;
|
---|
| 2883 | }
|
---|
| 2884 | dest = Matrix4::ZERO;
|
---|
| 2885 | dest[0][0] = 2 * nearPlane / width;
|
---|
| 2886 | dest[0][2] = (right+left) / width;
|
---|
| 2887 | dest[1][1] = 2 * nearPlane / height;
|
---|
| 2888 | dest[1][2] = (top+bottom) / height;
|
---|
| 2889 | if (forGpuProgram)
|
---|
| 2890 | {
|
---|
| 2891 | dest[2][2] = -q;
|
---|
| 2892 | dest[3][2] = -1.0f;
|
---|
| 2893 | }
|
---|
| 2894 | else
|
---|
| 2895 | {
|
---|
| 2896 | dest[2][2] = q;
|
---|
| 2897 | dest[3][2] = 1.0f;
|
---|
| 2898 | }
|
---|
| 2899 | dest[2][3] = qn;
|
---|
| 2900 | }
|
---|
| 2901 |
|
---|
| 2902 | //---------------------------------------------------------------------
|
---|
| 2903 | void D3DRenderSystem::setClipPlanes(const PlaneList& clipPlanes)
|
---|
| 2904 | {
|
---|
| 2905 | size_t i;
|
---|
| 2906 | size_t numClipPlanes;
|
---|
| 2907 | D3DVALUE dx7ClipPlane[4];
|
---|
| 2908 | DWORD mask = 0;
|
---|
| 2909 | HRESULT hr;
|
---|
| 2910 | numClipPlanes = clipPlanes.size();
|
---|
| 2911 |
|
---|
| 2912 | for (i = 0; i < numClipPlanes; ++i)
|
---|
| 2913 | {
|
---|
| 2914 | const Plane& plane = clipPlanes[i];
|
---|
| 2915 |
|
---|
| 2916 | dx7ClipPlane[0] = plane.normal.x;
|
---|
| 2917 | dx7ClipPlane[1] = plane.normal.y;
|
---|
| 2918 | dx7ClipPlane[2] = plane.normal.z;
|
---|
| 2919 | dx7ClipPlane[3] = plane.d;
|
---|
| 2920 |
|
---|
| 2921 | hr = mlpD3DDevice->SetClipPlane(i, dx7ClipPlane);
|
---|
| 2922 | if (FAILED(hr))
|
---|
| 2923 | {
|
---|
| 2924 | OGRE_EXCEPT(hr, "Unable to set clip plane",
|
---|
| 2925 | "D3D7RenderSystem::setClipPlanes");
|
---|
| 2926 | }
|
---|
| 2927 |
|
---|
| 2928 | mask |= (1 << i);
|
---|
| 2929 | }
|
---|
| 2930 |
|
---|
| 2931 | hr = mlpD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE, mask);
|
---|
| 2932 | if (FAILED(hr))
|
---|
| 2933 | {
|
---|
| 2934 | OGRE_EXCEPT(hr, "Unable to set render state for clip planes",
|
---|
| 2935 | "D3D7RenderSystem::setClipPlanes");
|
---|
| 2936 | }
|
---|
| 2937 | }
|
---|
| 2938 |
|
---|
| 2939 | // ------------------------------------------------------------------
|
---|
| 2940 | void D3DRenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D)
|
---|
| 2941 | {
|
---|
| 2942 | float plane[4] = { A, B, C, D };
|
---|
| 2943 | mlpD3DDevice->SetClipPlane (index, plane);
|
---|
| 2944 | }
|
---|
| 2945 |
|
---|
| 2946 | // ------------------------------------------------------------------
|
---|
| 2947 | void D3DRenderSystem::enableClipPlane (ushort index, bool enable)
|
---|
| 2948 | {
|
---|
| 2949 | DWORD prev;
|
---|
| 2950 | mlpD3DDevice->GetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE, &prev);
|
---|
| 2951 | __SetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE, prev | (1 << index));
|
---|
| 2952 | }
|
---|
| 2953 | //---------------------------------------------------------------------
|
---|
| 2954 | HardwareOcclusionQuery* D3DRenderSystem::createHardwareOcclusionQuery(void)
|
---|
| 2955 | {
|
---|
| 2956 | return (HardwareOcclusionQuery*) 0; // Hardware occlusion is not supported when DirectX7 is used
|
---|
| 2957 | }
|
---|
| 2958 | //-----------------------------------------------------------------------
|
---|
| 2959 | void D3DRenderSystem::_setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
|
---|
| 2960 | {
|
---|
| 2961 | // D3D7 does not have a colour write mask setting, so emulate it using
|
---|
| 2962 | // scene blending, on the assumption that setSceneBlend will be called
|
---|
| 2963 | // before this
|
---|
| 2964 | if (red || green || blue || alpha)
|
---|
| 2965 | {
|
---|
| 2966 | // restore saved scene blend
|
---|
| 2967 | _setSceneBlending(mSavedSrcFactor, mSavedDestFactor);
|
---|
| 2968 | }
|
---|
| 2969 | else
|
---|
| 2970 | {
|
---|
| 2971 | _setSceneBlending(SBF_ZERO, SBF_ONE);
|
---|
| 2972 | }
|
---|
| 2973 | }
|
---|
| 2974 | //---------------------------------------------------------------------
|
---|
| 2975 | Real D3DRenderSystem::getHorizontalTexelOffset(void)
|
---|
| 2976 | {
|
---|
| 2977 | // D3D considers the origin to be in the center of a pixel
|
---|
| 2978 | return -0.5f;
|
---|
| 2979 | }
|
---|
| 2980 | //---------------------------------------------------------------------
|
---|
| 2981 | Real D3DRenderSystem::getVerticalTexelOffset(void)
|
---|
| 2982 | {
|
---|
| 2983 | // D3D considers the origin to be in the center of a pixel
|
---|
| 2984 | return -0.5f;
|
---|
| 2985 | }
|
---|
| 2986 | //---------------------------------------------------------------------
|
---|
| 2987 | void D3DRenderSystem::_applyObliqueDepthProjection(Matrix4& matrix,
|
---|
| 2988 | const Plane& plane, bool forGpuProgram)
|
---|
| 2989 | {
|
---|
| 2990 | // Thanks to Eric Lenyel for posting this calculation at www.terathon.com
|
---|
| 2991 |
|
---|
| 2992 | // Calculate the clip-space corner point opposite the clipping plane
|
---|
| 2993 | // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
---|
| 2994 | // transform it into camera space by multiplying it
|
---|
| 2995 | // by the inverse of the projection matrix
|
---|
| 2996 |
|
---|
| 2997 | /* generalised version
|
---|
| 2998 | Vector4 q = matrix.inverse() *
|
---|
| 2999 | Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f);
|
---|
| 3000 | */
|
---|
| 3001 | Vector4 q;
|
---|
| 3002 | q.x = Math::Sign(plane.normal.x) / matrix[0][0];
|
---|
| 3003 | q.y = Math::Sign(plane.normal.y) / matrix[1][1];
|
---|
| 3004 | q.z = 1.0F;
|
---|
| 3005 | // flip the next bit from Lengyel since we're right-handed
|
---|
| 3006 | if (forGpuProgram)
|
---|
| 3007 | {
|
---|
| 3008 | q.w = (1.0F - matrix[2][2]) / matrix[2][3];
|
---|
| 3009 | }
|
---|
| 3010 | else
|
---|
| 3011 | {
|
---|
| 3012 | q.w = (1.0F + matrix[2][2]) / matrix[2][3];
|
---|
| 3013 | }
|
---|
| 3014 |
|
---|
| 3015 | // Calculate the scaled plane vector
|
---|
| 3016 | Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d);
|
---|
| 3017 | Vector4 c = clipPlane4d * (1.0F / (clipPlane4d.dotProduct(q)));
|
---|
| 3018 |
|
---|
| 3019 | // Replace the third row of the projection matrix
|
---|
| 3020 | matrix[2][0] = c.x;
|
---|
| 3021 | matrix[2][1] = c.y;
|
---|
| 3022 | // flip the next bit from Lengyel since we're right-handed
|
---|
| 3023 | if (forGpuProgram)
|
---|
| 3024 | {
|
---|
| 3025 | matrix[2][2] = c.z;
|
---|
| 3026 | }
|
---|
| 3027 | else
|
---|
| 3028 | {
|
---|
| 3029 | matrix[2][2] = -c.z;
|
---|
| 3030 | }
|
---|
| 3031 | matrix[2][3] = c.w;
|
---|
| 3032 |
|
---|
| 3033 | }
|
---|
| 3034 | //---------------------------------------------------------------------
|
---|
| 3035 | Real D3DRenderSystem::getMinimumDepthInputValue(void)
|
---|
| 3036 | {
|
---|
| 3037 | // Range [0.0f, 1.0f]
|
---|
| 3038 | return 0.0f;
|
---|
| 3039 | }
|
---|
| 3040 | //---------------------------------------------------------------------
|
---|
| 3041 | Real D3DRenderSystem::getMaximumDepthInputValue(void)
|
---|
| 3042 | {
|
---|
| 3043 | // Range [0.0f, 1.0f]
|
---|
| 3044 | // D3D inverts even identity view matrices, so maximum INPUT is -1.0
|
---|
| 3045 | return -1.0f;
|
---|
| 3046 | }
|
---|
| 3047 |
|
---|
| 3048 |
|
---|
| 3049 | }
|
---|