/opengles/src/ContextLines.cpp

http://ftk.googlecode.com/ · C++ · 440 lines · 284 code · 109 blank · 47 comment · 40 complexity · 416a1bc44250a5058265daa014cb4ecb MD5 · raw file

  1. // ==========================================================================
  2. //
  3. // ContextLines.cpp Rendering Context Class for 3D Rendering Library
  4. //
  5. // Rendering Operations for Lines
  6. //
  7. // --------------------------------------------------------------------------
  8. //
  9. // 08-12-2003 Hans-Martin Will initial version
  10. //
  11. // --------------------------------------------------------------------------
  12. //
  13. // Copyright (c) 2004, Hans-Martin Will. All rights reserved.
  14. //
  15. // Redistribution and use in source and binary forms, with or without
  16. // modification, are permitted provided that the following conditions are
  17. // met:
  18. //
  19. // * Redistributions of source code must retain the above copyright
  20. // notice, this list of conditions and the following disclaimer.
  21. // * Redistributions in binary form must reproduce the above copyright
  22. // notice, this list of conditions and the following disclaimer in the
  23. // documentation and/or other materials provided with the distribution.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  30. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  35. // THE POSSIBILITY OF SUCH DAMAGE.
  36. //
  37. // ==========================================================================
  38. #include "stdafx.h"
  39. #include "Context.h"
  40. #include "fixed.h"
  41. #include "Rasterizer.h"
  42. using namespace EGL;
  43. void Context :: LineWidthx(GLfixed width) {
  44. if (width <= 0) {
  45. RecordError(GL_INVALID_VALUE);
  46. } else {
  47. GetRasterizerState()->SetLineWidth(width);
  48. }
  49. }
  50. // --------------------------------------------------------------------------
  51. // Lines
  52. // --------------------------------------------------------------------------
  53. void Context :: RenderLines(GLint first, GLsizei count) {
  54. m_Rasterizer->PrepareLine();
  55. while (count >= 2) {
  56. count -= 2;
  57. RasterPos pos0, pos1;
  58. SelectArrayElement(first++);
  59. CurrentValuesToRasterPos(&pos0);
  60. SelectArrayElement(first++);
  61. CurrentValuesToRasterPos(&pos1);
  62. RenderLine(pos0, pos1);
  63. }
  64. }
  65. void Context :: RenderLines(GLsizei count, const GLubyte * indices) {
  66. m_Rasterizer->PrepareLine();
  67. while (count >= 2) {
  68. count -= 2;
  69. RasterPos pos0, pos1;
  70. SelectArrayElement(*indices++);
  71. CurrentValuesToRasterPos(&pos0);
  72. SelectArrayElement(*indices++);
  73. CurrentValuesToRasterPos(&pos1);
  74. RenderLine(pos0, pos1);
  75. }
  76. }
  77. void Context :: RenderLines(GLsizei count, const GLushort * indices) {
  78. m_Rasterizer->PrepareLine();
  79. while (count >= 2) {
  80. count -= 2;
  81. RasterPos pos0, pos1;
  82. SelectArrayElement(*indices++);
  83. CurrentValuesToRasterPos(&pos0);
  84. SelectArrayElement(*indices++);
  85. CurrentValuesToRasterPos(&pos1);
  86. RenderLine(pos0, pos1);
  87. }
  88. }
  89. // --------------------------------------------------------------------------
  90. // Line Strips
  91. // --------------------------------------------------------------------------
  92. void Context :: RenderLineStrip(GLint first, GLsizei count) {
  93. if (count >= 2) {
  94. m_Rasterizer->PrepareLine();
  95. RasterPos pos0, pos1;
  96. SelectArrayElement(first++);
  97. CurrentValuesToRasterPos(&pos0);
  98. --count;
  99. while (count >= 2) {
  100. count -= 2;
  101. SelectArrayElement(first++);
  102. CurrentValuesToRasterPos(&pos1);
  103. RenderLine(pos0, pos1);
  104. SelectArrayElement(first++);
  105. CurrentValuesToRasterPos(&pos0);
  106. RenderLine(pos1, pos0);
  107. }
  108. if (count >= 1) {
  109. SelectArrayElement(first++);
  110. CurrentValuesToRasterPos(&pos1);
  111. RenderLine(pos0, pos1);
  112. }
  113. }
  114. }
  115. void Context :: RenderLineStrip(GLsizei count, const GLubyte * indices) {
  116. if (count >= 2) {
  117. m_Rasterizer->PrepareLine();
  118. RasterPos pos0, pos1;
  119. SelectArrayElement(*indices++);
  120. CurrentValuesToRasterPos(&pos0);
  121. --count;
  122. while (count >= 2) {
  123. count -= 2;
  124. SelectArrayElement(*indices++);
  125. CurrentValuesToRasterPos(&pos1);
  126. RenderLine(pos0, pos1);
  127. SelectArrayElement(*indices++);
  128. CurrentValuesToRasterPos(&pos0);
  129. RenderLine(pos1, pos0);
  130. }
  131. if (count >= 1) {
  132. SelectArrayElement(*indices++);
  133. CurrentValuesToRasterPos(&pos1);
  134. RenderLine(pos0, pos1);
  135. }
  136. }
  137. }
  138. void Context :: RenderLineStrip(GLsizei count, const GLushort * indices) {
  139. if (count >= 2) {
  140. m_Rasterizer->PrepareLine();
  141. RasterPos pos0, pos1;
  142. SelectArrayElement(*indices++);
  143. CurrentValuesToRasterPos(&pos0);
  144. --count;
  145. while (count >= 2) {
  146. count -= 2;
  147. SelectArrayElement(*indices++);
  148. CurrentValuesToRasterPos(&pos1);
  149. RenderLine(pos0, pos1);
  150. SelectArrayElement(*indices++);
  151. CurrentValuesToRasterPos(&pos0);
  152. RenderLine(pos1, pos0);
  153. }
  154. if (count >= 1) {
  155. SelectArrayElement(*indices++);
  156. CurrentValuesToRasterPos(&pos1);
  157. RenderLine(pos0, pos1);
  158. }
  159. }
  160. }
  161. // --------------------------------------------------------------------------
  162. // Line Loops
  163. // --------------------------------------------------------------------------
  164. void Context :: RenderLineLoop(GLint first, GLsizei count) {
  165. if (count >= 2) {
  166. m_Rasterizer->PrepareLine();
  167. RasterPos pos0, pos1, start;
  168. SelectArrayElement(first++);
  169. CurrentValuesToRasterPos(&start);
  170. SelectArrayElement(first++);
  171. CurrentValuesToRasterPos(&pos0);
  172. RenderLine(start, pos0);
  173. count -= 2;
  174. while (count >= 2) {
  175. count -= 2;
  176. SelectArrayElement(first++);
  177. CurrentValuesToRasterPos(&pos1);
  178. RenderLine(pos0, pos1);
  179. SelectArrayElement(first++);
  180. CurrentValuesToRasterPos(&pos0);
  181. RenderLine(pos1, pos0);
  182. }
  183. if (count >= 1) {
  184. SelectArrayElement(first++);
  185. CurrentValuesToRasterPos(&pos1);
  186. RenderLine(pos0, pos1);
  187. RenderLine(pos1, start);
  188. } else {
  189. RenderLine(pos0, start);
  190. }
  191. }
  192. }
  193. void Context :: RenderLineLoop(GLsizei count, const GLubyte * indices) {
  194. if (count >= 2) {
  195. m_Rasterizer->PrepareLine();
  196. RasterPos pos0, pos1, start;
  197. SelectArrayElement(*indices++);
  198. CurrentValuesToRasterPos(&start);
  199. SelectArrayElement(*indices++);
  200. CurrentValuesToRasterPos(&pos0);
  201. RenderLine(start, pos0);
  202. count -= 2;
  203. while (count >= 2) {
  204. count -= 2;
  205. SelectArrayElement(*indices++);
  206. CurrentValuesToRasterPos(&pos1);
  207. RenderLine(pos0, pos1);
  208. SelectArrayElement(*indices++);
  209. CurrentValuesToRasterPos(&pos0);
  210. RenderLine(pos1, pos0);
  211. }
  212. if (count >= 1) {
  213. SelectArrayElement(*indices++);
  214. CurrentValuesToRasterPos(&pos1);
  215. RenderLine(pos0, pos1);
  216. RenderLine(pos1, start);
  217. } else {
  218. RenderLine(pos0, start);
  219. }
  220. }
  221. }
  222. void Context :: RenderLineLoop(GLsizei count, const GLushort * indices) {
  223. if (count >= 2) {
  224. m_Rasterizer->PrepareLine();
  225. RasterPos pos0, pos1, start;
  226. SelectArrayElement(*indices++);
  227. CurrentValuesToRasterPos(&start);
  228. SelectArrayElement(*indices++);
  229. CurrentValuesToRasterPos(&pos0);
  230. RenderLine(start, pos0);
  231. count -= 2;
  232. while (count >= 2) {
  233. count -= 2;
  234. SelectArrayElement(*indices++);
  235. CurrentValuesToRasterPos(&pos1);
  236. RenderLine(pos0, pos1);
  237. SelectArrayElement(*indices++);
  238. CurrentValuesToRasterPos(&pos0);
  239. RenderLine(pos1, pos0);
  240. }
  241. if (count >= 1) {
  242. SelectArrayElement(*indices++);
  243. CurrentValuesToRasterPos(&pos1);
  244. RenderLine(pos0, pos1);
  245. RenderLine(pos1, start);
  246. } else {
  247. RenderLine(pos0, start);
  248. }
  249. }
  250. }
  251. namespace {
  252. inline EGL_Fixed Interpolate(EGL_Fixed x0, EGL_Fixed x1, EGL_Fixed num, EGL_Fixed denom) {
  253. return x1 + (EGL_Fixed)((((I64)(x0-x1))*num)/denom);
  254. }
  255. inline void Interpolate(RasterPos& result, const RasterPos& dst, const RasterPos& src, EGL_Fixed num, EGL_Fixed denom) {
  256. result.m_ClipCoords.setX(Interpolate(dst.m_ClipCoords.x(), src.m_ClipCoords.x(), num, denom));
  257. result.m_ClipCoords.setY(Interpolate(dst.m_ClipCoords.y(), src.m_ClipCoords.y(), num, denom));
  258. result.m_ClipCoords.setZ(Interpolate(dst.m_ClipCoords.z(), src.m_ClipCoords.z(), num, denom));
  259. result.m_ClipCoords.setW(Interpolate(dst.m_ClipCoords.w(), src.m_ClipCoords.w(), num, denom));
  260. result.m_Color.r = Interpolate(dst.m_Color.r, src.m_Color.r, num, denom);
  261. result.m_Color.g = Interpolate(dst.m_Color.g, src.m_Color.g, num, denom);
  262. result.m_Color.b = Interpolate(dst.m_Color.b, src.m_Color.b, num, denom);
  263. result.m_Color.a = Interpolate(dst.m_Color.a, src.m_Color.a, num, denom);
  264. for (size_t index = 0; index < EGL_NUM_TEXTURE_UNITS; ++index) {
  265. result.m_TextureCoords[index].tu = Interpolate(dst.m_TextureCoords[index].tu, src.m_TextureCoords[index].tu, num, denom);
  266. result.m_TextureCoords[index].tv = Interpolate(dst.m_TextureCoords[index].tv, src.m_TextureCoords[index].tv, num, denom);
  267. }
  268. result.m_FogDensity = Interpolate(dst.m_FogDensity, src.m_FogDensity, num, denom);
  269. }
  270. inline bool ClipX(RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
  271. # define COORDINATE x()
  272. # include "LineClipper.inc"
  273. # undef COORDINATE
  274. }
  275. inline bool ClipY(RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
  276. # define COORDINATE y()
  277. # include "LineClipper.inc"
  278. # undef COORDINATE
  279. }
  280. inline bool ClipZ(RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
  281. # define COORDINATE z()
  282. # include "LineClipper.inc"
  283. # undef COORDINATE
  284. }
  285. inline bool ClipUser(const Vec4D& plane, RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
  286. EGL_Fixed f = from->m_EyeCoords * plane;
  287. EGL_Fixed t = to->m_EyeCoords * plane;
  288. if (f < 0) {
  289. if (t < 0) {
  290. return false;
  291. }
  292. Interpolate(*tempVertices, *from, *to, t, t - f);
  293. from = tempVertices++;
  294. return true;
  295. } else if (t < 0) {
  296. Interpolate(*tempVertices, *to, *from, f, f - t);
  297. to = tempVertices++;
  298. return true;
  299. } else {
  300. // no clipping
  301. return true;
  302. }
  303. }
  304. }
  305. void Context :: RenderLine(RasterPos& from, RasterPos& to) {
  306. RasterPos * tempVertices = m_Temporary;
  307. RasterPos * pFrom = &from;
  308. RasterPos * pTo = &to;
  309. if (m_ClipPlaneEnabled) {
  310. for (size_t index = 0, mask = 1; index < NUM_CLIP_PLANES; ++index, mask <<= 1) {
  311. if (m_ClipPlaneEnabled & mask) {
  312. if (!ClipUser(m_ClipPlanes[index], pFrom, pTo, tempVertices)) {
  313. return;
  314. }
  315. }
  316. }
  317. }
  318. if (ClipX(pFrom, pTo, tempVertices) &&
  319. ClipY(pFrom, pTo, tempVertices) &&
  320. ClipZ(pFrom, pTo, tempVertices)) {
  321. ClipCoordsToWindowCoords(*pFrom);
  322. ClipCoordsToWindowCoords(*pTo);
  323. if (m_RasterizerState.GetShadeModel() == RasterizerState::ShadeModelSmooth) {
  324. pFrom->m_Color = pFrom->m_FrontColor;
  325. } else {
  326. pFrom->m_Color = pTo->m_FrontColor;
  327. }
  328. pTo->m_Color = pTo->m_FrontColor;
  329. m_Rasterizer->RasterLine(*pFrom, *pTo);
  330. }
  331. }