No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

600 líneas
13 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #include <cstdlib>
  14. #if defined _WIN32
  15. # define WIN32_LEAN_AND_MEAN 1
  16. # include <windows.h>
  17. # undef WIN32_LEAN_AND_MEAN
  18. # undef near /* Fuck Microsoft */
  19. # undef far /* Fuck Microsoft again */
  20. #endif
  21. // FIXME: fine-tune this define
  22. #if defined LOL_USE_GLEW || defined HAVE_GL_2X || defined HAVE_GLES_2X
  23. #include "lolgl.h"
  24. namespace lol
  25. {
  26. /*
  27. * The global g_renderers object, initialised by Video::Setup
  28. */
  29. //Renderer *g_renderer = nullptr;
  30. array<Renderer*> g_renderers;
  31. /*
  32. * Private RendererData class
  33. */
  34. class RendererData
  35. {
  36. friend class Renderer;
  37. private:
  38. ibox2 m_viewport;
  39. vec4 m_clear_color;
  40. float m_clear_depth;
  41. AlphaFunc m_alpha_func;
  42. float m_alpha_value;
  43. BlendEquation m_blend_rgb, m_blend_alpha;
  44. BlendFunc m_blend_src, m_blend_dst;
  45. DepthFunc m_depth_func;
  46. DepthMask m_depth_mask;
  47. CullMode m_cull_mode;
  48. PolygonMode m_polygon_mode;
  49. ScissorMode m_scissor_mode;
  50. vec4 m_scissor_rect;
  51. };
  52. /*
  53. * Public Renderer class
  54. */
  55. Renderer::Renderer(ivec2 size)
  56. : m_data(new RendererData())
  57. {
  58. #if defined LOL_USE_GLEW && !defined __APPLE__
  59. /* Initialise GLEW if necessary */
  60. GLenum glerr = glewInit();
  61. if (glerr != GLEW_OK)
  62. {
  63. msg::error("cannot initialise GLEW: %s\n", glewGetErrorString(glerr));
  64. exit(EXIT_FAILURE);
  65. }
  66. #endif
  67. /* Initialise rendering states */
  68. m_data->m_viewport = ibox2(0, 0, 0, 0);
  69. SetViewport(ibox2(ivec2::zero, size));
  70. m_data->m_clear_color = vec4(-1.f);
  71. SetClearColor(vec4(0.1f, 0.2f, 0.3f, 1.0f));
  72. m_data->m_clear_depth = -1.f;
  73. SetClearDepth(1.f);
  74. m_data->m_alpha_func = AlphaFunc::Never;
  75. m_data->m_alpha_value = -1.0f;
  76. SetAlphaFunc(AlphaFunc::Disabled, 0.0f);
  77. m_data->m_blend_rgb = BlendEquation::Subtract;
  78. m_data->m_blend_alpha = BlendEquation::Subtract;
  79. SetBlendEquation(BlendEquation::Add, BlendEquation::Add);
  80. m_data->m_blend_src = BlendFunc::Disabled;
  81. m_data->m_blend_dst = BlendFunc::Disabled;
  82. SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha);
  83. m_data->m_depth_func = DepthFunc::Disabled;
  84. SetDepthFunc(DepthFunc::LessOrEqual);
  85. m_data->m_depth_mask = DepthMask::Disabled;
  86. SetDepthMask(DepthMask::Enabled);
  87. m_data->m_cull_mode = CullMode::Disabled;
  88. SetCullMode(CullMode::Clockwise);
  89. m_data->m_polygon_mode = PolygonMode::Point;
  90. SetPolygonMode(PolygonMode::Fill);
  91. m_data->m_scissor_mode = ScissorMode::Disabled;
  92. SetPolygonMode(PolygonMode::Fill);
  93. /* Add some rendering states that we don't export to the user */
  94. #if defined HAVE_GL_2X && !defined __APPLE__
  95. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  96. #endif
  97. }
  98. Renderer::~Renderer()
  99. {
  100. delete m_data;
  101. }
  102. /*
  103. * Buffer clearing
  104. */
  105. void Renderer::Clear(ClearMask mask)
  106. {
  107. GLbitfield m = 0;
  108. if (mask & ClearMask::Color)
  109. m |= GL_COLOR_BUFFER_BIT;
  110. if (mask & ClearMask::Depth)
  111. m |= GL_DEPTH_BUFFER_BIT;
  112. if (mask & ClearMask::Stencil)
  113. m |= GL_STENCIL_BUFFER_BIT;
  114. glClear(m);
  115. }
  116. /*
  117. * Renderer static
  118. */
  119. void Renderer::AddNew(ivec2 size)
  120. {
  121. g_renderers << new Renderer(size);
  122. }
  123. int Renderer::GetCount()
  124. {
  125. return g_renderers.count();
  126. }
  127. Renderer* Renderer::Get(int index)
  128. {
  129. return g_renderers[index];
  130. }
  131. void Renderer::DestroyAll()
  132. {
  133. for (Renderer* renderer : g_renderers)
  134. delete renderer;
  135. g_renderers.clear();
  136. }
  137. /*
  138. * Viewport dimensions
  139. */
  140. void Renderer::SetViewport(ibox2 viewport)
  141. {
  142. if (m_data->m_viewport == viewport)
  143. return;
  144. glViewport(viewport.aa.x, viewport.aa.y, viewport.bb.x, viewport.bb.y);
  145. m_data->m_viewport = viewport;
  146. }
  147. ibox2 Renderer::GetViewport() const
  148. {
  149. return m_data->m_viewport;
  150. }
  151. float Renderer::GetXYRatio() const
  152. {
  153. ivec2 s = GetViewport().extent();
  154. return (float)s.x / s.y;
  155. }
  156. float Renderer::GetYXRatio() const
  157. {
  158. ivec2 s = GetViewport().extent();
  159. return (float)s.y / s.x;
  160. }
  161. /*
  162. * Clear color
  163. */
  164. void Renderer::SetClearColor(vec4 color)
  165. {
  166. if (m_data->m_clear_color == color)
  167. return;
  168. glClearColor(color.r, color.g, color.b, color.a);
  169. m_data->m_clear_color = color;
  170. }
  171. vec4 Renderer::GetClearColor() const
  172. {
  173. return m_data->m_clear_color;
  174. }
  175. /*
  176. * Clear depth
  177. */
  178. void Renderer::SetClearDepth(float depth)
  179. {
  180. if (m_data->m_clear_depth == depth)
  181. return;
  182. #if defined HAVE_GLES_2X
  183. glClearDepthf(depth);
  184. #else
  185. glClearDepth(depth);
  186. #endif
  187. m_data->m_clear_depth = depth;
  188. }
  189. float Renderer::GetClearDepth() const
  190. {
  191. return m_data->m_clear_depth;
  192. }
  193. /*
  194. * Alpha testing
  195. */
  196. void Renderer::SetAlphaFunc(AlphaFunc func, float alpha)
  197. {
  198. if (m_data->m_alpha_func == func && m_data->m_alpha_value == alpha)
  199. return;
  200. #if defined HAVE_GLES_2X
  201. /* not supported */
  202. #elif defined GL_VERSION_1_1
  203. switch (func)
  204. {
  205. case AlphaFunc::Disabled:
  206. break; /* Nothing to do */
  207. case AlphaFunc::Never:
  208. glAlphaFunc(GL_NEVER, alpha); break;
  209. case AlphaFunc::Less:
  210. glAlphaFunc(GL_LESS, alpha); break;
  211. case AlphaFunc::Equal:
  212. glAlphaFunc(GL_EQUAL, alpha); break;
  213. case AlphaFunc::LessOrEqual:
  214. glAlphaFunc(GL_LEQUAL, alpha); break;
  215. case AlphaFunc::Greater:
  216. glAlphaFunc(GL_GREATER, alpha); break;
  217. case AlphaFunc::NotEqual:
  218. glAlphaFunc(GL_NOTEQUAL, alpha); break;
  219. case AlphaFunc::GreaterOrEqual:
  220. glAlphaFunc(GL_GEQUAL, alpha); break;
  221. case AlphaFunc::Always:
  222. glAlphaFunc(GL_ALWAYS, alpha); break;
  223. }
  224. if (func == AlphaFunc::Disabled)
  225. glDisable(GL_ALPHA_TEST);
  226. else
  227. glEnable(GL_ALPHA_TEST);
  228. #else
  229. /* XXX: alpha test not available in GL ES and deprecated anyway. */
  230. #endif
  231. m_data->m_alpha_func = func;
  232. m_data->m_alpha_value = alpha;
  233. }
  234. AlphaFunc Renderer::GetAlphaFunc() const
  235. {
  236. return m_data->m_alpha_func;
  237. }
  238. float Renderer::GetAlphaValue() const
  239. {
  240. return m_data->m_alpha_value;
  241. }
  242. /*
  243. * Blend equation
  244. */
  245. void Renderer::SetBlendEquation(BlendEquation rgb, BlendEquation alpha)
  246. {
  247. if (m_data->m_blend_rgb == rgb && m_data->m_blend_alpha == alpha)
  248. return;
  249. GLenum s1[2] = { GL_FUNC_ADD, GL_FUNC_ADD };
  250. BlendEquation s2[2] = { rgb, alpha };
  251. for (int i = 0; i < 2; ++i)
  252. {
  253. switch (s2[i])
  254. {
  255. case BlendEquation::Add:
  256. s1[i] = GL_FUNC_ADD; break;
  257. case BlendEquation::Subtract:
  258. s1[i] = GL_FUNC_SUBTRACT; break;
  259. case BlendEquation::ReverseSubtract:
  260. s1[i] = GL_FUNC_REVERSE_SUBTRACT; break;
  261. #if defined GL_MIN && defined GL_MAX
  262. case BlendEquation::Min:
  263. s1[i] = GL_MIN; break;
  264. case BlendEquation::Max:
  265. s1[i] = GL_MAX; break;
  266. #else
  267. case BlendEquation::Min:
  268. s1[i] = GL_MIN_EXT; break;
  269. case BlendEquation::Max:
  270. s1[i] = GL_MAX_EXT; break;
  271. #endif
  272. }
  273. }
  274. glBlendEquationSeparate(s1[0], s1[1]);
  275. m_data->m_blend_rgb = rgb;
  276. m_data->m_blend_alpha = alpha;
  277. }
  278. BlendEquation Renderer::GetBlendEquationRgb() const
  279. {
  280. return m_data->m_blend_rgb;
  281. }
  282. BlendEquation Renderer::GetBlendEquationAlpha() const
  283. {
  284. return m_data->m_blend_alpha;
  285. }
  286. /*
  287. * Blend function
  288. */
  289. void Renderer::SetBlendFunc(BlendFunc src, BlendFunc dst)
  290. {
  291. if (m_data->m_blend_src == src && m_data->m_blend_dst == dst)
  292. return;
  293. GLenum s1[2] = { GL_ONE, GL_ZERO };
  294. BlendFunc s2[2] = { src, dst };
  295. for (int i = 0; i < 2; ++i)
  296. {
  297. switch (s2[i])
  298. {
  299. case BlendFunc::Disabled:
  300. break; /* Nothing to do */
  301. case BlendFunc::Zero:
  302. s1[i] = GL_ZERO; break;
  303. case BlendFunc::One:
  304. s1[i] = GL_ONE; break;
  305. case BlendFunc::SrcColor:
  306. s1[i] = GL_SRC_COLOR; break;
  307. case BlendFunc::OneMinusSrcColor:
  308. s1[i] = GL_ONE_MINUS_SRC_COLOR; break;
  309. case BlendFunc::DstColor:
  310. s1[i] = GL_DST_COLOR; break;
  311. case BlendFunc::OneMinusDstColor:
  312. s1[i] = GL_ONE_MINUS_DST_COLOR; break;
  313. case BlendFunc::SrcAlpha:
  314. s1[i] = GL_SRC_ALPHA; break;
  315. case BlendFunc::OneMinusSrcAlpha:
  316. s1[i] = GL_ONE_MINUS_SRC_ALPHA; break;
  317. case BlendFunc::DstAlpha:
  318. s1[i] = GL_DST_ALPHA; break;
  319. case BlendFunc::OneMinusDstAlpha:
  320. s1[i] = GL_ONE_MINUS_DST_ALPHA; break;
  321. case BlendFunc::ConstantColor:
  322. s1[i] = GL_CONSTANT_COLOR; break;
  323. case BlendFunc::OneMinusConstantColor:
  324. s1[i] = GL_ONE_MINUS_CONSTANT_COLOR; break;
  325. case BlendFunc::ConstantAlpha:
  326. s1[i] = GL_CONSTANT_ALPHA; break;
  327. case BlendFunc::OneMinusConstantAlpha:
  328. s1[i] = GL_ONE_MINUS_CONSTANT_ALPHA; break;
  329. }
  330. }
  331. if (src == BlendFunc::Disabled)
  332. {
  333. glDisable(GL_BLEND);
  334. }
  335. else
  336. {
  337. glEnable(GL_BLEND);
  338. glBlendFunc(s1[0], s1[1]);
  339. }
  340. m_data->m_blend_src = src;
  341. m_data->m_blend_dst = dst;
  342. }
  343. BlendFunc Renderer::GetBlendFuncSrc() const
  344. {
  345. return m_data->m_blend_src;
  346. }
  347. BlendFunc Renderer::GetBlendFuncDst() const
  348. {
  349. return m_data->m_blend_dst;
  350. }
  351. /*
  352. * Depth test
  353. */
  354. void Renderer::SetDepthFunc(DepthFunc func)
  355. {
  356. if (m_data->m_depth_func == func)
  357. return;
  358. switch (func)
  359. {
  360. case DepthFunc::Disabled:
  361. break; /* Nothing to do */
  362. case DepthFunc::Never:
  363. glDepthFunc(GL_NEVER); break;
  364. case DepthFunc::Less:
  365. glDepthFunc(GL_LESS); break;
  366. case DepthFunc::Equal:
  367. glDepthFunc(GL_EQUAL); break;
  368. case DepthFunc::LessOrEqual:
  369. glDepthFunc(GL_LEQUAL); break;
  370. case DepthFunc::Greater:
  371. glDepthFunc(GL_GREATER); break;
  372. case DepthFunc::NotEqual:
  373. glDepthFunc(GL_NOTEQUAL); break;
  374. case DepthFunc::GreaterOrEqual:
  375. glDepthFunc(GL_GEQUAL); break;
  376. case DepthFunc::Always:
  377. glDepthFunc(GL_ALWAYS); break;
  378. }
  379. if (func == DepthFunc::Disabled)
  380. glDisable(GL_DEPTH_TEST);
  381. else
  382. glEnable(GL_DEPTH_TEST);
  383. m_data->m_depth_func = func;
  384. }
  385. DepthFunc Renderer::GetDepthFunc() const
  386. {
  387. return m_data->m_depth_func;
  388. }
  389. /*
  390. * Depth mask
  391. */
  392. void Renderer::SetDepthMask(DepthMask mask)
  393. {
  394. if (m_data->m_depth_mask == mask)
  395. return;
  396. if (mask == DepthMask::Disabled)
  397. glDepthMask(GL_FALSE);
  398. else
  399. glDepthMask(GL_TRUE);
  400. m_data->m_depth_mask = mask;
  401. }
  402. DepthMask Renderer::GetDepthMask() const
  403. {
  404. return m_data->m_depth_mask;
  405. }
  406. /*
  407. * Face culling
  408. */
  409. void Renderer::SetCullMode(CullMode mode)
  410. {
  411. if (m_data->m_cull_mode == mode)
  412. return;
  413. switch (mode)
  414. {
  415. case CullMode::Disabled:
  416. glDisable(GL_CULL_FACE);
  417. break;
  418. case CullMode::Clockwise:
  419. glEnable(GL_CULL_FACE);
  420. glCullFace(GL_FRONT);
  421. glFrontFace(GL_CW);
  422. break;
  423. case CullMode::CounterClockwise:
  424. glEnable(GL_CULL_FACE);
  425. glCullFace(GL_FRONT);
  426. glFrontFace(GL_CCW);
  427. break;
  428. }
  429. m_data->m_cull_mode = mode;
  430. }
  431. CullMode Renderer::GetCullMode() const
  432. {
  433. return m_data->m_cull_mode;
  434. }
  435. /*
  436. * Polygon rendering mode
  437. */
  438. void Renderer::SetPolygonMode(PolygonMode mode)
  439. {
  440. if (m_data->m_polygon_mode == mode)
  441. return;
  442. #if defined HAVE_GLES_2X
  443. /* not supported */
  444. #elif defined GL_VERSION_1_1
  445. switch (mode)
  446. {
  447. case PolygonMode::Point:
  448. glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  449. break;
  450. case PolygonMode::Line:
  451. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  452. break;
  453. case PolygonMode::Fill:
  454. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  455. break;
  456. }
  457. #endif
  458. m_data->m_polygon_mode = mode;
  459. }
  460. PolygonMode Renderer::GetPolygonMode() const
  461. {
  462. return m_data->m_polygon_mode;
  463. }
  464. /*
  465. * Scissor test mode
  466. */
  467. void Renderer::SetScissorMode(ScissorMode mode)
  468. {
  469. if (m_data->m_scissor_mode == mode)
  470. return;
  471. if (mode == ScissorMode::Enabled)
  472. glEnable(GL_SCISSOR_TEST);
  473. else
  474. glDisable(GL_SCISSOR_TEST);
  475. m_data->m_scissor_mode = mode;
  476. }
  477. void Renderer::SetScissorRect(vec4 rect)
  478. {
  479. m_data->m_scissor_rect = rect;
  480. if (m_data->m_scissor_mode == ScissorMode::Enabled)
  481. {
  482. glScissor((int)rect.x, (int)Video::GetSize().y - rect.w, (int)(rect.z - rect.x), (int)(rect.w - rect.y));
  483. //glScissor((int)rect.x, (int)rect.y, (int)(rect.z - rect.x), (int)(rect.w - rect.y));
  484. }
  485. }
  486. ScissorMode Renderer::GetScissorMode() const
  487. {
  488. return m_data->m_scissor_mode;
  489. }
  490. vec4 Renderer::GetScissorRect() const
  491. {
  492. return m_data->m_scissor_rect;
  493. }
  494. } /* namespace lol */
  495. #endif