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.
 
 
 

595 line
13 KiB

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