Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
11 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: material.c
  3. *
  4. * Material selection functions.
  5. *
  6. * Copyright (c) 1994 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <sys/types.h>
  14. #include <time.h>
  15. #include <windows.h>
  16. #include <GL/gl.h>
  17. #include "sscommon.h"
  18. //#define NUM_TEA_MATERIALS 24
  19. #define NUM_GOOD_MATERIALS 16 // 'good' ones among the 24 tea materials
  20. //#define NUM_TEX_MATERIALS 4 // materials for texture
  21. int goodMaterials[NUM_GOOD_MATERIALS] = {
  22. EMERALD, JADE, PEARL, RUBY, TURQUOISE, BRASS, BRONZE,
  23. COPPER, GOLD, SILVER, CYAN_PLASTIC, WHITE_PLASTIC, YELLOW_PLASTIC,
  24. CYAN_RUBBER, GREEN_RUBBER, WHITE_RUBBER };
  25. /* materials: emerald, jade, obsidian, pearl, ruby, turquoise
  26. * brass, bronze, chrome, copper, gold, silver
  27. * black, cyan, green, red, white, yellow plastic
  28. * black, cyan, green, red, white, yellow rubber
  29. description: ambient(RGB), diffuse(RGB), specular(RGB), shininess
  30. *
  31. */
  32. // 'tea' materials, from aux teapots program
  33. static GLfloat teaMaterialData[NUM_TEA_MATERIALS][10] =
  34. {
  35. 0.0215f, 0.1745f, 0.0215f,
  36. 0.07568f, 0.61424f, 0.07568f, 0.633f, 0.727811f, 0.633f, 0.6f,
  37. 0.135f, 0.2225f, 0.1575f,
  38. 0.54f, 0.89f, 0.63f, 0.316228f, 0.316228f, 0.316228f, 0.1f,
  39. 0.05375f, 0.05f, 0.06625f, // XX
  40. 0.18275f, 0.17f, 0.22525f, 0.332741f, 0.328634f, 0.346435f, 0.3f,
  41. 0.25f, 0.20725f, 0.20725f,
  42. 1.0f, 0.829f, 0.829f, 0.296648f, 0.296648f, 0.296648f, 0.088f,
  43. 0.1745f, 0.01175f, 0.01175f,
  44. 0.61424f, 0.04136f, 0.04136f, 0.727811f, 0.626959f, 0.626959f, 0.6f,
  45. 0.1f, 0.18725f, 0.1745f,
  46. 0.396f, 0.74151f, 0.69102f, 0.297254f, 0.30829f, 0.306678f, 0.1f,
  47. 0.329412f, 0.223529f, 0.027451f,
  48. 0.780392f, 0.568627f, 0.113725f, 0.992157f, 0.941176f, 0.807843f,
  49. 0.21794872f,
  50. 0.2125f, 0.1275f, 0.054f,
  51. 0.714f, 0.4284f, 0.18144f, 0.393548f, 0.271906f, 0.166721f, 0.2f,
  52. 0.25f, 0.25f, 0.25f, // XX
  53. 0.4f, 0.4f, 0.4f, 0.774597f, 0.774597f, 0.774597f, 0.6f,
  54. 0.19125f, 0.0735f, 0.0225f,
  55. 0.7038f, 0.27048f, 0.0828f, 0.256777f, 0.137622f, 0.086014f, 0.1f,
  56. 0.24725f, 0.1995f, 0.0745f,
  57. 0.75164f, 0.60648f, 0.22648f, 0.628281f, 0.555802f, 0.366065f, 0.4f,
  58. 0.19225f, 0.19225f, 0.19225f,
  59. 0.50754f, 0.50754f, 0.50754f, 0.508273f, 0.508273f, 0.508273f, 0.4f,
  60. 0.0f, 0.0f, 0.0f, 0.01f, 0.01f, 0.01f,
  61. 0.50f, 0.50f, 0.50f, .25f,
  62. 0.0f, 0.1f, 0.06f, 0.0f, 0.50980392f, 0.50980392f,
  63. 0.50196078f, 0.50196078f, 0.50196078f, .25f,
  64. 0.0f, 0.0f, 0.0f,
  65. 0.1f, 0.35f, 0.1f, 0.45f, 0.55f, 0.45f, .25f,
  66. 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, // XX
  67. 0.7f, 0.6f, 0.6f, .25f,
  68. 0.0f, 0.0f, 0.0f, 0.55f, 0.55f, 0.55f,
  69. 0.70f, 0.70f, 0.70f, .25f,
  70. 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f,
  71. 0.60f, 0.60f, 0.50f, .25f,
  72. 0.02f, 0.02f, 0.02f, 0.01f, 0.01f, 0.01f, // XX
  73. 0.4f, 0.4f, 0.4f, .078125f,
  74. 0.0f, 0.05f, 0.05f, 0.4f, 0.5f, 0.5f,
  75. 0.04f, 0.7f, 0.7f, .078125f,
  76. 0.0f, 0.05f, 0.0f, 0.4f, 0.5f, 0.4f,
  77. 0.04f, 0.7f, 0.04f, .078125f,
  78. 0.05f, 0.0f, 0.0f, 0.5f, 0.4f, 0.4f,
  79. 0.7f, 0.04f, 0.04f, .078125f,
  80. 0.05f, 0.05f, 0.05f, 0.5f, 0.5f, 0.5f,
  81. 0.7f, 0.7f, 0.7f, .078125f,
  82. 0.05f, 0.05f, 0.0f, 0.5f, 0.5f, 0.4f,
  83. 0.7f, 0.7f, 0.04f, .078125f
  84. };
  85. // generally white materials for texturing
  86. static GLfloat texMaterialData[NUM_TEX_MATERIALS][10] = {
  87. // bright white
  88. 0.2f, 0.2f, 0.2f,
  89. 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f,
  90. // less bright white
  91. 0.2f, 0.2f, 0.2f,
  92. 0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.5f,
  93. // warmish white
  94. 0.3f, 0.2f, 0.2f,
  95. 1.0f, 0.9f, 0.8f, 1.0f, 0.9f, 0.8f, 0.5f,
  96. // coolish white
  97. 0.2f, 0.2f, 0.3f,
  98. 0.8f, 0.9f, 1.0f, 0.8f, 0.9f, 1.0f, 0.5f
  99. };
  100. MATERIAL Material[NUM_TEA_MATERIALS + NUM_TEX_MATERIALS];
  101. // pure black material
  102. MATERIAL ss_BlackMat = {0.0f};
  103. /**************************************************************************\
  104. * InitMaterials
  105. *
  106. * Initialize MATERIAL structures with data
  107. * - Set alpha to 0.5 for all materials
  108. *
  109. \**************************************************************************/
  110. static void
  111. InitMaterials( MATERIAL *pm, float *pd, int count )
  112. {
  113. int i;
  114. for( i = 0; i < count; i++, pm++ ) {
  115. pm->ka.r = *pd++;
  116. pm->ka.g = *pd++;
  117. pm->ka.b = *pd++;
  118. pm->ka.a = 0.5f;
  119. pm->kd.r = *pd++;
  120. pm->kd.g = *pd++;
  121. pm->kd.b = *pd++;
  122. pm->kd.a = 0.5f;
  123. pm->ks.r = *pd++;
  124. pm->ks.g = *pd++;
  125. pm->ks.b = *pd++;
  126. pm->ks.a = 0.5f;
  127. pm->specExp = *pd++;
  128. }
  129. }
  130. /**************************************************************************\
  131. * ss_InitMaterials
  132. *
  133. * Initialize all materials
  134. *
  135. \**************************************************************************/
  136. void ss_InitMaterials()
  137. {
  138. ss_InitTeaMaterials();
  139. ss_InitTexMaterials();
  140. }
  141. /**************************************************************************\
  142. * ss_InitTeaMaterials
  143. *
  144. * Initialize Material structure with data in TeaMaterialData
  145. *
  146. \**************************************************************************/
  147. void ss_InitTeaMaterials()
  148. {
  149. InitMaterials( Material, teaMaterialData[0], NUM_TEA_MATERIALS );
  150. }
  151. /**************************************************************************\
  152. * ss_InitTexMaterials
  153. *
  154. * Initialize Material structure with data in TexMaterialData (tex materials
  155. * follow the tea materials in Material)
  156. *
  157. \**************************************************************************/
  158. void ss_InitTexMaterials()
  159. {
  160. InitMaterials( Material+NUM_TEA_MATERIALS, texMaterialData[0],
  161. NUM_TEX_MATERIALS );
  162. }
  163. /**************************************************************************\
  164. * ss_SetMaterial
  165. *
  166. * Set specified material with MATERIAL structure
  167. *
  168. \**************************************************************************/
  169. void ss_SetMaterial( MATERIAL *pMat )
  170. {
  171. glMaterialfv( GL_FRONT, GL_AMBIENT, (GLfloat*) &pMat->ka );
  172. glMaterialfv( GL_BACK, GL_AMBIENT, (GLfloat*) &pMat->ka );
  173. glMaterialfv( GL_FRONT, GL_DIFFUSE, (GLfloat *) &pMat->kd );
  174. glMaterialfv( GL_BACK, GL_DIFFUSE, (GLfloat *) &pMat->kd );
  175. glMaterialfv( GL_FRONT, GL_SPECULAR, (GLfloat *) &pMat->ks );
  176. glMaterialfv( GL_BACK, GL_SPECULAR, (GLfloat *) &pMat->ks );
  177. glMaterialf ( GL_FRONT, GL_SHININESS, pMat->specExp*128.0f);
  178. glMaterialf ( GL_BACK, GL_SHININESS, pMat->specExp*128.0f);
  179. }
  180. /**************************************************************************\
  181. * ss_SetMaterialIndex
  182. *
  183. * Set material using its index name
  184. *
  185. \**************************************************************************/
  186. void ss_SetMaterialIndex( int index )
  187. {
  188. if( (index < 0) || (index >= (NUM_TEA_MATERIALS+NUM_TEX_MATERIALS)) )
  189. return;
  190. ss_SetMaterial( &Material[index] );
  191. }
  192. /**************************************************************************\
  193. * ss_CreateMaterialGradient
  194. *
  195. * Given 2 materials and a count, create an incremental material, such
  196. * that adding it 'count' times to the first material will generate the
  197. * 2nd material.
  198. *
  199. \**************************************************************************/
  200. void
  201. ss_CreateMaterialGradient( MATERIAL *matInc, MATERIAL *startMat,
  202. MATERIAL *endMat, int transCount )
  203. {
  204. FLOAT fTransCount;
  205. if( !transCount ) {
  206. *matInc = *endMat;
  207. return;
  208. }
  209. /*
  210. * Add fudge factor to avoid round-off error, which could result in
  211. * invalid material values.
  212. */
  213. #define FMAT_GRAD_FUDGE 1.0001f
  214. fTransCount = (FLOAT) transCount * FMAT_GRAD_FUDGE;
  215. matInc->ka.r = (endMat->ka.r - startMat->ka.r) / fTransCount;
  216. matInc->ka.g = (endMat->ka.g - startMat->ka.g) / fTransCount;
  217. matInc->ka.b = (endMat->ka.b - startMat->ka.b) / fTransCount;
  218. matInc->ks.r = (endMat->ks.r - startMat->ks.r) / fTransCount;
  219. matInc->ks.g = (endMat->ks.g - startMat->ks.g) / fTransCount;
  220. matInc->ks.b = (endMat->ks.b - startMat->ks.b) / fTransCount;
  221. matInc->kd.r = (endMat->kd.r - startMat->kd.r) / fTransCount;
  222. matInc->kd.g = (endMat->kd.g - startMat->kd.g) / fTransCount;
  223. matInc->kd.b = (endMat->kd.b - startMat->kd.b) / fTransCount;
  224. matInc->specExp = (endMat->specExp - startMat->specExp) / fTransCount;
  225. }
  226. /**************************************************************************\
  227. * ss_TransitionMaterial
  228. *
  229. * Given a material, add to it the incremental material, and set the
  230. * result as the current material
  231. *
  232. \**************************************************************************/
  233. void
  234. ss_TransitionMaterial( MATERIAL *transMat, MATERIAL *transMatInc )
  235. {
  236. transMat->ka.r += transMatInc->ka.r;
  237. transMat->ka.g += transMatInc->ka.g;
  238. transMat->ka.b += transMatInc->ka.b;
  239. transMat->kd.r += transMatInc->kd.r;
  240. transMat->kd.g += transMatInc->kd.g;
  241. transMat->kd.b += transMatInc->kd.b;
  242. transMat->ks.r += transMatInc->ks.r;
  243. transMat->ks.g += transMatInc->ks.g;
  244. transMat->ks.b += transMatInc->ks.b;
  245. transMat->specExp += transMatInc->specExp;
  246. ss_SetMaterial( transMat );
  247. }
  248. /**************************************************************************\
  249. * ss_RandomTeaMaterial
  250. *
  251. * Select a random TeaMaterial
  252. * Return ptr to material
  253. *
  254. \**************************************************************************/
  255. MATERIAL *ss_RandomTeaMaterial( BOOL bSet )
  256. {
  257. int index;
  258. MATERIAL *pMat;
  259. index = goodMaterials[ ss_iRand(NUM_GOOD_MATERIALS) ];
  260. pMat = &Material[ index ];
  261. if( bSet )
  262. ss_SetMaterial( pMat );
  263. return pMat;
  264. }
  265. /**************************************************************************\
  266. * ss_RandomTeaMaterialIndex
  267. *
  268. * Select a random TeaMaterial
  269. * Return material index
  270. *
  271. \**************************************************************************/
  272. int ss_RandomTeaMaterialIndex( BOOL bSet )
  273. {
  274. int index;
  275. index = goodMaterials[ ss_iRand(NUM_GOOD_MATERIALS) ];
  276. if( bSet )
  277. ss_SetMaterial( &Material[ index ] );
  278. return index;
  279. }
  280. /**************************************************************************\
  281. * ss_RandomTexMaterial
  282. *
  283. * Select a random TexMaterial
  284. * Return ptr to material
  285. *
  286. \**************************************************************************/
  287. MATERIAL *ss_RandomTexMaterial( BOOL bSet )
  288. {
  289. int index;
  290. MATERIAL *pMat;
  291. index = NUM_TEA_MATERIALS + ss_iRand(NUM_TEX_MATERIALS);
  292. pMat = &Material[ index ];
  293. if( bSet )
  294. ss_SetMaterial( pMat );
  295. return pMat;
  296. }
  297. /**************************************************************************\
  298. * ss_RandomTexMaterialIndex
  299. *
  300. * Select a random TexMaterial
  301. *
  302. \**************************************************************************/
  303. int ss_RandomTexMaterialIndex( BOOL bSet )
  304. {
  305. int index;
  306. index = NUM_TEA_MATERIALS + ss_iRand(NUM_TEX_MATERIALS);
  307. if( bSet )
  308. ss_SetMaterial( &Material[ index ] );
  309. return index;
  310. }