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.

966 lines
25 KiB

  1. /*
  2. ** Copyright 1991,1992, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. */
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #include <namesint.h>
  21. #include <math.h>
  22. #include <glmath.h>
  23. /*
  24. ** Some math routines that are optimized in assembly
  25. */
  26. #define __GL_M_LN2_INV ((__GLfloat) (1.0 / 0.69314718055994530942))
  27. #define __GL_M_SQRT2 ((__GLfloat) 1.41421356237309504880)
  28. /************************************************************************/
  29. __GLtextureParamState * FASTCALL __glLookUpTextureParams(__GLcontext *gc, GLenum target)
  30. {
  31. switch (target) {
  32. case GL_TEXTURE_1D:
  33. return &gc->state.texture.texture[2].params;
  34. case GL_TEXTURE_2D:
  35. return &gc->state.texture.texture[3].params;
  36. default:
  37. return 0;
  38. }
  39. }
  40. __GLtextureObjectState * FASTCALL __glLookUpTextureTexobjs(__GLcontext *gc,
  41. GLenum target)
  42. {
  43. switch (target) {
  44. case GL_TEXTURE_1D:
  45. return &gc->state.texture.texture[2].texobjs;
  46. case GL_TEXTURE_2D:
  47. return &gc->state.texture.texture[3].texobjs;
  48. default:
  49. return 0;
  50. }
  51. }
  52. __GLtexture * FASTCALL __glLookUpTexture(__GLcontext *gc, GLenum target)
  53. {
  54. switch (target) {
  55. case GL_PROXY_TEXTURE_1D:
  56. return &gc->texture.texture[0]->map;
  57. case GL_PROXY_TEXTURE_2D:
  58. return &gc->texture.texture[1]->map;
  59. case GL_TEXTURE_1D:
  60. return &gc->texture.texture[2]->map;
  61. case GL_TEXTURE_2D:
  62. return &gc->texture.texture[3]->map;
  63. default:
  64. return 0;
  65. }
  66. }
  67. __GLtextureObject * FASTCALL __glLookUpTextureObject(__GLcontext *gc, GLenum target)
  68. {
  69. switch (target) {
  70. case GL_TEXTURE_1D:
  71. return gc->texture.boundTextures[2];
  72. case GL_TEXTURE_2D:
  73. return gc->texture.boundTextures[3];
  74. default:
  75. return 0;
  76. }
  77. }
  78. /************************************************************************/
  79. /*
  80. * Set palette subdivision parameters
  81. */
  82. void FASTCALL __glSetPaletteSubdivision(__GLtexture *tex, GLsizei subdiv)
  83. {
  84. tex->paletteSize = subdiv;
  85. tex->paletteDivShift = __glIntLog2(subdiv);
  86. tex->paletteDivision = (tex->paletteTotalSize >> tex->paletteDivShift)-1;
  87. }
  88. /*
  89. * Initialize palette portion of a texture
  90. */
  91. GLboolean FASTCALL __glInitTexturePalette(__GLcontext *gc, __GLtexture *tex)
  92. {
  93. #ifdef GL_EXT_paletted_texture
  94. tex->paletteBaseFormat = GL_RGBA;
  95. tex->paletteRequestedFormat = GL_RGBA;
  96. tex->paletteTotalSize = 1;
  97. __glSetPaletteSubdivision(tex, tex->paletteTotalSize);
  98. tex->paletteTotalData = GCALLOC(gc, sizeof(RGBQUAD));
  99. tex->paletteData = tex->paletteTotalData;
  100. if (tex->paletteTotalData != NULL)
  101. {
  102. *(DWORD *)&tex->paletteTotalData[0] = 0xffffffff;
  103. return GL_TRUE;
  104. }
  105. else
  106. {
  107. return GL_FALSE;
  108. }
  109. #else
  110. return GL_TRUE;
  111. #endif
  112. }
  113. /*
  114. ** Initialize everything in a texture object except the textureMachine.
  115. */
  116. GLboolean FASTCALL __glInitTextureObject(__GLcontext *gc,
  117. __GLtextureObject *texobj,
  118. GLuint name, GLuint targetIndex)
  119. {
  120. ASSERTOPENGL(NULL != texobj, "No texobj\n");
  121. texobj->targetIndex = targetIndex;
  122. texobj->resident = GL_FALSE;
  123. texobj->texture.map.texobjs.name = name;
  124. texobj->texture.map.texobjs.priority = 1.0;
  125. texobj->lowerPriority = NULL;
  126. texobj->higherPriority = NULL;
  127. texobj->loadKey = 0;
  128. return __glInitTexturePalette(gc, &texobj->texture.map);
  129. }
  130. void __glCleanupTexture(__GLcontext *gc, __GLtexture *tex,
  131. GLboolean freeBuffers)
  132. {
  133. GLint level, maxLevel;
  134. if (tex->level != NULL)
  135. {
  136. if (freeBuffers)
  137. {
  138. maxLevel = gc->constants.maxMipMapLevel;
  139. for (level = 0; level < maxLevel; level++)
  140. {
  141. if (tex->level[level].buffer != NULL)
  142. {
  143. GCFREE(gc, tex->level[level].buffer);
  144. }
  145. }
  146. }
  147. GCFREE(gc, tex->level);
  148. }
  149. #ifdef GL_EXT_paletted_texture
  150. if (tex->paletteTotalData != NULL)
  151. {
  152. GCFREE(gc, tex->paletteTotalData);
  153. }
  154. #endif
  155. }
  156. GLvoid FASTCALL __glCleanupTexObj(__GLcontext *gc, void *pData)
  157. {
  158. __GLtextureObject *texobj = (__GLtextureObject *)pData;
  159. // The last context to clean up shared state sets shared to NULL
  160. // so don't depend on it being non-NULL
  161. if (gc->texture.shared != NULL)
  162. {
  163. __glTexPriListRemove(gc, texobj, GL_TRUE);
  164. }
  165. __glCleanupTexture(gc, &texobj->texture.map, GL_TRUE);
  166. GCFREE(gc, texobj);
  167. }
  168. GLvoid WINAPIV __glDisposeTexObj(__GLcontext *gc, void *pData)
  169. {
  170. __GLtextureObject *texobj = (__GLtextureObject *)pData;
  171. #if DBG
  172. if (gc->texture.shared != NULL)
  173. {
  174. __GL_NAMES_ASSERT_LOCKED(gc->texture.shared->namesArray);
  175. }
  176. #endif
  177. texobj->refcount--;
  178. ASSERTOPENGL(texobj->refcount >= 0, "Invalid refcount\n");
  179. if (texobj->refcount == 0) {
  180. __glCleanupTexObj(gc, pData);
  181. }
  182. }
  183. static __GLnamesArrayTypeInfo texTypeInfo =
  184. {
  185. NULL, /* ptr to empty data struct */
  186. sizeof(__GLtextureObject), /* dataSize */
  187. __glDisposeTexObj, /* free callback */
  188. NULL /* alloc callback */
  189. };
  190. void FASTCALL __glEarlyInitTextureState(__GLcontext *gc)
  191. {
  192. GLint numTextures, numEnvs;
  193. GLint i,maxMipMapLevel;
  194. __GLtextureObject *texobj;
  195. /* XXX Override device dependent values */
  196. gc->constants.numberOfTextures = 4;
  197. gc->constants.maxTextureSize = 1 << (gc->constants.maxMipMapLevel - 1);
  198. /* Allocate memory based on number of textures supported */
  199. numTextures = gc->constants.numberOfTextures;
  200. numEnvs = gc->constants.numberOfTextureEnvs;
  201. gc->state.texture.texture = (__GLperTextureState*)
  202. GCALLOCZ(gc, numTextures*sizeof(__GLperTextureState));
  203. gc->texture.texture = (__GLperTextureMachine**)
  204. GCALLOCZ(gc, numTextures*sizeof(__GLperTextureMachine*));
  205. #ifdef NT
  206. if (gc->texture.texture == NULL)
  207. {
  208. return;
  209. }
  210. #endif
  211. gc->state.texture.env = (__GLtextureEnvState*)
  212. GCALLOCZ(gc, numEnvs*sizeof(__GLtextureEnvState));
  213. /*
  214. ** Init texture object structures.
  215. ** The default textures need to be turned into texture objects
  216. ** and stored away in the namesArray so they can be retrieved.
  217. ** Normally a texture object has only one textureMachine allocated
  218. ** with it because it supports only one object. The default texture
  219. ** texture object is special in that its textureMachine is an array
  220. ** of textureMachines, one for each target.
  221. */
  222. gc->texture.shared = GCALLOCZ(gc, sizeof(__GLsharedTextureState));
  223. if (gc->texture.shared == NULL)
  224. {
  225. return;
  226. }
  227. if (NULL == gc->texture.shared->namesArray) {
  228. gc->texture.shared->namesArray = __glNamesNewArray(gc, &texTypeInfo);
  229. }
  230. maxMipMapLevel = gc->constants.maxMipMapLevel;
  231. /*
  232. ** Set up the dummy texture objects for the default textures.
  233. ** Because the default textures are not shared, they should
  234. ** not be hung off of the namesArray structure.
  235. */
  236. gc->texture.defaultTextures = (__GLtextureObject *)GCALLOCZ
  237. (gc, numTextures*sizeof(__GLtextureObject));
  238. if (gc->texture.defaultTextures == NULL)
  239. {
  240. return;
  241. }
  242. /* allocate the boundTextures array */
  243. gc->texture.boundTextures = (__GLtextureObject **)GCALLOCZ
  244. (gc, numTextures*sizeof(__GLtextureObject *));
  245. if (gc->texture.boundTextures == NULL)
  246. {
  247. return;
  248. }
  249. // Allocate DirectDraw texture surface pointers
  250. gc->texture.ddtex.pdds = (LPDIRECTDRAWSURFACE *)GCALLOCZ
  251. (gc, maxMipMapLevel*sizeof(LPDIRECTDRAWSURFACE));
  252. if (gc->texture.ddtex.pdds == NULL)
  253. {
  254. return;
  255. }
  256. if (!__glInitTextureObject(gc, &gc->texture.ddtex.texobj, __GL_TEX_DDRAW,
  257. __GL_TEX_TARGET_INDEX_2D))
  258. {
  259. return;
  260. }
  261. gc->texture.ddtex.texobj.refcount = 1;
  262. gc->texture.ddtex.texobj.texture.map.level = (__GLmipMapLevel*)
  263. GCALLOCZ(gc, maxMipMapLevel*sizeof(__GLmipMapLevel));
  264. texobj = gc->texture.defaultTextures;
  265. for (i=0; i < numTextures; i++, texobj++) {
  266. __glInitTextureObject(gc, texobj, 0/*name*/, i/*targetIndex*/);
  267. ASSERTOPENGL(texobj->texture.map.texobjs.name == 0,
  268. "Non-default texture at init time\n");
  269. /*
  270. ** The refcount is unused because default textures aren't
  271. ** shared.
  272. */
  273. texobj->refcount = 1;
  274. /*
  275. ** Install the default textures into the gc.
  276. */
  277. gc->texture.texture[i] = &(texobj->texture);
  278. gc->texture.boundTextures[i] = texobj;
  279. /* Allocate memory based on max mipmap level supported */
  280. texobj->texture.map.level = (__GLmipMapLevel*)
  281. GCALLOCZ(gc, maxMipMapLevel*sizeof(__GLmipMapLevel));
  282. if (texobj->texture.map.level == NULL)
  283. {
  284. return;
  285. }
  286. __glTexPriListAdd(gc, texobj, GL_TRUE);
  287. }
  288. }
  289. /*
  290. ** This routine is used to initialize a texture object.
  291. ** Texture objects must be initialized exactly the way the default
  292. ** textures are initialized at startup of the library.
  293. */
  294. void FASTCALL __glInitTextureMachine(__GLcontext *gc, GLuint targetIndex,
  295. __GLperTextureMachine *ptm,
  296. GLboolean allocLevels)
  297. {
  298. GLint level, maxMipMapLevel;
  299. ptm->map.gc = gc;
  300. /*
  301. ** Can't copy the params currently in the gc state.texture params,
  302. ** because they might not be at init conditions.
  303. */
  304. ptm->map.params.sWrapMode = GL_REPEAT;
  305. ptm->map.params.tWrapMode = GL_REPEAT;
  306. ptm->map.params.minFilter = GL_NEAREST_MIPMAP_LINEAR;
  307. ptm->map.params.magFilter = GL_LINEAR;
  308. switch (targetIndex) {
  309. case 0:
  310. ptm->map.dim = 1;
  311. ptm->map.createLevel = __glCreateProxyLevel;
  312. break;
  313. case 1:
  314. ptm->map.dim = 2;
  315. ptm->map.createLevel = __glCreateProxyLevel;
  316. break;
  317. case 2:
  318. ptm->map.dim = 1;
  319. ptm->map.createLevel = __glCreateLevel;
  320. break;
  321. case 3:
  322. ptm->map.dim = 2;
  323. ptm->map.createLevel = __glCreateLevel;
  324. break;
  325. default:
  326. break;
  327. }
  328. maxMipMapLevel = gc->constants.maxMipMapLevel;
  329. if (allocLevels)
  330. {
  331. ptm->map.level = (__GLmipMapLevel*)
  332. GCALLOCZ(gc, maxMipMapLevel*sizeof(__GLmipMapLevel));
  333. if (ptm->map.level == NULL)
  334. {
  335. return;
  336. }
  337. }
  338. /* Init each texture level */
  339. for (level = 0; level < maxMipMapLevel; level++) {
  340. ptm->map.level[level].requestedFormat = 1;
  341. }
  342. }
  343. void FASTCALL __glInitTextureState(__GLcontext *gc)
  344. {
  345. __GLperTextureState *pts;
  346. __GLtextureEnvState *tes;
  347. __GLperTextureMachine **ptm;
  348. GLint i, numTextures, numEnvs;
  349. numTextures = gc->constants.numberOfTextures;
  350. numEnvs = gc->constants.numberOfTextureEnvs;
  351. gc->state.current.texture.w = __glOne;
  352. /* Init each texture environment state */
  353. tes = &gc->state.texture.env[0];
  354. for (i = 0; i < numEnvs; i++, tes++) {
  355. tes->mode = GL_MODULATE;
  356. }
  357. /* Init each textures state */
  358. pts = &gc->state.texture.texture[0];
  359. ptm = gc->texture.texture;
  360. for (i = 0; i < numTextures; i++, pts++, ptm++) {
  361. /* Init client state */
  362. pts->texobjs.name = 0;
  363. pts->texobjs.priority = 1.0;
  364. /* Init machine state */
  365. __glInitTextureMachine(gc, i, *ptm, GL_FALSE);
  366. pts->params = (*ptm)->map.params;
  367. }
  368. /* Init rest of texture state */
  369. gc->state.texture.s.mode = GL_EYE_LINEAR;
  370. gc->state.texture.s.eyePlaneEquation.x = __glOne;
  371. gc->state.texture.s.objectPlaneEquation.x = __glOne;
  372. gc->state.texture.t.mode = GL_EYE_LINEAR;
  373. gc->state.texture.t.eyePlaneEquation.y = __glOne;
  374. gc->state.texture.t.objectPlaneEquation.y = __glOne;
  375. gc->state.texture.r.mode = GL_EYE_LINEAR;
  376. gc->state.texture.q.mode = GL_EYE_LINEAR;
  377. // Initialize DirectDraw texture
  378. __glInitTextureMachine(gc, __GL_TEX_TARGET_INDEX_2D,
  379. &gc->texture.ddtex.texobj.texture, GL_FALSE);
  380. }
  381. void __glFreeSharedTextureState(__GLcontext *gc)
  382. {
  383. #ifdef NT
  384. __glNamesLockArray(gc, gc->texture.shared->namesArray);
  385. gc->texture.shared->namesArray->refcount--;
  386. if (gc->texture.shared->namesArray->refcount == 0)
  387. {
  388. __GLsharedTextureState *shared;
  389. __glTexPriListUnloadAll(gc);
  390. // NULL the shared pointer first, preventing its reuse
  391. // after we unlock it. We need to unlock before we free it
  392. // because the critical section will be cleaned up in the
  393. // free
  394. shared = gc->texture.shared;
  395. gc->texture.shared = NULL;
  396. __glNamesFreeArray(gc, shared->namesArray);
  397. GCFREE(gc, shared);
  398. }
  399. else
  400. {
  401. __glNamesUnlockArray(gc, gc->texture.shared->namesArray);
  402. gc->texture.shared = NULL;
  403. }
  404. #else
  405. gc->texture.namesArray->refcount--;
  406. if (gc->texture.namesArray->refcount == 0)
  407. {
  408. __glNamesFreeArray(gc, gc->texture.namesArray);
  409. }
  410. gc->texture.namesArray = NULL;
  411. #endif
  412. }
  413. void FASTCALL __glFreeTextureState(__GLcontext *gc)
  414. {
  415. __GLperTextureMachine **ptm;
  416. GLint i, level, numTextures;
  417. /*
  418. ** Clean up all allocs associated with texture objects.
  419. */
  420. numTextures = gc->constants.numberOfTextures;
  421. ptm = gc->texture.texture;
  422. for (i = 0; i < numTextures; i++, ptm++)
  423. {
  424. // If the texture selected is a texture object, unbind it
  425. // This protects any shared texture objects plus it selects
  426. // the default texture so it gets cleaned up
  427. if ( (*ptm) != NULL)
  428. {
  429. if ((*ptm)->map.texobjs.name != 0)
  430. {
  431. __glBindTexture(gc, i, 0, GL_FALSE);
  432. }
  433. ASSERTOPENGL((*ptm)->map.texobjs.name == 0,
  434. "Texture object still bound during cleanup");
  435. }
  436. // Pull the default texture out of the priority list.
  437. // If we failed partway through initialization we may not
  438. // have added the texture to the list so we need to check
  439. // whether it is appropriate to call remove.
  440. if (gc->texture.defaultTextures != NULL)
  441. {
  442. if (gc->texture.defaultTextures[i].texture.map.level != NULL)
  443. {
  444. __glTexPriListRemove(gc, gc->texture.defaultTextures+i,
  445. GL_FALSE);
  446. }
  447. }
  448. if ( (*ptm) != NULL)
  449. {
  450. __glCleanupTexture(gc, &(*ptm)->map, GL_TRUE);
  451. }
  452. }
  453. __glFreeSharedTextureState(gc);
  454. GCFREE(gc, gc->texture.texture);
  455. GCFREE(gc, gc->texture.boundTextures);
  456. GCFREE(gc, gc->texture.defaultTextures);
  457. GCFREE(gc, gc->state.texture.texture);
  458. GCFREE(gc, gc->state.texture.env);
  459. gc->texture.texture = NULL;
  460. gc->texture.boundTextures = NULL;
  461. gc->texture.defaultTextures = NULL;
  462. gc->state.texture.texture = NULL;
  463. gc->state.texture.env = NULL;
  464. // Free DirectDraw texture state
  465. GCFREE(gc, gc->texture.ddtex.pdds);
  466. gc->texture.ddtex.pdds = NULL;
  467. __glCleanupTexture(gc, &gc->texture.ddtex.texobj.texture.map, GL_FALSE);
  468. }
  469. /************************************************************************/
  470. void APIPRIVATE __glim_TexGenfv(GLenum coord, GLenum pname, const GLfloat pv[])
  471. {
  472. __GLtextureCoordState *tcs;
  473. __GLtransform *tr;
  474. __GL_SETUP_NOT_IN_BEGIN();
  475. switch (coord) {
  476. case GL_S: tcs = &gc->state.texture.s; break;
  477. case GL_T: tcs = &gc->state.texture.t; break;
  478. case GL_R: tcs = &gc->state.texture.r; break;
  479. case GL_Q: tcs = &gc->state.texture.q; break;
  480. default:
  481. __glSetError(GL_INVALID_ENUM);
  482. return;
  483. }
  484. switch (pname) {
  485. case GL_TEXTURE_GEN_MODE:
  486. switch (((GLenum) FTOL(pv[0]))) {
  487. case GL_EYE_LINEAR:
  488. case GL_OBJECT_LINEAR:
  489. tcs->mode = (GLenum) FTOL(pv[0]);
  490. break;
  491. case GL_SPHERE_MAP:
  492. if ((coord == GL_R) || (coord == GL_Q)) {
  493. __glSetError(GL_INVALID_ENUM);
  494. return;
  495. }
  496. tcs->mode = (GLenum) FTOL(pv[0]);
  497. break;
  498. default:
  499. __glSetError(GL_INVALID_ENUM);
  500. return;
  501. }
  502. break;
  503. case GL_OBJECT_PLANE:
  504. tcs->objectPlaneEquation.x = pv[0];
  505. tcs->objectPlaneEquation.y = pv[1];
  506. tcs->objectPlaneEquation.z = pv[2];
  507. tcs->objectPlaneEquation.w = pv[3];
  508. break;
  509. case GL_EYE_PLANE:
  510. #ifdef NT
  511. tr = gc->transform.modelView;
  512. if (tr->flags & XFORM_UPDATE_INVERSE)
  513. __glComputeInverseTranspose(gc, tr);
  514. (*tr->inverseTranspose.xf4)(&tcs->eyePlaneEquation, pv,
  515. &tr->inverseTranspose);
  516. #else
  517. /*XXX transform should not be in generic code */
  518. tcs->eyePlaneSet.x = pv[0];
  519. tcs->eyePlaneSet.y = pv[1];
  520. tcs->eyePlaneSet.z = pv[2];
  521. tcs->eyePlaneSet.w = pv[3];
  522. tr = gc->transform.modelView;
  523. if (tr->flags & XFORM_UPDATE_INVERSE) {
  524. (*gc->procs.computeInverseTranspose)(gc, tr);
  525. }
  526. (*tr->inverseTranspose.xf4)(&tcs->eyePlaneEquation,
  527. &tcs->eyePlaneSet.x,
  528. &tr->inverseTranspose);
  529. #endif
  530. break;
  531. default:
  532. __glSetError(GL_INVALID_ENUM);
  533. return;
  534. }
  535. __GL_DELAY_VALIDATE(gc);
  536. MCD_STATE_DIRTY(gc, TEXGEN);
  537. }
  538. /************************************************************************/
  539. void APIPRIVATE __glim_TexParameterfv(GLenum target, GLenum pname, const GLfloat pv[])
  540. {
  541. __GLtextureParamState *pts;
  542. GLenum e;
  543. GLboolean bTexState = GL_TRUE;
  544. __GL_SETUP_NOT_IN_BEGIN();
  545. pts = __glLookUpTextureParams(gc, target);
  546. if (!pts) {
  547. bad_enum:
  548. bTexState = GL_FALSE;
  549. __glSetError(GL_INVALID_ENUM);
  550. return;
  551. }
  552. switch (pname) {
  553. case GL_TEXTURE_WRAP_S:
  554. switch (e = (GLenum) FTOL(pv[0])) {
  555. case GL_REPEAT:
  556. case GL_CLAMP:
  557. pts->sWrapMode = e;
  558. break;
  559. default:
  560. goto bad_enum;
  561. }
  562. break;
  563. case GL_TEXTURE_WRAP_T:
  564. switch (e = (GLenum) FTOL(pv[0])) {
  565. case GL_REPEAT:
  566. case GL_CLAMP:
  567. pts->tWrapMode = e;
  568. break;
  569. default:
  570. goto bad_enum;
  571. }
  572. break;
  573. case GL_TEXTURE_MIN_FILTER:
  574. switch (e = (GLenum)FTOL(pv[0])) {
  575. case GL_NEAREST:
  576. case GL_LINEAR:
  577. case GL_NEAREST_MIPMAP_NEAREST:
  578. case GL_LINEAR_MIPMAP_NEAREST:
  579. case GL_NEAREST_MIPMAP_LINEAR:
  580. case GL_LINEAR_MIPMAP_LINEAR:
  581. pts->minFilter = e;
  582. break;
  583. default:
  584. goto bad_enum;
  585. }
  586. break;
  587. case GL_TEXTURE_MAG_FILTER:
  588. switch (e = (GLenum)FTOL(pv[0])) {
  589. case GL_NEAREST:
  590. case GL_LINEAR:
  591. pts->magFilter = e;
  592. break;
  593. default:
  594. goto bad_enum;
  595. }
  596. break;
  597. case GL_TEXTURE_BORDER_COLOR:
  598. __glClampColorf(gc, &pts->borderColor, pv);
  599. break;
  600. case GL_TEXTURE_PRIORITY:
  601. {
  602. __GLtextureObject *texobj;
  603. __GLtextureObjectState *ptos;
  604. ptos = __glLookUpTextureTexobjs(gc, target);
  605. ptos->priority = __glClampf(pv[0], __glZero, __glOne);
  606. texobj = __glLookUpTextureObject(gc, target);
  607. texobj->texture.map.texobjs.priority = ptos->priority;
  608. __glTexPriListChangePriority(gc, texobj, GL_TRUE);
  609. }
  610. bTexState = GL_FALSE;
  611. break;
  612. default:
  613. goto bad_enum;
  614. }
  615. __GL_DELAY_VALIDATE(gc);
  616. #ifdef _MCD_
  617. if (bTexState &&
  618. gc->texture.currentTexture &&
  619. (pts == &gc->texture.currentTexture->params))
  620. {
  621. MCD_STATE_DIRTY(gc, TEXTURE);
  622. }
  623. #endif
  624. }
  625. void APIPRIVATE __glim_TexParameteriv(GLenum target, GLenum pname, const GLint pv[])
  626. {
  627. __GLtextureParamState *pts;
  628. GLenum e;
  629. GLboolean bTexState = GL_TRUE;
  630. __GL_SETUP_NOT_IN_BEGIN();
  631. pts = __glLookUpTextureParams(gc, target);
  632. if (!pts) {
  633. bad_enum:
  634. bTexState = GL_FALSE;
  635. __glSetError(GL_INVALID_ENUM);
  636. return;
  637. }
  638. switch (pname) {
  639. case GL_TEXTURE_WRAP_S:
  640. switch (e = (GLenum) pv[0]) {
  641. case GL_REPEAT:
  642. case GL_CLAMP:
  643. pts->sWrapMode = e;
  644. break;
  645. default:
  646. goto bad_enum;
  647. }
  648. break;
  649. case GL_TEXTURE_WRAP_T:
  650. switch (e = (GLenum) pv[0]) {
  651. case GL_REPEAT:
  652. case GL_CLAMP:
  653. pts->tWrapMode = e;
  654. break;
  655. default:
  656. goto bad_enum;
  657. }
  658. break;
  659. case GL_TEXTURE_MIN_FILTER:
  660. switch (e = (GLenum) pv[0]) {
  661. case GL_NEAREST:
  662. case GL_LINEAR:
  663. case GL_NEAREST_MIPMAP_NEAREST:
  664. case GL_LINEAR_MIPMAP_NEAREST:
  665. case GL_NEAREST_MIPMAP_LINEAR:
  666. case GL_LINEAR_MIPMAP_LINEAR:
  667. pts->minFilter = e;
  668. break;
  669. default:
  670. goto bad_enum;
  671. }
  672. break;
  673. case GL_TEXTURE_MAG_FILTER:
  674. switch (e = (GLenum) pv[0]) {
  675. case GL_NEAREST:
  676. case GL_LINEAR:
  677. pts->magFilter = e;
  678. break;
  679. default:
  680. goto bad_enum;
  681. }
  682. break;
  683. case GL_TEXTURE_BORDER_COLOR:
  684. __glClampColori(gc, &pts->borderColor, pv);
  685. break;
  686. case GL_TEXTURE_PRIORITY:
  687. {
  688. __GLfloat priority;
  689. __GLtextureObjectState *ptos;
  690. __GLtextureObject *texobj;
  691. ptos = __glLookUpTextureTexobjs(gc, target);
  692. priority = __glClampf(__GL_I_TO_FLOAT(pv[0]), __glZero, __glOne);
  693. ptos->priority = priority;
  694. texobj = __glLookUpTextureObject(gc, target);
  695. texobj->texture.map.texobjs.priority = priority;
  696. __glTexPriListChangePriority(gc, texobj, GL_TRUE);
  697. }
  698. bTexState = GL_FALSE;
  699. break;
  700. default:
  701. goto bad_enum;
  702. }
  703. __GL_DELAY_VALIDATE(gc);
  704. #ifdef _MCD_
  705. if (bTexState &&
  706. gc->texture.currentTexture &&
  707. (pts == &gc->texture.currentTexture->params))
  708. {
  709. MCD_STATE_DIRTY(gc, TEXTURE);
  710. }
  711. #endif
  712. }
  713. /************************************************************************/
  714. void APIPRIVATE __glim_TexEnvfv(GLenum target, GLenum pname, const GLfloat pv[])
  715. {
  716. __GLtextureEnvState *tes;
  717. GLenum e;
  718. __GL_SETUP_NOT_IN_BEGIN();
  719. if(target < GL_TEXTURE_ENV) {
  720. __glSetError(GL_INVALID_ENUM);
  721. return;
  722. }
  723. target -= GL_TEXTURE_ENV;
  724. #ifdef NT
  725. // target is unsigned!
  726. if (target >= (GLenum) gc->constants.numberOfTextureEnvs) {
  727. #else
  728. if (target >= gc->constants.numberOfTextureEnvs) {
  729. #endif // NT
  730. bad_enum:
  731. __glSetError(GL_INVALID_ENUM);
  732. return;
  733. }
  734. tes = &gc->state.texture.env[target];
  735. switch (pname) {
  736. case GL_TEXTURE_ENV_MODE:
  737. switch(e = (GLenum) FTOL(pv[0])) {
  738. case GL_MODULATE:
  739. case GL_DECAL:
  740. case GL_BLEND:
  741. case GL_REPLACE:
  742. tes->mode = e;
  743. break;
  744. default:
  745. goto bad_enum;
  746. }
  747. break;
  748. case GL_TEXTURE_ENV_COLOR:
  749. __glClampAndScaleColorf(gc, &tes->color, pv);
  750. break;
  751. default:
  752. goto bad_enum;
  753. }
  754. __GL_DELAY_VALIDATE(gc);
  755. MCD_STATE_DIRTY(gc, TEXENV);
  756. }
  757. void APIPRIVATE __glim_TexEnviv(GLenum target, GLenum pname, const GLint pv[])
  758. {
  759. __GLtextureEnvState *tes;
  760. GLenum e;
  761. __GL_SETUP_NOT_IN_BEGIN();
  762. if(target < GL_TEXTURE_ENV) {
  763. __glSetError(GL_INVALID_ENUM);
  764. return;
  765. }
  766. target -= GL_TEXTURE_ENV;
  767. #ifdef NT
  768. // target is unsigned!
  769. if (target >= (GLenum) gc->constants.numberOfTextureEnvs) {
  770. #else
  771. if (target >= gc->constants.numberOfTextureEnvs) {
  772. #endif // NT
  773. bad_enum:
  774. __glSetError(GL_INVALID_ENUM);
  775. return;
  776. }
  777. tes = &gc->state.texture.env[target];
  778. switch (pname) {
  779. case GL_TEXTURE_ENV_MODE:
  780. switch(e = (GLenum) pv[0]) {
  781. case GL_MODULATE:
  782. case GL_DECAL:
  783. case GL_BLEND:
  784. case GL_REPLACE:
  785. tes->mode = e;
  786. break;
  787. default:
  788. goto bad_enum;
  789. }
  790. break;
  791. case GL_TEXTURE_ENV_COLOR:
  792. __glClampAndScaleColori(gc, &tes->color, pv);
  793. break;
  794. default:
  795. goto bad_enum;
  796. }
  797. __GL_DELAY_VALIDATE(gc);
  798. MCD_STATE_DIRTY(gc, TEXENV);
  799. }
  800. /************************************************************************/
  801. GLboolean FASTCALL __glIsTextureConsistent(__GLcontext *gc, GLenum name)
  802. {
  803. __GLtexture *tex = __glLookUpTexture(gc, name);
  804. __GLtextureParamState *params = __glLookUpTextureParams(gc, name);
  805. GLint i, width, height;
  806. GLint maxLevel;
  807. GLint border;
  808. GLenum baseFormat;
  809. GLenum requestedFormat;
  810. if ((tex->level[0].width == 0) || (tex->level[0].height == 0)) {
  811. return GL_FALSE;
  812. }
  813. border = tex->level[0].border;
  814. width = tex->level[0].width - border*2;
  815. height = tex->level[0].height - border*2;
  816. maxLevel = gc->constants.maxMipMapLevel;
  817. baseFormat = tex->level[0].baseFormat;
  818. requestedFormat = tex->level[0].requestedFormat;
  819. switch(gc->state.texture.env[0].mode) {
  820. case GL_DECAL:
  821. if (baseFormat != GL_RGB && baseFormat != GL_RGBA) {
  822. return GL_FALSE;
  823. }
  824. break;
  825. default:
  826. break;
  827. }
  828. /* If not-mipmapping, we are ok */
  829. switch (params->minFilter) {
  830. case GL_NEAREST:
  831. case GL_LINEAR:
  832. return GL_TRUE;
  833. default:
  834. break;
  835. }
  836. i = 0;
  837. while (++i < maxLevel) {
  838. if (width == 1 && height == 1) break;
  839. width >>= 1;
  840. if (width == 0) width = 1;
  841. height >>= 1;
  842. if (height == 0) height = 1;
  843. if (tex->level[i].border != border ||
  844. (GLenum)tex->level[i].requestedFormat != requestedFormat ||
  845. tex->level[i].width != width + border*2 ||
  846. tex->level[i].height != height + border*2)
  847. {
  848. return GL_FALSE;
  849. }
  850. }
  851. return GL_TRUE;
  852. }
  853. /***********************************************************************/
  854. #ifdef GL_WIN_multiple_textures
  855. void APIPRIVATE __glim_CurrentTextureIndexWIN(GLuint index)
  856. {
  857. }
  858. void APIPRIVATE __glim_NthTexCombineFuncWIN(GLuint index,
  859. GLenum leftColorFactor, GLenum colorOp, GLenum rightColorFactor,
  860. GLenum leftAlphaFactor, GLenum alphaOp, GLenum rightAlphaFactor)
  861. {
  862. }
  863. #endif // GL_WIN_multiple_textures