/opengles/src/Context.cpp

http://ftk.googlecode.com/ · C++ · 1339 lines · 977 code · 298 blank · 64 comment · 78 complexity · 252f6380eda9bdc1e49d67a518fcf459 MD5 · raw file

  1. // ==========================================================================
  2. //
  3. // context.cpp Rendering Context Class for 3D Rendering Library
  4. //
  5. // --------------------------------------------------------------------------
  6. //
  7. // 08-07-2003 Hans-Martin Will initial version
  8. //
  9. // --------------------------------------------------------------------------
  10. //
  11. // Copyright (c) 2004, Hans-Martin Will. All rights reserved.
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions are
  15. // met:
  16. //
  17. // * Redistributions of source code must retain the above copyright
  18. // notice, this list of conditions and the following disclaimer.
  19. // * Redistributions in binary form must reproduce the above copyright
  20. // notice, this list of conditions and the following disclaimer in the
  21. // documentation and/or other materials provided with the distribution.
  22. //
  23. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  28. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  33. // THE POSSIBILITY OF SUCH DAMAGE.
  34. //
  35. // ==========================================================================
  36. #include "stdafx.h"
  37. #include "Context.h"
  38. #include "Surface.h"
  39. #include "Rasterizer.h"
  40. #include "Utils.h"
  41. using namespace EGL;
  42. // --------------------------------------------------------------------------
  43. // Constructor and destructor
  44. // --------------------------------------------------------------------------
  45. Context :: Context(const Config & config)
  46. :
  47. m_Config(config),
  48. m_DrawSurface(0),
  49. m_ReadSurface(0),
  50. m_LastError(GL_NO_ERROR),
  51. // transformation matrices
  52. m_ModelViewMatrixStack(16),
  53. m_CurrentMatrixStack(&m_ModelViewMatrixStack),
  54. m_MatrixMode(GL_MODELVIEW),
  55. m_Scissor(0, 0, config.GetConfigAttrib(EGL_WIDTH), config.GetConfigAttrib(EGL_HEIGHT)),
  56. m_Viewport(0, 0, config.GetConfigAttrib(EGL_WIDTH), config.GetConfigAttrib(EGL_HEIGHT)),
  57. m_CurrentPaletteMatrix(0),
  58. // server flags
  59. m_ClipPlaneEnabled(0),
  60. m_LightingEnabled(false),
  61. m_TwoSidedLightning(false),
  62. m_LightEnabled(0), // no light on
  63. m_CullFaceEnabled(false),
  64. m_DitherEnabled(false),
  65. m_ReverseFaceOrientation(false),
  66. m_CullMode(CullModeBack),
  67. m_ColorMaterialEnabled(false),
  68. m_NormalizeEnabled(false),
  69. m_RescaleNormalEnabled(false),
  70. m_PolygonOffsetFillEnabled(false),
  71. m_MultiSampleEnabled(false),
  72. m_SampleAlphaToCoverageEnabled(false),
  73. m_SampleAlphaToOneEnabled(false),
  74. m_SampleCoverageEnabled(false),
  75. m_ScissorTestEnabled(false),
  76. m_MatrixPaletteEnabled(false),
  77. m_MatrixModePaletteEnabled(false),
  78. m_ActiveTexture(0),
  79. m_ClientActiveTexture(0),
  80. // point parameters
  81. m_PointSize(EGL_ONE),
  82. m_PointSizeMin(EGL_ONE),
  83. m_PointSizeMax(EGL_ONE), // what is the correct value?
  84. m_PointFadeThresholdSize(EGL_ONE),
  85. m_PointSizeAttenuate(false),
  86. // fog parameters for setup phase
  87. m_FogMode(FogModeExp),
  88. m_FogStart(0),
  89. m_FogEnd(EGL_ONE),
  90. m_FogGradient(EGL_ONE),
  91. m_FogGradientShift(0),
  92. m_FogDensity(EGL_ONE),
  93. // client flags
  94. m_VertexArrayEnabled(false),
  95. m_NormalArrayEnabled(false),
  96. m_ColorArrayEnabled(false),
  97. m_PointSizeArrayEnabled(false),
  98. // buffers
  99. m_CurrentArrayBuffer(0),
  100. m_CurrentElementArrayBuffer(0),
  101. // general context state
  102. m_Current(false),
  103. m_Disposed(false),
  104. m_ViewportInitialized(false),
  105. m_DefaultNormal(0, 0, EGL_ONE),
  106. m_DefaultRGBA(EGL_ONE, EGL_ONE, EGL_ONE, EGL_ONE),
  107. // pixel store state
  108. m_PixelStorePackAlignment(4),
  109. m_PixelStoreUnpackAlignment(4),
  110. // SGIS_generate_mipmap extension
  111. m_GenerateMipmaps(false),
  112. // hints
  113. m_PerspectiveCorrectionHint(GL_DONT_CARE),
  114. m_PointSmoothHint(GL_DONT_CARE),
  115. m_LineSmoothHint(GL_DONT_CARE),
  116. m_FogHint(GL_DONT_CARE),
  117. m_GenerateMipmapHint(GL_DONT_CARE)
  118. {
  119. DepthRangex(VIEWPORT_NEAR, VIEWPORT_FAR);
  120. ClearDepthx(EGL_ONE);
  121. ClearStencil(0);
  122. m_Rasterizer = new Rasterizer(GetRasterizerState());
  123. m_Buffers.Allocate(); // default buffer
  124. m_LightModelAmbient.r = m_LightModelAmbient.g = m_LightModelAmbient.b = F(0.2f);
  125. m_LightModelAmbient.a = F(1.0);
  126. m_Lights[0].SetDiffuseColor(FractionalColor(F(1.0), F(1.0), F(1.0), F(1.0)));
  127. m_Lights[0].SetSpecularColor(FractionalColor(F(1.0), F(1.0), F(1.0), F(1.0)));
  128. m_PointDistanceAttenuation[0] = EGL_ONE;
  129. m_PointDistanceAttenuation[1] = 0;
  130. m_PointDistanceAttenuation[2] = 0;
  131. size_t defaultTexture = m_Textures.Allocate();
  132. for (size_t unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  133. m_TexCoordArrayEnabled[unit] = false;
  134. m_Rasterizer->SetTexture(unit, m_Textures.GetObject(defaultTexture));
  135. }
  136. memset(&m_ClipPlanes, 0, sizeof(m_ClipPlanes));
  137. }
  138. Context :: ~Context() {
  139. if (m_DrawSurface != 0) {
  140. m_DrawSurface->SetCurrentContext(0);
  141. }
  142. if (m_ReadSurface != 0 && m_ReadSurface != m_DrawSurface) {
  143. m_ReadSurface->SetCurrentContext(0);
  144. }
  145. m_ReadSurface = m_DrawSurface = 0;
  146. if (m_Rasterizer != 0) {
  147. delete m_Rasterizer;
  148. m_Rasterizer = 0;
  149. }
  150. }
  151. void Context :: SetReadSurface(EGL::Surface * surface) {
  152. if (m_ReadSurface != 0 && m_ReadSurface != m_DrawSurface && m_ReadSurface != surface) {
  153. m_ReadSurface->SetCurrentContext(0);
  154. }
  155. m_ReadSurface = surface;
  156. m_ReadSurface->SetCurrentContext(this);
  157. }
  158. void Context :: SetDrawSurface(EGL::Surface * surface) {
  159. if (m_DrawSurface != 0 && m_ReadSurface != m_DrawSurface && m_DrawSurface != surface) {
  160. m_DrawSurface->SetCurrentContext(0);
  161. }
  162. if (surface != 0 && !m_ViewportInitialized) {
  163. U16 width = surface->GetWidth();
  164. U16 height = surface->GetHeight();
  165. Viewport(0, 0, width, height);
  166. Scissor(0, 0, width, height);
  167. m_ViewportInitialized = true;
  168. }
  169. m_DrawSurface = surface;
  170. m_DrawSurface->SetCurrentContext(this);
  171. m_Rasterizer->SetSurface(surface);
  172. UpdateScissorTest();
  173. }
  174. void Context :: Dispose() {
  175. if (m_Current) {
  176. m_Disposed = true;
  177. } else {
  178. delete this;
  179. }
  180. }
  181. void Context :: SetCurrent(bool current) {
  182. m_Current = current;
  183. if (!m_Current && m_Disposed) {
  184. delete this;
  185. }
  186. }
  187. // --------------------------------------------------------------------------
  188. // Error handling
  189. // --------------------------------------------------------------------------
  190. GLenum Context :: GetError(void) {
  191. GLenum result = m_LastError;
  192. m_LastError = GL_NO_ERROR;
  193. return result;
  194. }
  195. void Context :: RecordError(GLenum error) {
  196. if (error != GL_NO_ERROR && m_LastError == GL_NO_ERROR) {
  197. m_LastError = error;
  198. }
  199. }
  200. // --------------------------------------------------------------------------
  201. // Clearing
  202. // --------------------------------------------------------------------------
  203. void Context :: Clear(GLbitfield mask) {
  204. if (m_DrawSurface == 0) {
  205. return;
  206. }
  207. if ((mask & (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != mask) {
  208. RecordError(GL_INVALID_VALUE);
  209. return;
  210. }
  211. if (m_ScissorTestEnabled) {
  212. if (mask & GL_COLOR_BUFFER_BIT) {
  213. // is clamping [min, max] or [min, max)
  214. m_DrawSurface->ClearColorBuffer(m_ColorClearValue,
  215. m_RasterizerState.GetColorMask(), m_Scissor);
  216. }
  217. if (mask & GL_DEPTH_BUFFER_BIT) {
  218. // actually need to transform depth to correct value
  219. EGL_Fixed clearValue = EGL_MAP_0_1(m_DepthClearValue);
  220. m_DrawSurface->ClearDepthBuffer(clearValue, m_RasterizerState.GetDepthMask(), m_Scissor);
  221. }
  222. if (mask & GL_STENCIL_BUFFER_BIT) {
  223. m_DrawSurface->ClearStencilBuffer(m_StencilClearValue, m_RasterizerState.GetStencilMask(), m_Scissor);
  224. }
  225. } else {
  226. if (mask & GL_COLOR_BUFFER_BIT) {
  227. // is clamping [min, max] or [min, max)
  228. m_DrawSurface->ClearColorBuffer(m_ColorClearValue, m_RasterizerState.GetColorMask());
  229. }
  230. if (mask & GL_DEPTH_BUFFER_BIT) {
  231. // actually need to transform depth to correct value
  232. EGL_Fixed clearValue = EGL_MAP_0_1(m_DepthClearValue);
  233. m_DrawSurface->ClearDepthBuffer(clearValue, m_RasterizerState.GetDepthMask());
  234. }
  235. if (mask & GL_STENCIL_BUFFER_BIT) {
  236. m_DrawSurface->ClearStencilBuffer(m_StencilClearValue, m_RasterizerState.GetStencilMask());
  237. }
  238. }
  239. }
  240. void Context :: ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
  241. m_ColorClearValue = FractionalColor(red, green, blue, alpha);
  242. }
  243. void Context :: ClearDepthx(GLclampx depth) {
  244. m_DepthClearValue = EGL_CLAMP(depth, 0, EGL_ONE);
  245. }
  246. void Context :: ClearStencil(GLint s) {
  247. m_StencilClearValue = s;
  248. }
  249. // --------------------------------------------------------------------------
  250. //
  251. // --------------------------------------------------------------------------
  252. void Context :: Toggle(GLenum cap, bool value) {
  253. switch (cap) {
  254. case GL_LIGHTING:
  255. m_LightingEnabled = value;
  256. break;
  257. case GL_FOG:
  258. GetRasterizerState()->EnableFog(value);
  259. break;
  260. case GL_TEXTURE_2D:
  261. GetRasterizerState()->EnableTexture(m_ActiveTexture, value);
  262. break;
  263. case GL_CULL_FACE:
  264. m_CullFaceEnabled = value;
  265. break;
  266. case GL_ALPHA_TEST:
  267. GetRasterizerState()->EnableAlphaTest(value);
  268. break;
  269. case GL_BLEND:
  270. GetRasterizerState()->EnableBlending(value);
  271. break;
  272. case GL_COLOR_LOGIC_OP:
  273. GetRasterizerState()->EnableLogicOp(value);
  274. break;
  275. case GL_DITHER:
  276. m_DitherEnabled = value;
  277. break;
  278. case GL_STENCIL_TEST:
  279. GetRasterizerState()->EnableStencilTest(value);
  280. break;
  281. case GL_DEPTH_TEST:
  282. GetRasterizerState()->EnableDepthTest(value);
  283. break;
  284. case GL_LIGHT0:
  285. case GL_LIGHT1:
  286. case GL_LIGHT2:
  287. case GL_LIGHT3:
  288. case GL_LIGHT4:
  289. case GL_LIGHT5:
  290. case GL_LIGHT6:
  291. case GL_LIGHT7:
  292. {
  293. int mask = 1 << (cap - GL_LIGHT0);
  294. if (value) {
  295. m_LightEnabled |= mask;
  296. } else {
  297. m_LightEnabled &= ~mask;
  298. }
  299. }
  300. break;
  301. case GL_POINT_SMOOTH:
  302. GetRasterizerState()->SetPointSmoothEnabled(value);
  303. break;
  304. case GL_POINT_SPRITE_OES:
  305. GetRasterizerState()->SetPointSpriteEnabled(value);
  306. break;
  307. case GL_LINE_SMOOTH:
  308. GetRasterizerState()->SetLineSmoothEnabled(value);
  309. break;
  310. case GL_SCISSOR_TEST:
  311. m_ScissorTestEnabled = value;
  312. UpdateScissorTest();
  313. break;
  314. case GL_COLOR_MATERIAL:
  315. m_ColorMaterialEnabled = value;
  316. break;
  317. case GL_NORMALIZE:
  318. m_NormalizeEnabled = value;
  319. break;
  320. case GL_CLIP_PLANE0:
  321. case GL_CLIP_PLANE1:
  322. case GL_CLIP_PLANE2:
  323. case GL_CLIP_PLANE3:
  324. case GL_CLIP_PLANE4:
  325. case GL_CLIP_PLANE5:
  326. {
  327. size_t plane = cap - GL_CLIP_PLANE0;
  328. U32 mask = ~(1u << plane);
  329. U32 bit = value ? (1u << plane) : 0;
  330. m_ClipPlaneEnabled = (m_ClipPlaneEnabled & mask) | bit;
  331. }
  332. break;
  333. case GL_RESCALE_NORMAL:
  334. m_RescaleNormalEnabled = value;
  335. UpdateInverseModelViewMatrix();
  336. break;
  337. case GL_POLYGON_OFFSET_FILL:
  338. GetRasterizerState()->EnablePolygonOffsetFill(value);
  339. break;
  340. case GL_MULTISAMPLE:
  341. m_MultiSampleEnabled = value;
  342. break;
  343. case GL_SAMPLE_ALPHA_TO_COVERAGE:
  344. m_SampleAlphaToCoverageEnabled = value;
  345. break;
  346. case GL_SAMPLE_ALPHA_TO_ONE:
  347. m_SampleAlphaToOneEnabled = value;
  348. break;
  349. case GL_SAMPLE_COVERAGE:
  350. m_SampleCoverageEnabled = value;
  351. break;
  352. case GL_MATRIX_PALETTE_OES:
  353. m_MatrixPaletteEnabled = value;
  354. break;
  355. default:
  356. RecordError(GL_INVALID_ENUM);
  357. return;
  358. }
  359. }
  360. void Context :: Disable(GLenum cap) {
  361. Toggle(cap, false);
  362. }
  363. void Context :: Enable(GLenum cap) {
  364. Toggle(cap, true);
  365. }
  366. void Context :: Hint(GLenum target, GLenum mode) {
  367. if (mode != GL_DONT_CARE && mode != GL_FASTEST && mode != GL_NICEST) {
  368. RecordError(GL_INVALID_ENUM);
  369. return;
  370. }
  371. switch (target) {
  372. case GL_FOG_HINT:
  373. m_FogHint = mode;
  374. break;
  375. case GL_LINE_SMOOTH_HINT:
  376. m_LineSmoothHint = mode;
  377. break;
  378. case GL_PERSPECTIVE_CORRECTION_HINT:
  379. m_PerspectiveCorrectionHint = mode;
  380. break;
  381. case GL_POINT_SMOOTH_HINT:
  382. m_PointSmoothHint = mode;
  383. break;
  384. case GL_GENERATE_MIPMAP_HINT:
  385. m_GenerateMipmapHint = mode;
  386. break;
  387. default:
  388. RecordError(GL_INVALID_ENUM);
  389. return;
  390. }
  391. }
  392. namespace {
  393. static const GLenum formats[] = {
  394. GL_PALETTE4_RGB8_OES,
  395. GL_PALETTE4_RGBA8_OES,
  396. GL_PALETTE4_R5_G6_B5_OES,
  397. GL_PALETTE4_RGBA4_OES,
  398. GL_PALETTE4_RGB5_A1_OES,
  399. GL_PALETTE8_RGB8_OES,
  400. GL_PALETTE8_RGBA8_OES,
  401. GL_PALETTE8_R5_G6_B5_OES,
  402. GL_PALETTE8_RGBA4_OES,
  403. GL_PALETTE8_RGB5_A1_OES
  404. };
  405. void CopyRect(const Rect & rect, GLint * params) {
  406. params[0] = rect.x;
  407. params[1] = rect.y;
  408. params[2] = rect.width;
  409. params[3] = rect.height;
  410. }
  411. GLenum EnumFromComparisonFunc(RasterizerState::ComparisonFunc func) {
  412. switch (func) {
  413. case RasterizerState::CompFuncNever: return GL_NEVER;
  414. case RasterizerState::CompFuncLess: return GL_LESS;
  415. case RasterizerState::CompFuncLEqual: return GL_LEQUAL;
  416. case RasterizerState::CompFuncGreater: return GL_GREATER;
  417. case RasterizerState::CompFuncGEqual: return GL_GEQUAL;
  418. case RasterizerState::CompFuncEqual: return GL_EQUAL;
  419. case RasterizerState::CompFuncNotEqual: return GL_NOTEQUAL;
  420. case RasterizerState::CompFuncAlways: return GL_ALWAYS;
  421. default: return 0;
  422. }
  423. }
  424. GLenum EnumFromStencilOp(RasterizerState::StencilOp op) {
  425. switch (op) {
  426. case RasterizerState::StencilOpKeep: return GL_KEEP;
  427. case RasterizerState::StencilOpZero: return GL_ZERO;
  428. case RasterizerState::StencilOpReplace: return GL_REPLACE;
  429. case RasterizerState::StencilOpIncr: return GL_INCR;
  430. case RasterizerState::StencilOpDecr: return GL_DECR;
  431. case RasterizerState::StencilOpInvert: return GL_INVERT;
  432. default: return 0;
  433. }
  434. }
  435. GLenum EnumFromLogicOp(RasterizerState::LogicOp op) {
  436. switch (op) {
  437. case RasterizerState::LogicOpClear: return GL_CLEAR;
  438. case RasterizerState::LogicOpAnd: return GL_AND;
  439. case RasterizerState::LogicOpAndReverse: return GL_AND_REVERSE;
  440. case RasterizerState::LogicOpCopy: return GL_COPY;
  441. case RasterizerState::LogicOpAndInverted: return GL_AND_INVERTED;
  442. case RasterizerState::LogicOpNoop: return GL_NOOP;
  443. case RasterizerState::LogicOpXor: return GL_XOR;
  444. case RasterizerState::LogicOpOr: return GL_OR;
  445. case RasterizerState::LogicOpNor: return GL_NOR;
  446. case RasterizerState::LogicOpEquiv: return GL_EQUIV;
  447. case RasterizerState::LogicOpInvert: return GL_INVERT;
  448. case RasterizerState::LogicOpOrReverse: return GL_OR_REVERSE;
  449. case RasterizerState::LogicOpCopyInverted: return GL_COPY_INVERTED;
  450. case RasterizerState::LogicOpOrInverted: return GL_OR_INVERTED;
  451. case RasterizerState::LogicOpNand: return GL_NAND;
  452. case RasterizerState::LogicOpSet: return GL_SET;
  453. default: return 0;
  454. }
  455. }
  456. GLenum EnumFromBlendFuncSrc(RasterizerState::BlendFuncSrc sfactor) {
  457. switch (sfactor) {
  458. case RasterizerState::BlendFuncSrcZero: return GL_ZERO;
  459. case RasterizerState::BlendFuncSrcOne: return GL_ONE;
  460. case RasterizerState::BlendFuncSrcDstColor: return GL_DST_COLOR;
  461. case RasterizerState::BlendFuncSrcOneMinusDstColor: return GL_ONE_MINUS_DST_COLOR;
  462. case RasterizerState::BlendFuncSrcSrcAlpha: return GL_SRC_ALPHA;
  463. case RasterizerState::BlendFuncSrcOneMinusSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA;
  464. case RasterizerState::BlendFuncSrcDstAlpha: return GL_DST_ALPHA;
  465. case RasterizerState::BlendFuncSrcOneMinusDstAlpha: return GL_ONE_MINUS_DST_ALPHA;
  466. case RasterizerState::BlendFuncSrcSrcAlphaSaturate: return GL_SRC_ALPHA_SATURATE;
  467. default: return 0;
  468. }
  469. }
  470. GLenum EnumFromBlendFuncDst(RasterizerState::BlendFuncDst dfactor) {
  471. switch (dfactor) {
  472. case RasterizerState::BlendFuncDstZero: return GL_ZERO;
  473. case RasterizerState::BlendFuncDstSrcColor: return GL_SRC_COLOR;
  474. case RasterizerState::BlendFuncDstOneMinusSrcColor: return GL_ONE_MINUS_SRC_COLOR;
  475. case RasterizerState::BlendFuncDstSrcAlpha: return GL_SRC_ALPHA;
  476. case RasterizerState::BlendFuncDstOneMinusSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA;
  477. case RasterizerState::BlendFuncDstDstAlpha: return GL_DST_ALPHA;
  478. case RasterizerState::BlendFuncDstOneMinusDstAlpha: return GL_ONE_MINUS_DST_ALPHA;
  479. case RasterizerState::BlendFuncDstOne: return GL_ONE;
  480. default: return 0;
  481. }
  482. }
  483. }
  484. void Context :: GetIntegerv(GLenum pname, GLint *params) {
  485. switch (pname) {
  486. /* 1.0 stuff */
  487. case GL_SMOOTH_LINE_WIDTH_RANGE:
  488. case GL_SMOOTH_POINT_SIZE_RANGE:
  489. case GL_ALIASED_POINT_SIZE_RANGE:
  490. case GL_ALIASED_LINE_WIDTH_RANGE:
  491. params[0] = params[1] = 1;
  492. return;
  493. case GL_ALPHA_BITS:
  494. params[0] = m_Config.GetConfigAttrib(EGL_ALPHA_SIZE);
  495. break;
  496. case GL_BLUE_BITS:
  497. params[0] = m_Config.GetConfigAttrib(EGL_BLUE_SIZE);
  498. break;
  499. case GL_DEPTH_BITS:
  500. params[0] = m_Config.GetConfigAttrib(EGL_DEPTH_SIZE);
  501. break;
  502. case GL_GREEN_BITS:
  503. params[0] = m_Config.GetConfigAttrib(EGL_GREEN_SIZE);
  504. break;
  505. case GL_RED_BITS:
  506. params[0] = m_Config.GetConfigAttrib(EGL_RED_SIZE);
  507. break;
  508. case GL_STENCIL_BITS:
  509. params[0] = m_Config.GetConfigAttrib(EGL_STENCIL_SIZE);
  510. break;
  511. case GL_SUBPIXEL_BITS:
  512. params[0] = m_Config.GetConfigAttrib(EGL_SAMPLES);
  513. break;
  514. case GL_COMPRESSED_TEXTURE_FORMATS:
  515. {
  516. size_t numFormats = sizeof(formats) / sizeof(formats[0]);
  517. for (size_t index = 0; index < numFormats; ++index)
  518. params[index] = formats[index];
  519. }
  520. break;
  521. case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
  522. params[0] = sizeof(formats) / sizeof(formats[0]);
  523. break;
  524. case GL_MAX_ELEMENTS_INDICES:
  525. case GL_MAX_ELEMENTS_VERTICES:
  526. params[0] = INT_MAX;
  527. break;
  528. case GL_MAX_LIGHTS:
  529. params[0] = EGL_NUMBER_LIGHTS;
  530. break;
  531. case GL_MAX_CLIP_PLANES:
  532. params[0] = NUM_CLIP_PLANES;
  533. break;
  534. case GL_MAX_MODELVIEW_STACK_DEPTH:
  535. params[0] = m_ModelViewMatrixStack.GetStackSize();
  536. break;
  537. case GL_MODELVIEW_STACK_DEPTH:
  538. params[0] = m_ModelViewMatrixStack.GetCurrentStackSize();
  539. break;
  540. case GL_MAX_PROJECTION_STACK_DEPTH:
  541. params[0] = m_ProjectionMatrixStack.GetStackSize();
  542. break;
  543. case GL_PROJECTION_STACK_DEPTH:
  544. params[0] = m_ProjectionMatrixStack.GetCurrentStackSize();
  545. break;
  546. case GL_MAX_TEXTURE_STACK_DEPTH:
  547. params[0] = m_TextureMatrixStack[m_ActiveTexture].GetStackSize();
  548. break;
  549. case GL_TEXTURE_STACK_DEPTH:
  550. params[0] = m_TextureMatrixStack[m_ActiveTexture].GetCurrentStackSize();
  551. break;
  552. case GL_MAX_TEXTURE_SIZE:
  553. params[0] = RasterizerState::MaxTextureSize;
  554. break;
  555. case GL_MAX_TEXTURE_UNITS:
  556. params[0] = EGL_NUM_TEXTURE_UNITS;
  557. break;
  558. case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
  559. params[0] = GL_UNSIGNED_SHORT_5_6_5;
  560. break;
  561. case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
  562. params[0] = GL_RGB;
  563. break;
  564. case GL_MAX_VIEWPORT_DIMS:
  565. params[0] = m_Config.m_Width;
  566. params[1] = m_Config.m_Height;
  567. break;
  568. case GL_MAX_PALETTE_MATRICES_OES:
  569. case GL_MAX_VERTEX_UNITS_OES:
  570. params[0] = MATRIX_PALETTE_SIZE;
  571. break;
  572. // params[0] = EGL_NUM_TEXTURE_UNITS;
  573. // break;
  574. case GL_VERTEX_ARRAY_SIZE:
  575. params[0] = m_VertexArray.size;
  576. break;
  577. case GL_VERTEX_ARRAY_STRIDE:
  578. params[0] = m_VertexArray.stride;
  579. break;
  580. case GL_VERTEX_ARRAY_TYPE:
  581. params[0] = m_VertexArray.type;
  582. break;
  583. case GL_NORMAL_ARRAY_STRIDE:
  584. params[0] = m_NormalArray.stride;
  585. break;
  586. case GL_NORMAL_ARRAY_TYPE:
  587. params[0] = m_NormalArray.type;
  588. break;
  589. case GL_COLOR_ARRAY_SIZE:
  590. params[0] = m_ColorArray.size;
  591. break;
  592. case GL_COLOR_ARRAY_STRIDE:
  593. params[0] = m_ColorArray.stride;
  594. break;
  595. case GL_COLOR_ARRAY_TYPE:
  596. params[0] = m_ColorArray.type;
  597. break;
  598. case GL_TEXTURE_COORD_ARRAY_SIZE:
  599. params[0] = m_TexCoordArray[m_ClientActiveTexture].size;
  600. break;
  601. case GL_TEXTURE_COORD_ARRAY_STRIDE:
  602. params[0] = m_TexCoordArray[m_ClientActiveTexture].stride;
  603. break;
  604. case GL_TEXTURE_COORD_ARRAY_TYPE:
  605. params[0] = m_TexCoordArray[m_ClientActiveTexture].type;
  606. break;
  607. case GL_MATRIX_INDEX_ARRAY_SIZE_OES:
  608. params[0] = m_MatrixIndexArray.size;
  609. break;
  610. case GL_MATRIX_INDEX_ARRAY_TYPE_OES:
  611. params[0] = m_MatrixIndexArray.type;
  612. break;
  613. case GL_MATRIX_INDEX_ARRAY_STRIDE_OES:
  614. params[0] = m_MatrixIndexArray.stride;
  615. break;
  616. case GL_WEIGHT_ARRAY_SIZE_OES:
  617. params[0] = m_WeightArray.size;
  618. break;
  619. case GL_WEIGHT_ARRAY_TYPE_OES:
  620. params[0] = m_WeightArray.type;
  621. break;
  622. case GL_WEIGHT_ARRAY_STRIDE_OES:
  623. params[0] = m_WeightArray.stride;
  624. break;
  625. case GL_POINT_SIZE_ARRAY_TYPE_OES:
  626. params[0] = m_PointSizeArray.type;
  627. break;
  628. case GL_POINT_SIZE_ARRAY_STRIDE_OES:
  629. params[0] = m_PointSizeArray.stride;
  630. break;
  631. case GL_VERTEX_ARRAY_BUFFER_BINDING:
  632. params[0] = m_VertexArray.boundBuffer;
  633. break;
  634. case GL_NORMAL_ARRAY_BUFFER_BINDING:
  635. params[0] = m_NormalArray.boundBuffer;
  636. break;
  637. case GL_COLOR_ARRAY_BUFFER_BINDING:
  638. params[0] = m_ColorArray.boundBuffer;
  639. break;
  640. case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
  641. params[0] = m_TexCoordArray[m_ClientActiveTexture].boundBuffer;
  642. break;
  643. case GL_ELEMENT_ARRAY_BUFFER_BINDING:
  644. params[0] = m_CurrentElementArrayBuffer;
  645. break;
  646. case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
  647. params[0] = m_PointSizeArray.boundBuffer;
  648. break;
  649. case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES:
  650. params[0] = m_MatrixIndexArray.boundBuffer;
  651. break;
  652. case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES:
  653. params[0] = m_WeightArray.boundBuffer;
  654. break;
  655. case GL_ARRAY_BUFFER_BINDING:
  656. params[0] = m_CurrentArrayBuffer;
  657. break;
  658. case GL_UNPACK_ALIGNMENT:
  659. params[0] = m_PixelStoreUnpackAlignment;
  660. break;
  661. case GL_PACK_ALIGNMENT:
  662. params[0] = m_PixelStorePackAlignment;
  663. break;
  664. case GL_STENCIL_CLEAR_VALUE:
  665. params[0] = m_StencilClearValue;
  666. break;
  667. case GL_DEPTH_CLEAR_VALUE:
  668. params[0] = EGL_Mul(0x7fffffff, m_DepthClearValue);
  669. break;
  670. case GL_SCISSOR_BOX:
  671. CopyRect(m_Scissor, params);
  672. break;
  673. case GL_SAMPLE_BUFFERS:
  674. params[0] = m_Config.m_SampleBuffers;
  675. break;
  676. case GL_SAMPLES:
  677. params[0] = m_Config.m_Samples;
  678. break;
  679. case GL_VIEWPORT:
  680. CopyRect(m_Viewport, params);
  681. break;
  682. case GL_STENCIL_WRITEMASK:
  683. params[0] = m_RasterizerState.GetStencilMask();
  684. break;
  685. case GL_STENCIL_VALUE_MASK:
  686. params[0] = m_RasterizerState.GetStencilComparisonMask();
  687. break;
  688. case GL_STENCIL_REF:
  689. params[0] = m_RasterizerState.GetStencilRef();
  690. break;
  691. case GL_ALPHA_TEST_REF:
  692. params[0] = EGL_Mul(0x7fffffff, m_RasterizerState.GetAlphaRef());
  693. break;
  694. case GL_ALPHA_TEST_FUNC:
  695. params[0] = EnumFromComparisonFunc(m_RasterizerState.GetAlphaFunc());
  696. break;
  697. case GL_STENCIL_FUNC:
  698. params[0] = EnumFromComparisonFunc(m_RasterizerState.GetStencilFunc());
  699. break;
  700. case GL_STENCIL_FAIL:
  701. params[0] = EnumFromStencilOp(m_RasterizerState.GetStencilOpFail());
  702. break;
  703. case GL_STENCIL_PASS_DEPTH_FAIL:
  704. params[0] = EnumFromStencilOp(m_RasterizerState.GetStencilOpFailZFail());
  705. break;
  706. case GL_STENCIL_PASS_DEPTH_PASS:
  707. params[0] = EnumFromStencilOp(m_RasterizerState.GetStencilOpFailZPass());
  708. break;
  709. case GL_DEPTH_FUNC:
  710. params[0] = EnumFromComparisonFunc(m_RasterizerState.GetDepthFunc());
  711. break;
  712. case GL_LOGIC_OP_MODE:
  713. params[0] = EnumFromLogicOp(m_RasterizerState.GetLogicOp());
  714. break;
  715. case GL_BLEND_SRC:
  716. params[0] = EnumFromBlendFuncSrc(m_RasterizerState.GetBlendFuncSrc());
  717. break;
  718. case GL_BLEND_DST:
  719. params[0] = EnumFromBlendFuncDst(m_RasterizerState.GetBlendFuncDst());
  720. break;
  721. case GL_FOG_MODE:
  722. {
  723. switch (m_FogMode) {
  724. case FogLinear: params[0] = GL_LINEAR; break;
  725. case FogModeExp: params[0] = GL_EXP; break;
  726. case FogModeExp2: params[0] = GL_EXP2; break;
  727. }
  728. }
  729. break;
  730. case GL_SHADE_MODEL:
  731. {
  732. switch (m_RasterizerState.GetShadeModel()) {
  733. case RasterizerState::ShadeModelFlat: params[0] = GL_FLAT;
  734. case RasterizerState::ShadeModelSmooth: params[0] = GL_SMOOTH;
  735. }
  736. }
  737. break;
  738. case GL_CULL_FACE_MODE:
  739. {
  740. switch (m_CullMode) {
  741. case CullModeFront: params[0] = GL_FRONT; break;
  742. case CullModeBack: params[0] = GL_BACK; break;
  743. case CullModeBackAndFront: params[0] = GL_FRONT_AND_BACK; break;
  744. }
  745. }
  746. break;
  747. case GL_FRONT_FACE:
  748. params[0] = m_ReverseFaceOrientation ? GL_CW : GL_CCW;
  749. break;
  750. case GL_MATRIX_MODE:
  751. params[0] = m_MatrixMode;
  752. break;
  753. case GL_ACTIVE_TEXTURE:
  754. params[0] = GL_TEXTURE0 + m_ActiveTexture;
  755. break;
  756. case GL_CLIENT_ACTIVE_TEXTURE:
  757. params[0] = GL_TEXTURE0 + m_ClientActiveTexture;
  758. break;
  759. case GL_TEXTURE_BINDING_2D:
  760. {
  761. size_t index = m_Textures.GetIndex(m_Rasterizer->GetTexture(m_ActiveTexture));
  762. if (index == ~0) {
  763. params[0] = 0;
  764. } else {
  765. params[0] = index;
  766. }
  767. }
  768. break;
  769. case GL_COORD_REPLACE_OES:
  770. params[0] = m_RasterizerState.IsPointCoordReplaceEnabled(m_ActiveTexture);
  771. break;
  772. case GL_CURRENT_COLOR:
  773. {
  774. params[0] = EGL_Mul(0x7fffffff, m_DefaultRGBA.r);
  775. params[1] = EGL_Mul(0x7fffffff, m_DefaultRGBA.g);
  776. params[2] = EGL_Mul(0x7fffffff, m_DefaultRGBA.b);
  777. params[3] = EGL_Mul(0x7fffffff, m_DefaultRGBA.a);
  778. }
  779. break;
  780. case GL_PERSPECTIVE_CORRECTION_HINT:
  781. params[0] = m_PerspectiveCorrectionHint;
  782. break;
  783. case GL_POINT_SMOOTH_HINT:
  784. params[0] = m_PointSmoothHint;
  785. break;
  786. case GL_LINE_SMOOTH_HINT:
  787. params[0] = m_LineSmoothHint;
  788. break;
  789. case GL_FOG_HINT:
  790. params[0] = m_FogHint;
  791. break;
  792. case GL_GENERATE_MIPMAP_HINT:
  793. params[0] = m_GenerateMipmapHint;
  794. break;
  795. default:
  796. RecordError(GL_INVALID_ENUM);
  797. }
  798. }
  799. const GLubyte * Context :: GetString(GLenum name) {
  800. switch (name) {
  801. case GL_VENDOR:
  802. return (GLubyte *) EGL_CONFIG_VENDOR;
  803. case GL_VERSION:
  804. return (GLubyte *) EGL_CONFIG_VERSION;
  805. case GL_RENDERER:
  806. return (GLubyte *) EGL_CONFIG_RENDERER;
  807. case GL_EXTENSIONS:
  808. return (GLubyte *) EGL_CONFIG_EXTENSIONS;
  809. default:
  810. RecordError(GL_INVALID_ENUM);
  811. return 0;
  812. }
  813. }
  814. void Context :: Finish(void) { }
  815. void Context :: Flush(void) { }
  816. void Context :: GetBooleanv(GLenum pname, GLboolean *params) {
  817. switch (pname) {
  818. case GL_LIGHT_MODEL_TWO_SIDE:
  819. params[0] = m_TwoSidedLightning;
  820. break;
  821. case GL_COLOR_WRITEMASK:
  822. {
  823. Color mask = m_RasterizerState.GetColorMask();
  824. params[0] = mask.R() != 0;
  825. params[1] = mask.G() != 0;
  826. params[2] = mask.B() != 0;
  827. params[3] = mask.A() != 0;
  828. }
  829. break;
  830. case GL_DEPTH_WRITEMASK:
  831. params[0] = m_RasterizerState.GetDepthMask();
  832. break;
  833. case GL_SAMPLE_COVERAGE_INVERT:
  834. params[0] = m_RasterizerState.GetSampleCoverageInvert();
  835. break;
  836. default:
  837. RecordError(GL_INVALID_ENUM);
  838. return;
  839. }
  840. }
  841. bool Context :: GetFixedv(GLenum pname, GLfixed *params) {
  842. switch (pname) {
  843. case GL_CURRENT_COLOR:
  844. CopyColor(m_DefaultRGBA, params);
  845. break;
  846. case GL_CURRENT_TEXTURE_COORDS:
  847. CopyVector(m_DefaultTextureCoords[m_ActiveTexture], params);
  848. break;
  849. case GL_CURRENT_NORMAL:
  850. params[0] = m_DefaultNormal.x();
  851. params[1] = m_DefaultNormal.y();
  852. params[2] = m_DefaultNormal.z();
  853. break;
  854. case GL_MODELVIEW_MATRIX:
  855. CopyMatrix(m_ModelViewMatrixStack.CurrentMatrix(), params);
  856. break;
  857. case GL_PROJECTION_MATRIX:
  858. CopyMatrix(m_ProjectionMatrixStack.CurrentMatrix(), params);
  859. break;
  860. case GL_TEXTURE_MATRIX:
  861. CopyMatrix(m_TextureMatrixStack[m_ActiveTexture].CurrentMatrix(), params);
  862. break;
  863. case GL_FOG_COLOR:
  864. CopyColor(m_RasterizerState.GetFogColor(), params);
  865. break;
  866. case GL_FOG_DENSITY:
  867. params[0] = m_FogDensity;
  868. break;
  869. case GL_FOG_START:
  870. params[0] = m_FogStart;
  871. break;
  872. case GL_FOG_END:
  873. params[0] = m_FogEnd;
  874. break;
  875. case GL_LIGHT_MODEL_AMBIENT:
  876. CopyColor(m_LightModelAmbient, params);
  877. break;
  878. case GL_COLOR_CLEAR_VALUE:
  879. CopyColor(m_ColorClearValue, params);
  880. break;
  881. case GL_ALIASED_LINE_WIDTH_RANGE:
  882. case GL_ALIASED_POINT_SIZE_RANGE:
  883. case GL_SMOOTH_LINE_WIDTH_RANGE:
  884. case GL_SMOOTH_POINT_SIZE_RANGE:
  885. params[0] = params[1] = EGL_ONE;
  886. break;
  887. case GL_POLYGON_OFFSET_UNITS:
  888. params[0] = m_RasterizerState.GetPolygonOffsetUnits();
  889. break;
  890. case GL_POLYGON_OFFSET_FACTOR:
  891. params[0] = m_RasterizerState.GetPolygonOffsetFactor();
  892. break;
  893. case GL_SAMPLE_COVERAGE_VALUE:
  894. params[0] = m_RasterizerState.GetSampleCoverage();
  895. break;
  896. case GL_POINT_SIZE_MIN:
  897. params[0] = m_PointSizeMin;
  898. break;
  899. case GL_POINT_SIZE_MAX:
  900. params[0] = m_PointSizeMax;
  901. break;
  902. case GL_POINT_FADE_THRESHOLD_SIZE:
  903. params[0] = m_PointFadeThresholdSize;
  904. break;
  905. case GL_POINT_DISTANCE_ATTENUATION:
  906. params[0] = m_PointDistanceAttenuation[0];
  907. params[1] = m_PointDistanceAttenuation[1];
  908. params[2] = m_PointDistanceAttenuation[2];
  909. break;
  910. case GL_DEPTH_RANGE:
  911. params[0] = m_DepthRangeNear;
  912. params[1] = m_DepthRangeFar;
  913. break;
  914. case GL_POINT_SIZE:
  915. case GL_LINE_WIDTH:
  916. params[0] = EGL_ONE;
  917. break;
  918. default:
  919. RecordError(GL_INVALID_ENUM);
  920. return false;
  921. }
  922. return true;
  923. }
  924. void Context :: GetPointerv(GLenum pname, void **params) {
  925. switch (pname) {
  926. case GL_VERTEX_ARRAY_POINTER:
  927. params[0] = const_cast<void *>(m_VertexArray.pointer);
  928. break;
  929. case GL_NORMAL_ARRAY_POINTER:
  930. params[0] = const_cast<void *>(m_NormalArray.pointer);
  931. break;
  932. case GL_COLOR_ARRAY_POINTER:
  933. params[0] = const_cast<void *>(m_ColorArray.pointer);
  934. break;
  935. case GL_TEXTURE_COORD_ARRAY_POINTER:
  936. params[0] = const_cast<void *>(m_TexCoordArray[m_ClientActiveTexture].pointer);
  937. break;
  938. case GL_MATRIX_INDEX_ARRAY_POINTER_OES:
  939. params[0] = const_cast<void *>(m_MatrixIndexArray.pointer);
  940. break;
  941. case GL_WEIGHT_ARRAY_POINTER_OES:
  942. params[0] = const_cast<void *>(m_WeightArray.pointer);
  943. break;
  944. case GL_POINT_SIZE_ARRAY_POINTER_OES:
  945. params[0] = const_cast<void *>(m_PointSizeArray.pointer);
  946. break;
  947. default:
  948. RecordError(GL_INVALID_ENUM);
  949. break;
  950. }
  951. }
  952. GLboolean Context :: IsEnabled(GLenum cap) {
  953. switch (cap) {
  954. case GL_VERTEX_ARRAY:
  955. return m_VertexArrayEnabled;
  956. case GL_NORMAL_ARRAY:
  957. return m_NormalArrayEnabled;
  958. case GL_COLOR_ARRAY:
  959. return m_ColorArrayEnabled;
  960. case GL_TEXTURE_COORD_ARRAY:
  961. return m_TexCoordArrayEnabled[m_ClientActiveTexture];
  962. case GL_MATRIX_INDEX_ARRAY_OES:
  963. return m_MatrixIndexArrayEnabled;
  964. case GL_WEIGHT_ARRAY_OES:
  965. return m_WeightArrayEnabled;
  966. case GL_POINT_SIZE_ARRAY_OES:
  967. return m_PointSizeArrayEnabled;
  968. case GL_NORMALIZE:
  969. return m_NormalizeEnabled;
  970. case GL_RESCALE_NORMAL:
  971. return m_RescaleNormalEnabled;
  972. case GL_LIGHT0:
  973. case GL_LIGHT1:
  974. case GL_LIGHT2:
  975. case GL_LIGHT3:
  976. case GL_LIGHT4:
  977. case GL_LIGHT5:
  978. case GL_LIGHT6:
  979. case GL_LIGHT7:
  980. {
  981. int mask = 1 << (cap - GL_LIGHT0);
  982. return (m_LightEnabled & mask) != 0;
  983. }
  984. case GL_CLIP_PLANE0:
  985. case GL_CLIP_PLANE1:
  986. case GL_CLIP_PLANE2:
  987. case GL_CLIP_PLANE3:
  988. case GL_CLIP_PLANE4:
  989. case GL_CLIP_PLANE5:
  990. {
  991. U32 bit = 1u << (cap - GL_CLIP_PLANE0);
  992. return (m_ClipPlaneEnabled & bit) != 0;
  993. }
  994. break;
  995. case GL_FOG:
  996. return m_RasterizerState.IsEnabledFog();
  997. case GL_LIGHTING:
  998. return m_LightingEnabled;
  999. case GL_COLOR_MATERIAL:
  1000. return m_ColorMaterialEnabled;
  1001. case GL_POINT_SMOOTH:
  1002. return m_RasterizerState.IsPointSmoothEnabled();
  1003. case GL_LINE_SMOOTH:
  1004. return m_RasterizerState.IsLineSmoothEnabled();
  1005. case GL_CULL_FACE:
  1006. return m_CullFaceEnabled;
  1007. case GL_POLYGON_OFFSET_FILL:
  1008. return m_RasterizerState.IsEnabledPolygonOffsetFill();
  1009. case GL_SCISSOR_TEST:
  1010. return m_ScissorTestEnabled;
  1011. case GL_ALPHA_TEST:
  1012. return m_RasterizerState.IsEnabledAlphaTest();
  1013. case GL_STENCIL_TEST:
  1014. return m_RasterizerState.IsEnabledStencilTest();
  1015. case GL_DEPTH_TEST:
  1016. return m_RasterizerState.IsEnabledDepthTest();
  1017. case GL_BLEND:
  1018. return m_RasterizerState.IsEnabledBlending();
  1019. case GL_COLOR_LOGIC_OP:
  1020. return m_RasterizerState.IsEnabledLogicOp();
  1021. case GL_TEXTURE_2D:
  1022. return m_RasterizerState.IsEnabledTexture(m_ActiveTexture);
  1023. case GL_MATRIX_PALETTE_OES:
  1024. return m_MatrixPaletteEnabled;
  1025. case GL_POINT_SPRITE_OES:
  1026. return m_RasterizerState.IsPointSpriteEnabled();
  1027. case GL_MULTISAMPLE:
  1028. return m_MultiSampleEnabled;
  1029. case GL_SAMPLE_ALPHA_TO_COVERAGE:
  1030. return m_SampleAlphaToCoverageEnabled;
  1031. case GL_SAMPLE_ALPHA_TO_ONE:
  1032. return m_SampleAlphaToOneEnabled;
  1033. case GL_SAMPLE_COVERAGE:
  1034. return m_SampleCoverageEnabled;
  1035. case GL_DITHER:
  1036. return m_DitherEnabled;
  1037. default:
  1038. RecordError(GL_INVALID_ENUM);
  1039. return false;
  1040. }
  1041. }