matrixmapper.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. ** Command & Conquer Renegade(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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWPhys *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/matrixmapper.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Greg_h $*
  29. * *
  30. * $Modtime:: 6/21/01 10:32a $*
  31. * *
  32. * $Revision:: 10 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * MatrixMapperClass::MatrixMapperClass -- Constructor *
  37. * MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
  38. * MatrixMapperClass::Update_View_To_Pixel_Transform -- recomputes ViewToPixel *
  39. * MatrixMapperClass::Compute_Texture_Coordinate -- compute a single texture coord *
  40. * MatrixMapperClass::isActive -- check if this mapper should be active *
  41. * MatrixMapperClass::process -- process the given VertexPipe *
  42. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  43. #include "matrixmapper.h"
  44. #include "dx8wrapper.h"
  45. /***********************************************************************************************
  46. * MatrixMapperClass::MatrixMapperClass -- Constructor *
  47. * *
  48. * Initializes the member variables to defaults *
  49. * *
  50. * INPUT: *
  51. * *
  52. * OUTPUT: *
  53. * *
  54. * WARNINGS: *
  55. * *
  56. * HISTORY: *
  57. * 11/13/99 gth : created *
  58. *=============================================================================================*/
  59. MatrixMapperClass::MatrixMapperClass(int stage) :
  60. TextureMapperClass(stage),
  61. Flags(0),
  62. ViewToTexture(true),
  63. ViewToPixel(true),
  64. GradientUCoord(0.5f)
  65. {
  66. ViewSpaceProjectionNormal = Vector3(0.0f,0.0f,0.0f);
  67. }
  68. /***********************************************************************************************
  69. * MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
  70. * *
  71. * INPUT: *
  72. * *
  73. * OUTPUT: *
  74. * *
  75. * WARNINGS: *
  76. * *
  77. * HISTORY: *
  78. * 6/20/2001 gth : created *
  79. *=============================================================================================*/
  80. void MatrixMapperClass::Set_Texture_Transform(const Matrix3D & view_to_texture,float texsize)
  81. {
  82. ViewToTexture = Matrix4(view_to_texture);
  83. Update_View_To_Pixel_Transform(texsize);
  84. }
  85. /***********************************************************************************************
  86. * MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
  87. * *
  88. * INPUT: *
  89. * *
  90. * OUTPUT: *
  91. * *
  92. * WARNINGS: *
  93. * *
  94. * HISTORY: *
  95. * 11/13/99 gth : Created. *
  96. *=============================================================================================*/
  97. void MatrixMapperClass::Set_Texture_Transform(const Matrix4 & view_to_texture,float texsize)
  98. {
  99. ViewToTexture=view_to_texture;
  100. Update_View_To_Pixel_Transform(texsize);
  101. }
  102. /***********************************************************************************************
  103. * MatrixMapperClass::Update_View_To_Pixel_Transform -- recomputes ViewToPixel *
  104. * *
  105. * INPUT: *
  106. * *
  107. * OUTPUT: *
  108. * *
  109. * WARNINGS: *
  110. * *
  111. * HISTORY: *
  112. * 1/4/00 gth : Created. *
  113. *=============================================================================================*/
  114. void MatrixMapperClass::Update_View_To_Pixel_Transform(float tex_size)
  115. {
  116. /*
  117. ** Create a ViewToPixel matrix which also does all of the offseting and flipping that has
  118. ** to take place to get the actual texture coordinates.
  119. **
  120. ** Here is a description of the math:
  121. ** If you transform eye-space points with the ViewToTexture matrix, you then need to compute:
  122. ** s = ((x/w) + 1.0f) * 0.5f * ((texwid-2)/texwid)
  123. ** t = (1.0f - (y/w)) * 0.5f * ((texwid-2)/texwid)
  124. **
  125. ** Let K = 0.5 * ((texwid-2)/texwid), Then:
  126. ** ((x/w) + 1.0f) * K = (K*x + K*w) / w
  127. ** (1.0f - (y/w)) * K = (-K*y + K*w) / w
  128. **
  129. ** This leads to the following matrix (The KOOK matrix!)
  130. ** | K 0 0 K |
  131. ** | 0 -K 0 K |
  132. ** | 0 0 1 0 |
  133. ** | 0 0 0 1 |
  134. **
  135. ** The code below manually "optimally" pre-multiplies this matrix with the ViewToTexture matrix
  136. **
  137. ** In addition, the z-coordinate is modified so that it goes from 0 to 1 rather than -1 to +1.
  138. ** It can also be flipped if the INVERT_DEPTH_GRADIENT flag is on.
  139. */
  140. float k = 0.5 * (tex_size - 2.0f) / tex_size;
  141. ViewToPixel[0][0] = k * ViewToTexture[0][0] + k * ViewToTexture[3][0];
  142. ViewToPixel[0][1] = k * ViewToTexture[0][1] + k * ViewToTexture[3][1];
  143. ViewToPixel[0][2] = k * ViewToTexture[0][2] + k * ViewToTexture[3][2];
  144. ViewToPixel[0][3] = k * ViewToTexture[0][3] + k * ViewToTexture[3][3];
  145. ViewToPixel[1][0] = -k * ViewToTexture[1][0] + k * ViewToTexture[3][0];
  146. ViewToPixel[1][1] = -k * ViewToTexture[1][1] + k * ViewToTexture[3][1];
  147. ViewToPixel[1][2] = -k * ViewToTexture[1][2] + k * ViewToTexture[3][2];
  148. ViewToPixel[1][3] = -k * ViewToTexture[1][3] + k * ViewToTexture[3][3];
  149. if (Get_Flag(INVERT_DEPTH_GRADIENT)) {
  150. ViewToPixel[2][0] = -0.5f * ViewToTexture[2][0] + 0.5f * ViewToTexture[3][0];
  151. ViewToPixel[2][1] = -0.5f * ViewToTexture[2][1] + 0.5f * ViewToTexture[3][1];
  152. ViewToPixel[2][2] = -0.5f * ViewToTexture[2][2] + 0.5f * ViewToTexture[3][2];
  153. ViewToPixel[2][3] = -0.5f * ViewToTexture[2][3] + 0.5f * ViewToTexture[3][3];
  154. } else {
  155. ViewToPixel[2][0] = 0.5f * ViewToTexture[2][0] + 0.5f * ViewToTexture[3][0];
  156. ViewToPixel[2][1] = 0.5f * ViewToTexture[2][1] + 0.5f * ViewToTexture[3][1];
  157. ViewToPixel[2][2] = 0.5f * ViewToTexture[2][2] + 0.5f * ViewToTexture[3][2];
  158. ViewToPixel[2][3] = 0.5f * ViewToTexture[2][3] + 0.5f * ViewToTexture[3][3];
  159. }
  160. ViewToPixel[3] = ViewToTexture[3];
  161. /*
  162. ** Store the view space negative z vector for lighting effects
  163. */
  164. ViewSpaceProjectionNormal.X = -ViewToTexture[2][0];
  165. ViewSpaceProjectionNormal.Y = -ViewToTexture[2][1];
  166. ViewSpaceProjectionNormal.Z = -ViewToTexture[2][2];
  167. ViewSpaceProjectionNormal.Normalize();
  168. }
  169. /***********************************************************************************************
  170. * MatrixMapperClass::Compute_Texture_Coordinate -- compute a single texture coord *
  171. * *
  172. * INPUT: *
  173. * point - 3D point to calculate the texture coordinate for *
  174. * set_stq - pointer to texture coordinate, s,t will be stored in X,Y. q will be stored in Z *
  175. * *
  176. * OUTPUT: *
  177. * *
  178. * WARNINGS: *
  179. * *
  180. * HISTORY: *
  181. * 1/25/00 gth : Created. *
  182. *=============================================================================================*/
  183. void MatrixMapperClass::Compute_Texture_Coordinate(const Vector3 & point,Vector3 * set_stq)
  184. {
  185. set_stq->X = ViewToPixel[0][0]*point.X + ViewToPixel[0][1]*point.Y + ViewToPixel[0][2]*point.Z + ViewToPixel[0][3];
  186. set_stq->Y = ViewToPixel[1][0]*point.X + ViewToPixel[1][1]*point.Y + ViewToPixel[1][2]*point.Z + ViewToPixel[1][3];
  187. set_stq->Z = ViewToPixel[3][0]*point.X + ViewToPixel[3][1]*point.Y + ViewToPixel[3][2]*point.Z + ViewToPixel[3][3];
  188. }
  189. void MatrixMapperClass::Apply(int uv_array_index)
  190. {
  191. Matrix4 m;
  192. switch (Type)
  193. {
  194. case ORTHO_PROJECTION:
  195. /*
  196. ** Orthographic projection
  197. */
  198. DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),ViewToPixel);
  199. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
  200. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
  201. break;
  202. case PERSPECTIVE_PROJECTION:
  203. /*
  204. ** Perspective projection
  205. */
  206. m[0]=ViewToPixel[0];
  207. m[1]=ViewToPixel[1];
  208. m[2]=ViewToPixel[3];
  209. DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
  210. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
  211. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_PROJECTED|D3DTTFF_COUNT3);
  212. break;
  213. case DEPTH_GRADIENT:
  214. /*
  215. ** Depth gradient, Set up second stage texture coordinates to
  216. ** apply a depth gradient to the projection. Note that the
  217. ** depth values have been set up to vary from 0 to 1 in the
  218. ** Update_View_To_Pixel_Transform function.
  219. */
  220. m[0].Set(0,0,0,GradientUCoord);
  221. m[1]=ViewToPixel[2];
  222. DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
  223. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
  224. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
  225. break;
  226. case NORMAL_GRADIENT:
  227. /*
  228. ** Normal Gradient, Set up the second stage texture coordinates to
  229. ** apply a gradient based on the dot product of the vertex normal
  230. ** and the projection direction. (NOTE: this is basically texture-
  231. ** based diffuse lighting!)
  232. */
  233. m[0].Set(0,0,0,GradientUCoord);
  234. m[1].Set(ViewSpaceProjectionNormal.X,ViewSpaceProjectionNormal.Y,ViewSpaceProjectionNormal.Z, 0);
  235. DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
  236. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
  237. DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
  238. break;
  239. }
  240. }