TerrainTex.cpp 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: TerrainTex.cpp ////////////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Westwood Studios Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2001 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // Project: RTS3
  34. //
  35. // File name: TerrainTex.cpp
  36. //
  37. // Created: John Ahlquist, April 2001
  38. //
  39. // Desc: TextureClass overrides to perform custom texturing for the terrain.
  40. //
  41. //-----------------------------------------------------------------------------
  42. //-----------------------------------------------------------------------------
  43. // Includes
  44. //-----------------------------------------------------------------------------
  45. #include <stdlib.h>
  46. #include "W3DDevice/GameClient/TerrainTex.h"
  47. #include "W3DDevice/GameClient/WorldHeightMap.h"
  48. #include "W3DDevice/GameClient/TileData.h"
  49. #include "common/GlobalData.h"
  50. #include "WW3D2/dx8wrapper.h"
  51. #include "d3dx8tex.h"
  52. /******************************************************************************
  53. TerrainTextureClass
  54. ******************************************************************************/
  55. //-----------------------------------------------------------------------------
  56. // Public Functions
  57. //-----------------------------------------------------------------------------
  58. //=============================================================================
  59. // TerrainTextureClass::TerrainTextureClass
  60. //=============================================================================
  61. /** Constructor. Calls parent constructor to create a 16 bit per pixel D3D
  62. texture of the desired height and mip level. */
  63. //=============================================================================
  64. TerrainTextureClass::TerrainTextureClass(int height, MipCountType mipLevelCount) :
  65. TextureClass(TEXTURE_WIDTH, height,
  66. WW3D_FORMAT_A1R5G5B5, mipLevelCount )
  67. {
  68. }
  69. //=============================================================================
  70. // TerrainTextureClass::update
  71. //=============================================================================
  72. /** Sets the tile bitmap data into the texture. The tiles are placed with 4
  73. pixel borders around them, so that when the tiles are scaled and bilinearly
  74. interpolated, you don't get seams between the tiles. */
  75. //=============================================================================
  76. int TerrainTextureClass::update(WorldHeightMap *htMap)
  77. {
  78. // D3DTexture is our texture;
  79. IDirect3DSurface8 *surface_level;
  80. D3DSURFACE_DESC surface_desc;
  81. D3DLOCKED_RECT locked_rect;
  82. DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0, &surface_level));
  83. DX8_ErrorCode(surface_level->GetDesc(&surface_desc));
  84. if (surface_desc.Width < TEXTURE_WIDTH) {
  85. surface_level->Release();
  86. if (surface_desc.Width == 256) {
  87. return update256(htMap);
  88. }
  89. return false;
  90. }
  91. DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0));
  92. Int tilePixelExtent = TILE_PIXEL_EXTENT;
  93. Int tilesPerRow = surface_desc.Width/(2*TILE_PIXEL_EXTENT+TILE_OFFSET);
  94. tilesPerRow *= 2;
  95. // Int numRows = surface_desc.Height/(tilePixelExtent+TILE_OFFSET);
  96. #ifdef _DEBUG
  97. //DEBUG_ASSERTCRASH(tilesPerRow*numRows >= htMap->m_numBitmapTiles, ("Too many tiles."));
  98. DEBUG_ASSERTCRASH((Int)surface_desc.Width >= tilePixelExtent*tilesPerRow, ("Bitmap too small."));
  99. #endif
  100. if (surface_desc.Format == D3DFMT_A1R5G5B5) {
  101. #if 0
  102. UnsignedInt cellX, cellY;
  103. for (cellX = 0; cellX < surface_desc.Width; cellX++) {
  104. for (cellY = 0; cellY < surface_desc.Height; cellY++) {
  105. UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*2;
  106. *((Short*)pBGR) = (((255-2*cellY)>>3)<<10) + ((4*cellX)>>4);
  107. }
  108. }
  109. #endif
  110. Int tileNdx;
  111. Int pixelBytes = 2;
  112. for (tileNdx=0; tileNdx < htMap->m_numBitmapTiles; tileNdx++) {
  113. TileData *pTile = htMap->getSourceTile(tileNdx);
  114. if (!pTile) continue;
  115. ICoord2D position = pTile->m_tileLocationInTexture;
  116. if (position.x<=0) continue; // all real tile offsets start at 2. jba.
  117. Int i,j;
  118. for (j=0; j<tilePixelExtent; j++) {
  119. UnsignedByte *pBGR = pTile->getRGBDataForWidth(tilePixelExtent);
  120. pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match.
  121. Int row = position.y+j;
  122. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  123. (row)*surface_desc.Width*pixelBytes;
  124. Int column = position.x;
  125. pBGRX += column*pixelBytes;
  126. for (i=0; i<tilePixelExtent; i++) {
  127. *((Short*)pBGRX) = 0x8000 + ((pBGR[2]>>3)<<10) + ((pBGR[1]>>3)<<5) + (pBGR[0]>>3);
  128. pBGRX +=pixelBytes;
  129. pBGR +=TILE_BYTES_PER_PIXEL;
  130. }
  131. }
  132. }
  133. // Now draw the 4 pixel border around each tile class.
  134. Int texClass;
  135. for (texClass=0; texClass<htMap->m_numTextureClasses; texClass++) {
  136. Int width = htMap->m_textureClasses[texClass].width;
  137. ICoord2D origin = htMap->m_textureClasses[texClass].positionInTexture;
  138. if (origin.x<=0) continue;
  139. width *= TILE_PIXEL_EXTENT;
  140. // Duplicate 4 columns of pixels before and after.
  141. Int j;
  142. for (j=0; j<width; j++) {
  143. Int row = origin.y+j;
  144. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  145. (row)*surface_desc.Width*pixelBytes;
  146. Int column = origin.x;
  147. pBGRX += column*pixelBytes;
  148. // copy before
  149. memcpy(pBGRX-(4)*pixelBytes, pBGRX+(width-4)*pixelBytes, 4*pixelBytes);
  150. // copy after
  151. memcpy(pBGRX+(width*pixelBytes), pBGRX, 4*pixelBytes);
  152. }
  153. // Duplicate 4 rows of pixels before and after.
  154. for (j=0; j<4; j++) {
  155. // copy before.
  156. Int row = origin.y-j-1;
  157. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  158. (row)*surface_desc.Width*pixelBytes;
  159. UnsignedByte *target = pBGRX+(origin.x-4)*pixelBytes;
  160. memcpy(target, target+width*surface_desc.Width*pixelBytes, (width+8)*pixelBytes);
  161. // copy after.
  162. row = origin.y+j;
  163. pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  164. (row)*surface_desc.Width*pixelBytes;
  165. target = pBGRX+(origin.x-4)*pixelBytes;
  166. memcpy(target+width*surface_desc.Width*pixelBytes, target, (width+8)*pixelBytes);
  167. }
  168. }
  169. }
  170. surface_level->UnlockRect();
  171. surface_level->Release();
  172. DX8_ErrorCode(D3DXFilterTexture(D3DTexture, NULL, 0, D3DX_FILTER_BOX));
  173. if (TheWritableGlobalData->m_textureReductionFactor) {
  174. D3DTexture->SetLOD(TheWritableGlobalData->m_textureReductionFactor);
  175. }
  176. return(surface_desc.Height);
  177. }
  178. #if 0 // old version.
  179. //=============================================================================
  180. // TerrainTextureClass::update
  181. //=============================================================================
  182. /** Sets the tile bitmap data into the texture. The tiles are placed with 4
  183. pixel borders around them, so that when the tiles are scaled and bilinearly
  184. interpolated, you don't get seams between the tiles. */
  185. //=============================================================================
  186. int TerrainTextureClass::update(WorldHeightMap *htMap)
  187. {
  188. // D3DTexture is our texture;
  189. IDirect3DSurface8 *surface_level;
  190. D3DSURFACE_DESC surface_desc;
  191. D3DLOCKED_RECT locked_rect;
  192. DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0, &surface_level));
  193. DX8_ErrorCode(surface_level->GetDesc(&surface_desc));
  194. if (surface_desc.Width < TEXTURE_WIDTH) {
  195. surface_level->Release();
  196. if (surface_desc.Width == 256) {
  197. return update256(htMap);
  198. }
  199. return false;
  200. }
  201. DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0));
  202. Int tilePixelExtent = TILE_PIXEL_EXTENT;
  203. Int tilesPerRow = surface_desc.Width/(2*TILE_PIXEL_EXTENT+TILE_OFFSET);
  204. tilesPerRow *= 2;
  205. Int numRows = surface_desc.Height/(tilePixelExtent+TILE_OFFSET);
  206. #ifdef _DEBUG
  207. assert(tilesPerRow*numRows >= htMap->m_numBitmapTiles);
  208. assert((Int)surface_desc.Width >= tilePixelExtent*tilesPerRow);
  209. #endif
  210. if (surface_desc.Format == D3DFMT_A1R5G5B5) {
  211. Int cellX, cellY;
  212. #if 0
  213. for (cellX = 0; cellX < surface_desc.Width; cellX++) {
  214. for (cellY = 0; cellY < surface_desc.Height; cellY++) {
  215. UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*2;
  216. *((Short*)pBGR) = (((255-2*cellY)>>3)<<10) + ((4*cellX)>>4);
  217. }
  218. }
  219. #endif
  220. Int pixelBytes = 2;
  221. for (cellY = 0; cellY < numRows; cellY++) {
  222. for (cellX = 0; cellX < tilesPerRow; cellX++) {
  223. Int tileNdx = cellX/2 + (tilesPerRow/2)*(cellY/2);
  224. tileNdx *=4;
  225. if (cellX&1) tileNdx++;
  226. if (!(cellY&1)) tileNdx += 2;
  227. #define ADD_EXTRA_TILES 1
  228. #if ADD_EXTRA_TILES // Fills in an extra 2 columns and 1 row of tiles if there is room.
  229. if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-4)) {
  230. tileNdx -= 4;
  231. }
  232. if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-8)) {
  233. tileNdx -= 8;
  234. }
  235. if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-2*tilesPerRow)) {
  236. tileNdx -= 2*tilesPerRow;
  237. }
  238. #endif
  239. if (htMap->getSourceTile(tileNdx)) {
  240. Int i,j;
  241. for (j=0; j<tilePixelExtent; j++) {
  242. UnsignedByte *pBGR = htMap->getSourceTile(tileNdx)->getRGBDataForWidth(tilePixelExtent);
  243. pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match.
  244. Int row = cellY*tilePixelExtent+j;
  245. row += TILE_OFFSET/2;
  246. row += TILE_OFFSET*(cellY/2);
  247. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  248. (row)*surface_desc.Width*pixelBytes;
  249. Int column = cellX*tilePixelExtent;
  250. column += TILE_OFFSET*(cellX/2);
  251. pBGRX += column*pixelBytes;
  252. pBGRX += (TILE_OFFSET/2)*pixelBytes;
  253. for (i=0; i<tilePixelExtent; i++) {
  254. *((Short*)pBGRX) = 0x8000 + ((pBGR[2]>>3)<<10) + ((pBGR[1]>>3)<<5) + (pBGR[0]>>3);
  255. pBGRX +=pixelBytes;
  256. pBGR +=TILE_BYTES_PER_PIXEL;
  257. }
  258. }
  259. }
  260. }
  261. }
  262. for (cellY = 0; cellY < numRows; cellY++) {
  263. for (cellX = 0; cellX < tilesPerRow; cellX++) {
  264. // Duplicate 4 rows of pixels before and after.
  265. Int j;
  266. for (j=0; j<tilePixelExtent; j++) {
  267. Int row = cellY*tilePixelExtent+j;
  268. row += TILE_OFFSET/2;
  269. row += TILE_OFFSET*(cellY/2);
  270. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  271. (row)*surface_desc.Width*pixelBytes;
  272. Int column = cellX*tilePixelExtent;
  273. column += TILE_OFFSET*(cellX/2);
  274. pBGRX += column*pixelBytes;
  275. if (cellX&1) {
  276. Int bytesToCopy = 4*pixelBytes;
  277. if (cellX == tilesPerRow-1) {
  278. // last cell, so fill to the end of the texture.
  279. Int usedWidth = tilesPerRow*tilePixelExtent + TILE_OFFSET*(tilesPerRow/2);
  280. usedWidth *= pixelBytes;
  281. bytesToCopy += surface_desc.Width*pixelBytes - usedWidth;
  282. }
  283. // Copy after.
  284. pBGRX -= tilePixelExtent*pixelBytes;
  285. pBGRX += (TILE_OFFSET/2)*pixelBytes;
  286. memcpy(pBGRX+(2*tilePixelExtent*pixelBytes), pBGRX, bytesToCopy);
  287. } else {
  288. // copy before
  289. memcpy(pBGRX, pBGRX+(2*tilePixelExtent)*pixelBytes, 4*pixelBytes);
  290. }
  291. }
  292. }
  293. }
  294. for (cellY = 0; cellY < numRows; cellY++) {
  295. Int rowBytes = surface_desc.Width*pixelBytes;
  296. Int row = cellY*tilePixelExtent;
  297. row += TILE_OFFSET/2;
  298. row += TILE_OFFSET*(cellY/2);
  299. if ( (cellY&1) == 0) {
  300. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  301. (row)*rowBytes;
  302. row += 2*tilePixelExtent;
  303. UnsignedByte *pBase = ((UnsignedByte*)locked_rect.pBits) +
  304. (row)*rowBytes;
  305. memcpy(pBGRX-4*rowBytes, pBase-4*rowBytes, 4*rowBytes);
  306. } else {
  307. UnsignedByte *pBase = ((UnsignedByte*)locked_rect.pBits) +
  308. (row-tilePixelExtent)*rowBytes;
  309. row += tilePixelExtent;
  310. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  311. (row)*rowBytes;
  312. memcpy(pBGRX, pBase, 4*rowBytes);
  313. }
  314. }
  315. }
  316. surface_level->UnlockRect();
  317. surface_level->Release();
  318. DX8_ErrorCode(D3DXFilterTexture(D3DTexture, NULL, 0, D3DX_FILTER_BOX));
  319. return(surface_desc.Height);
  320. }
  321. #endif
  322. //=============================================================================
  323. // TerrainTextureClass::update256
  324. //=============================================================================
  325. /** Sets the tile bitmap data into the texture. Handles the special case for voodoos
  326. and the like where the max texture size is 256. The tiles are placed with 1
  327. pixel borders around them, so that when the tiles are scaled and bilinearly
  328. interpolated, you don't get seams between the tiles. */
  329. //=============================================================================
  330. int TerrainTextureClass::update256(WorldHeightMap *htMap)
  331. {
  332. // D3DTexture is our texture;
  333. IDirect3DSurface8 *surface_level;
  334. D3DSURFACE_DESC surface_desc;
  335. D3DLOCKED_RECT locked_rect;
  336. DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0, &surface_level));
  337. DX8_ErrorCode(surface_level->GetDesc(&surface_desc));
  338. if (surface_desc.Width != 256) {
  339. surface_level->Release();
  340. return surface_desc.Height;
  341. }
  342. DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0));
  343. Int tilePixelExtent = TILE_PIXEL_EXTENT/4; // We are going from 1024 to 256, so need to divide all the constants by 4.
  344. Int tileOffset = TILE_OFFSET/4;
  345. Int tilesPerRow = surface_desc.Width/(2*tilePixelExtent+tileOffset);
  346. tilesPerRow *= 2;
  347. Int numRows = surface_desc.Height/(tilePixelExtent+tileOffset);
  348. #ifdef _DEBUG
  349. assert(tilesPerRow*numRows >= htMap->m_numBitmapTiles);
  350. assert((Int)surface_desc.Width >= tilePixelExtent*tilesPerRow);
  351. #endif
  352. if (surface_desc.Format == D3DFMT_A1R5G5B5) {
  353. Int cellX, cellY;
  354. #if 0
  355. for (cellX = 0; cellX < surface_desc.Width; cellX++) {
  356. for (cellY = 0; cellY < surface_desc.Height; cellY++) {
  357. UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*2;
  358. *((Short*)pBGR) = (((255-2*cellY)>>3)<<10) + ((4*cellX)>>4);
  359. }
  360. }
  361. numRows = 0;
  362. #endif
  363. Int pixelBytes = 2;
  364. for (cellY = 0; cellY < numRows; cellY++) {
  365. for (cellX = 0; cellX < tilesPerRow; cellX++) {
  366. Int tileNdx = cellX/2 + (tilesPerRow/2)*(cellY/2);
  367. tileNdx *=4;
  368. if (cellX&1) tileNdx++;
  369. if (!(cellY&1)) tileNdx += 2;
  370. #if ADD_EXTRA_TILES // Fills in an extra 2 columns and 1 row of tiles if there is room.
  371. if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-4)) {
  372. tileNdx -= 4;
  373. }
  374. if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-8)) {
  375. tileNdx -= 8;
  376. }
  377. if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-2*tilesPerRow)) {
  378. tileNdx -= 2*tilesPerRow;
  379. }
  380. #endif
  381. if (htMap->getSourceTile(tileNdx)) {
  382. Int i,j;
  383. for (j=0; j<tilePixelExtent; j++) {
  384. UnsignedByte *pBGR = htMap->getSourceTile(tileNdx)->getRGBDataForWidth(tilePixelExtent);
  385. pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match.
  386. Int row = cellY*tilePixelExtent+j;
  387. row += tileOffset/2;
  388. row += tileOffset*(cellY/2);
  389. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  390. (row)*surface_desc.Width*pixelBytes;
  391. Int column = cellX*tilePixelExtent;
  392. column += tileOffset*(cellX/2);
  393. pBGRX += column*pixelBytes;
  394. pBGRX += (tileOffset/2)*pixelBytes;
  395. for (i=0; i<tilePixelExtent; i++) {
  396. *((Short*)pBGRX) = 0x8000 + ((pBGR[2]>>3)<<10) + ((pBGR[1]>>3)<<5) + (pBGR[0]>>3);
  397. pBGRX +=pixelBytes;
  398. pBGR +=TILE_BYTES_PER_PIXEL;
  399. }
  400. }
  401. }
  402. }
  403. }
  404. for (cellY = 0; cellY < numRows; cellY++) {
  405. for (cellX = 0; cellX < tilesPerRow; cellX++) {
  406. // Duplicate 1 rows of pixels before and after.
  407. Int j;
  408. for (j=0; j<tilePixelExtent; j++) {
  409. Int row = cellY*tilePixelExtent+j;
  410. row += tileOffset/2;
  411. row += tileOffset*(cellY/2);
  412. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  413. (row)*surface_desc.Width*pixelBytes;
  414. Int column = cellX*tilePixelExtent;
  415. column += tileOffset*(cellX/2);
  416. pBGRX += column*pixelBytes;
  417. if (cellX&1) {
  418. // Copy after.
  419. pBGRX -= tilePixelExtent*pixelBytes;
  420. pBGRX += (tileOffset/2)*pixelBytes;
  421. Int bytesToCopy = pixelBytes;
  422. if (cellX == tilesPerRow-1) {
  423. // last cell, so fill to the end of the texture.
  424. Int usedWidth = tilesPerRow*tilePixelExtent + tileOffset*(tilesPerRow/2);
  425. usedWidth *= pixelBytes;
  426. bytesToCopy += surface_desc.Width*pixelBytes - usedWidth;
  427. }
  428. memcpy(pBGRX+(2*tilePixelExtent*pixelBytes), pBGRX, bytesToCopy);
  429. // Copy after.
  430. pBGRX -= tilePixelExtent*pixelBytes;
  431. pBGRX += (TILE_OFFSET/2)*pixelBytes;
  432. } else {
  433. // copy before
  434. memcpy(pBGRX, pBGRX+(2*tilePixelExtent)*pixelBytes, pixelBytes);
  435. }
  436. }
  437. }
  438. }
  439. for (cellY = 0; cellY < numRows; cellY++) {
  440. Int rowBytes = surface_desc.Width*pixelBytes;
  441. Int row = cellY*tilePixelExtent;
  442. row += tileOffset/2;
  443. row += tileOffset*(cellY/2);
  444. if ( (cellY&1) == 0) {
  445. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  446. (row)*rowBytes;
  447. row += 2*tilePixelExtent;
  448. UnsignedByte *pBase = ((UnsignedByte*)locked_rect.pBits) +
  449. (row)*rowBytes;
  450. memcpy(pBGRX-rowBytes, pBase-rowBytes, rowBytes);
  451. } else {
  452. UnsignedByte *pBase = ((UnsignedByte*)locked_rect.pBits) +
  453. (row-tilePixelExtent)*rowBytes;
  454. row += tilePixelExtent;
  455. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  456. (row)*rowBytes;
  457. memcpy(pBGRX, pBase, rowBytes);
  458. }
  459. }
  460. }
  461. surface_level->UnlockRect();
  462. surface_level->Release();
  463. DX8_ErrorCode(D3DXFilterTexture(D3DTexture, NULL, 0, D3DX_FILTER_BOX));
  464. // Note - normal width for the terrain texture is 1024. We are at 256
  465. // probably running on a voodoo. The height we return is scaled up
  466. // to match the expected width of 1024. jba.
  467. return(surface_desc.Height*4);
  468. }
  469. //=============================================================================
  470. // TerrainTextureClass::Apply
  471. //=============================================================================
  472. /** Sets the texture as the current D3D texture, and does some custom setup
  473. (standard D3D setup, but beyond the scope of W3D). */
  474. //=============================================================================
  475. void TerrainTextureClass::Apply(unsigned int stage)
  476. {
  477. // Do the base apply.
  478. TextureClass::Apply(stage);
  479. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
  480. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
  481. if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
  482. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  483. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  484. } else {
  485. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT);
  486. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT);
  487. }
  488. if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
  489. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
  490. } else {
  491. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  492. }
  493. // Now setup the texture pipeline.
  494. if (stage==0) {
  495. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  496. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  497. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  498. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  499. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  500. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  501. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
  502. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false);
  503. }
  504. }
  505. /******************************************************************************
  506. AlphaTerrainTextureClass
  507. ******************************************************************************/
  508. //-----------------------------------------------------------------------------
  509. // Public Functions
  510. //-----------------------------------------------------------------------------
  511. //=============================================================================
  512. // AlphaTerrainTextureClass::AlphaTerrainTextureClass
  513. //=============================================================================
  514. /** Constructor. Calls parent constructor to creat a throw away 8x8 texture,
  515. then uses the base texture's D3D texture. This way the base tiles pass, drawn
  516. using TerrainTextureClass shares the same texture with the blended edges pass,
  517. saving lots of texture memory, and preventing seams between blended tiles. */
  518. //=============================================================================
  519. AlphaTerrainTextureClass::AlphaTerrainTextureClass( TextureClass *pBaseTex ):
  520. TextureClass(8, 8,
  521. WW3D_FORMAT_A1R5G5B5, MIP_LEVELS_1 )
  522. {
  523. if (D3DTexture) {
  524. // Release the 8x8 texture.
  525. D3DTexture->Release();
  526. D3DTexture = NULL;
  527. }
  528. // Attach the base texture's d3d texture.
  529. D3DTexture = pBaseTex->Peek_DX8_Texture();
  530. D3DTexture->AddRef();
  531. }
  532. //=============================================================================
  533. // AlphaTerrainTextureClass::Apply
  534. //=============================================================================
  535. /** Sets the texture as the current D3D texture, and does some custom setup.
  536. This may be applied in either single pass, as the second texture in the pipe,
  537. or multipass. If stage==0, we are doing multipass and we set up the pipe
  538. for a single texture. If stage==1, then we are doing a single pass, and we
  539. set up the pipe so that we blend onto the base texture in stage 0.
  540. (standard D3D setup, but beyond the scope of W3D). */
  541. //=============================================================================
  542. void AlphaTerrainTextureClass::Apply(unsigned int stage)
  543. {
  544. // Do the base apply.
  545. TextureClass::Apply(stage);
  546. // Set the bilinear or trilinear filtering.
  547. if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
  548. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  549. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  550. } else {
  551. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT);
  552. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT);
  553. }
  554. if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
  555. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
  556. } else {
  557. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  558. }
  559. // Since we are using multiple distinct tiles, the textures doesn't wrap, so clamp it.
  560. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
  561. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
  562. // Now setup the texture pipeline.
  563. if (stage==0) {
  564. // Modulate the diffuse color with the texture as lighting comes from diffuse.
  565. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  566. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  567. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  568. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  569. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 1 );
  570. // Blend the result using the alpha. (came from diffuse mod texture)
  571. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
  572. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
  573. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
  574. // Disable stage 2.
  575. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  576. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  577. } else if (stage==1) {
  578. if (TheGlobalData && !TheGlobalData->m_multiPassTerrain)
  579. {
  580. ///@todo: Remove 8-Stage Nvidia hack after drivers are fixed.
  581. //This method is a backdoor specific to Nvidia based cards. It will fail on
  582. //other hardware. Allows single pass blend of 2 textures and post modulate diffuse.
  583. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  584. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0);
  585. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  586. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  587. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  588. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  589. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
  590. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_ADD);
  591. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1);
  592. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE);
  593. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  594. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_ADD);
  595. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT);
  596. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
  597. DX8Wrapper::Set_DX8_Texture(2, NULL);
  598. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_MODULATE);
  599. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, 2);
  600. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  601. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG2, D3DTA_TEXTURE);
  602. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  603. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
  604. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
  605. DX8Wrapper::Set_DX8_Texture(3, NULL);
  606. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  607. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, 3);
  608. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG1, D3DTA_DIFFUSE | 0 | D3DTA_ALPHAREPLICATE);
  609. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  610. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  611. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
  612. DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
  613. DX8Wrapper::Set_DX8_Texture(4, NULL);
  614. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLOROP, D3DTOP_MODULATE);
  615. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_TEXCOORDINDEX, 4);
  616. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG1, D3DTA_CURRENT);
  617. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  618. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  619. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
  620. DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
  621. DX8Wrapper::Set_DX8_Texture(5, NULL);
  622. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLOROP, D3DTOP_ADD);
  623. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_TEXCOORDINDEX, 5);
  624. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
  625. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  626. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAOP, D3DTOP_ADD);
  627. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT);
  628. DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
  629. DX8Wrapper::Set_DX8_Texture(6, NULL);
  630. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLOROP, D3DTOP_MODULATE);
  631. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_TEXCOORDINDEX, 6);
  632. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG1, D3DTA_TFACTOR);
  633. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG2, D3DTA_TFACTOR);
  634. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  635. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
  636. DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
  637. DX8Wrapper::Set_DX8_Texture(7, NULL);
  638. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  639. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_TEXCOORDINDEX, 7);
  640. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG1, D3DTA_TFACTOR);
  641. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG2, D3DTA_TFACTOR);
  642. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  643. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
  644. DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
  645. }
  646. else
  647. {
  648. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  649. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
  650. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  651. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  652. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  653. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
  654. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  655. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  656. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  657. }
  658. }
  659. }
  660. /******************************************************************************
  661. LightMapTerrainTextureClass
  662. ******************************************************************************/
  663. //-----------------------------------------------------------------------------
  664. // Public Functions
  665. //-----------------------------------------------------------------------------
  666. //=============================================================================
  667. // LightMapTerrainTextureClass::LightMapTerrainTextureClass
  668. //=============================================================================
  669. /** Constructor. Calls parent constructor to load the .tga texture. */
  670. //=============================================================================
  671. LightMapTerrainTextureClass::LightMapTerrainTextureClass(AsciiString name, MipCountType mipLevelCount) :
  672. TextureClass(name.isEmpty()?"TSNoiseUrb.tga":name.str(),name.isEmpty()?"TSNoiseUrb.tga":name.str(), mipLevelCount )
  673. {
  674. }
  675. #define STRETCH_FACTOR ((float)(1/(63.0*MAP_XY_FACTOR/2))) /* covers 63/2 tiles */
  676. //=============================================================================
  677. // LightMapTerrainTextureClass::Apply
  678. //=============================================================================
  679. /** Sets the texture as the current D3D texture, and does some custom setup.
  680. The LightMapTerrainTextureClass may be applied by itself, or with the
  681. CloudMapTerrainTextureClass. This may be applied in either single pass,
  682. as the second texture in the pipe,
  683. or multipass. If stage==0, we are doing multipass and we set up the pipe
  684. for a single texture. If stage==1, then we are doing a single pass, and we
  685. set up the pipe so that we blend onto the cloud map texture in stage 0.
  686. Also, texture is mapped using the x/y coordinates of the map, saving us
  687. yet another set of uv coordinates.
  688. (standard D3D setup, but beyond the scope of W3D). */
  689. //=============================================================================
  690. void LightMapTerrainTextureClass::Apply(unsigned int stage)
  691. {
  692. // Do the base apply.
  693. TextureClass::Apply(stage);
  694. /* previous setup */
  695. if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
  696. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
  697. } else {
  698. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  699. }
  700. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT);
  701. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  702. // Disable 3rd stage just in case.
  703. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
  704. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  705. // Now setup the texture pipeline.
  706. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  707. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT );
  708. if (stage == 0) {
  709. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
  710. //Disable second stage
  711. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  712. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  713. } else {
  714. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE );
  715. }
  716. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  717. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
  718. // Two output coordinates are used.
  719. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
  720. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
  721. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
  722. Matrix4 curView;
  723. DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
  724. D3DXMATRIX inv;
  725. float det;
  726. D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
  727. D3DXMATRIX scale;
  728. D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1);
  729. inv *=scale;
  730. if (stage==0) {
  731. DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4*)&inv));
  732. } if (stage==1) {
  733. DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4*)&inv));
  734. }
  735. if (stage==0) {
  736. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
  737. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR);
  738. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO);
  739. }
  740. }
  741. /******************************************************************************
  742. AlphaEdgeTextureClass
  743. ******************************************************************************/
  744. //-----------------------------------------------------------------------------
  745. // Public Functions
  746. //-----------------------------------------------------------------------------
  747. /**
  748. * AlphaEdgeTextureClass - Generates the alpha edge blending for terrain.
  749. *
  750. */
  751. AlphaEdgeTextureClass::AlphaEdgeTextureClass( int height, MipCountType mipLevelCount) :
  752. // TextureClass("EdgingTemplate.tga","EdgingTemplate.tga", mipLevelCount )
  753. TextureClass(TEXTURE_WIDTH, height, WW3D_FORMAT_A8R8G8B8, mipLevelCount )
  754. {
  755. }
  756. int AlphaEdgeTextureClass::update256(WorldHeightMap *htMap)
  757. {
  758. return 1;
  759. }
  760. int AlphaEdgeTextureClass::update(WorldHeightMap *htMap)
  761. {
  762. // D3DTexture is our texture;
  763. IDirect3DSurface8 *surface_level;
  764. D3DSURFACE_DESC surface_desc;
  765. D3DLOCKED_RECT locked_rect;
  766. DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0, &surface_level));
  767. DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0));
  768. DX8_ErrorCode(surface_level->GetDesc(&surface_desc));
  769. Int tilePixelExtent = TILE_PIXEL_EXTENT; // blend tiles are 1/4 tiles.
  770. // Int tilesPerRow = surface_desc.Width / (tilePixelExtent+8);
  771. // Int numRows = surface_desc.Height/(tilePixelExtent+8);
  772. if (surface_desc.Format == D3DFMT_A8R8G8B8) {
  773. #if 1
  774. #if 1
  775. Int cellX, cellY;
  776. for (cellX = 0; (UnsignedInt)cellX < surface_desc.Width; cellX++) {
  777. for (cellY = 0; cellY < surface_desc.Height; cellY++) {
  778. UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*4;
  779. pBGR[2] = 255-cellY/2;
  780. pBGR[0] = cellX/2;
  781. pBGR[3] = cellX/2; // alpha.
  782. pBGR[3] = 128; // alpha.
  783. }
  784. }
  785. #endif
  786. #if 1
  787. Int tileNdx;
  788. Int pixelBytes = 4;
  789. for (tileNdx=0; tileNdx < htMap->m_numEdgeTiles; tileNdx++) {
  790. TileData *pTile = htMap->getEdgeTile(tileNdx);
  791. if (!pTile) continue;
  792. ICoord2D position = pTile->m_tileLocationInTexture;
  793. if (position.x<=0) continue; // all real edge offsets start at 4. jba.
  794. Int i,j;
  795. Int column = position.x;
  796. for (j=0; j<tilePixelExtent; j++) {
  797. Int row = position.y+j;
  798. UnsignedByte *pBGR = htMap->getEdgeTile(tileNdx)->getRGBDataForWidth(tilePixelExtent);
  799. pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match.
  800. UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) +
  801. (row)*surface_desc.Width*pixelBytes;
  802. pBGRX += column*pixelBytes;
  803. for (i=0; i<tilePixelExtent; i++) {
  804. pBGRX[0] = pBGR[0]; //r
  805. pBGRX[1] = pBGR[1]; //g
  806. pBGRX[2] = pBGR[2]; //b
  807. if (pBGR[0]==0 && pBGR[1]==0 && pBGR[2]==0) {
  808. pBGRX[3] = 0x80;
  809. } else if (pBGR[0]==0xff && pBGR[1]==0xff && pBGR[2]==0xff) {
  810. pBGRX[3] = 0x00;
  811. } else {
  812. pBGRX[3] = 0xff;
  813. }
  814. pBGRX += pixelBytes;
  815. pBGR += TILE_BYTES_PER_PIXEL;
  816. }
  817. }
  818. }
  819. #endif
  820. #endif
  821. }
  822. surface_level->UnlockRect();
  823. surface_level->Release();
  824. DX8_ErrorCode(D3DXFilterTexture(D3DTexture, NULL, 0, D3DX_FILTER_BOX));
  825. return(surface_desc.Height);
  826. }
  827. void AlphaEdgeTextureClass::Apply(unsigned int stage)
  828. {
  829. // Do the base apply.
  830. TextureClass::Apply(stage);
  831. if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
  832. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  833. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  834. } else {
  835. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT);
  836. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT);
  837. }
  838. if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
  839. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
  840. } else {
  841. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  842. }
  843. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
  844. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
  845. // Now setup the texture pipeline.
  846. if (stage==0) {
  847. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  848. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  849. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  850. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  851. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  852. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 1 );
  853. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
  854. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
  855. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
  856. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  857. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  858. } else if (stage==1) {
  859. // Drawing texture through the mask.
  860. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
  861. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  862. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
  863. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE );
  864. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
  865. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
  866. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );
  867. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  868. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1 );
  869. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
  870. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_ONE);
  871. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO);
  872. }
  873. }
  874. /******************************************************************************
  875. CloudMapTerrainTextureClass
  876. ******************************************************************************/
  877. //-----------------------------------------------------------------------------
  878. // Public Functions
  879. //-----------------------------------------------------------------------------
  880. //=============================================================================
  881. // CloudMapTerrainTextureClass::CloudMapTerrainTextureClass
  882. //=============================================================================
  883. /** Constructor. Calls parent constructor to load the .tga texture, and sets
  884. up the "sliding" parameters for the clouds to slide over the terrain. */
  885. //=============================================================================
  886. //@todo - Allow adjustment of the cloud slide rate, and lose the hard coded "cloudmap.tga"
  887. CloudMapTerrainTextureClass::CloudMapTerrainTextureClass(MipCountType mipLevelCount) :
  888. TextureClass("TSCloudMed.tga","TSCloudMed.tga", mipLevelCount )
  889. {
  890. Set_Mip_Mapping( FILTER_TYPE_FAST );
  891. m_xSlidePerSecond = -0.02f;
  892. m_ySlidePerSecond = 1.50f * m_xSlidePerSecond;
  893. m_curTick = 0;
  894. m_xOffset = 0;
  895. m_yOffset = 0;
  896. }
  897. //=============================================================================
  898. // CloudMapTerrainTextureClass::Apply
  899. //=============================================================================
  900. /** Sets the texture as the current D3D texture, and does some custom setup.
  901. The CloudMapTerrainTextureClass may be applied by itself, or with the
  902. LightMapTerrainTexture. This may be applied in either single pass,
  903. as the first texture in the pipe with LightMapTerrainTextureClass as the
  904. second stage of the pape, or multipass. We setup for stage 0, assuming that
  905. we are the only texture, as LightMapTerrainTexture will adjust for multitexture
  906. if it is applied to stage 1.
  907. Also, texture is mapped using the x/y coordinates of the map, saving us
  908. yet another set of uv coordinates.
  909. (standard D3D setup, but beyond the scope of W3D). */
  910. //=============================================================================
  911. void CloudMapTerrainTextureClass::Apply(unsigned int stage)
  912. {
  913. // Do the base apply.
  914. TextureClass::Apply(stage);
  915. /* previous setup */
  916. if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
  917. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
  918. } else {
  919. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  920. }
  921. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  922. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  923. // Now setup the texture pipeline.
  924. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
  925. // Two output coordinates are used.
  926. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
  927. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
  928. DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
  929. Matrix4 curView;
  930. DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView);
  931. D3DXMATRIX inv;
  932. float det;
  933. D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView);
  934. D3DXMATRIX scale;
  935. D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1);
  936. inv *=scale;
  937. D3DXMATRIX offset;
  938. Int delta = m_curTick;
  939. m_curTick = ::GetTickCount();
  940. delta = m_curTick-delta;
  941. m_xOffset += m_xSlidePerSecond*delta/1000;
  942. m_yOffset += m_ySlidePerSecond*delta/1000;
  943. if (m_xOffset > 1) m_xOffset -= 1;
  944. if (m_yOffset > 1) m_yOffset -= 1;
  945. if (m_xOffset < -1) m_xOffset += 1;
  946. if (m_yOffset < -1) m_yOffset += 1;
  947. D3DXMatrixTranslation(&offset, m_xOffset, m_yOffset,0);
  948. inv *= offset;
  949. if (stage==0) {
  950. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  951. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  952. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
  953. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  954. DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4*)&inv));
  955. // Disable 3rd stage just in case.
  956. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
  957. DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  958. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  959. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  960. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
  961. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR);
  962. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO);
  963. } else if (stage==1) {
  964. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  965. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  966. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
  967. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
  968. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  969. DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4*)&inv));
  970. }
  971. }
  972. //=============================================================================
  973. // CloudMapTerrainTextureClass::restore
  974. //=============================================================================
  975. /** Cleans up any custom settings to the texturing pipeline that may not be
  976. understood by w3d. */
  977. //=============================================================================
  978. void CloudMapTerrainTextureClass::restore(void)
  979. {
  980. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  981. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  982. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  983. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  984. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
  985. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
  986. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
  987. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
  988. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  989. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  990. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE );
  991. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  992. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
  993. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
  994. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 0 );
  995. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
  996. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false);
  997. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
  998. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
  999. if (TheGlobalData && !TheGlobalData->m_multiPassTerrain)
  1000. {
  1001. ///@todo: Remove 8-Stage Nvidia hack after drivers are fixed.
  1002. //This method is a backdoor specific to Nvidia based cards. It will fail on
  1003. //other hardware. Allows single pass blend of 2 textures and post modulate diffuse.
  1004. Int i;
  1005. for (i=0; i<8; i++) {
  1006. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_COLOROP, D3DTOP_DISABLE);
  1007. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_TEXCOORDINDEX, i);
  1008. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  1009. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  1010. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
  1011. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  1012. DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
  1013. DX8Wrapper::Set_DX8_Texture(i, NULL);
  1014. }
  1015. }
  1016. }
  1017. /******************************************************************************
  1018. ScorchTextureClass
  1019. ******************************************************************************/
  1020. //-----------------------------------------------------------------------------
  1021. // Public Functions
  1022. //-----------------------------------------------------------------------------
  1023. //=============================================================================
  1024. // ScorchTextureClass::ScorchTextureClass
  1025. //=============================================================================
  1026. /** Constructor. Calls parent constructor to load the .tga texture. */
  1027. //=============================================================================
  1028. /// @todo - get "EXScorch01.tga" from not hard coded location.
  1029. ScorchTextureClass::ScorchTextureClass(MipCountType mipLevelCount) :
  1030. TextureClass("EXScorch01.tga","EXScorch01.tga", mipLevelCount )
  1031. {
  1032. }
  1033. //=============================================================================
  1034. // ScorchTextureClass::Apply
  1035. //=============================================================================
  1036. /** Sets the texture as the current D3D texture, and does some custom setup.
  1037. The ScorchTextureClass is applied by iteself, as it's mesh is a subset of the
  1038. terrain mesh.
  1039. (standard D3D setup, but beyond the scope of W3D). */
  1040. //=============================================================================
  1041. void ScorchTextureClass::Apply(unsigned int stage)
  1042. {
  1043. // Do the base apply.
  1044. TextureClass::Apply(stage);
  1045. // Setup bilinear or trilinear filtering as specified in global data.
  1046. if (TheGlobalData && TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex) {
  1047. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
  1048. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
  1049. } else {
  1050. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT);
  1051. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT);
  1052. }
  1053. if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) {
  1054. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
  1055. } else {
  1056. DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  1057. }
  1058. DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
  1059. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
  1060. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
  1061. // Now setup the texture pipeline.
  1062. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  1063. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  1064. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  1065. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  1066. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 );
  1067. DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true);
  1068. DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
  1069. DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
  1070. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  1071. DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  1072. }