GLRenderer.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. /*
  2. Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
  3. Permission is hereby granted, free of charge, to any person
  4. obtaining a copy of this software and associated documentation
  5. files (the "Software"), to deal in the Software without
  6. restriction, including without limitation the rights to use,
  7. copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the
  9. Software is furnished to do so, subject to the following
  10. conditions:
  11. The above copyright notice and this permission notice shall be
  12. included in all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  15. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  17. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  18. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include "Config.h"
  23. #include <GL/glew.h>
  24. #include <cassert>
  25. #include <algorithm>
  26. #include "Types.h"
  27. #include "GLIndexBuffer.h"
  28. #include "GLOcclusionQuery.h"
  29. #include "GLRenderer.h"
  30. #include "GLUtils.h"
  31. #include "GLVertexBuffer.h"
  32. #include "Log.h"
  33. #include "Material.h"
  34. #include "Allocator.h"
  35. #include "TextureResource.h"
  36. #if defined(WINDOWS)
  37. //Define the missing constants in vs' gl.h
  38. #define GL_TEXTURE_3D 0x806F
  39. #define GL_TEXTURE_CUBE_MAP 0x8513
  40. #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
  41. #define GL_SEPARATE_SPECULAR_COLOR 0x81FA
  42. #define GL_SINGLE_COLOR 0x81F9
  43. #define GL_GENERATE_MIPMAP 0x8191
  44. #endif
  45. namespace crown
  46. {
  47. //-----------------------------------------------------------------------------
  48. GLRenderer::GLRenderer() :
  49. m_max_lights(0),
  50. m_max_texture_size(0),
  51. m_max_texture_units(0),
  52. m_max_vertex_indices(0),
  53. m_max_vertex_vertices(0),
  54. m_max_anisotropy(0.0f),
  55. m_texture_count(0),
  56. m_active_texture_unit(0)
  57. {
  58. m_min_max_point_size[0] = 0.0f;
  59. m_min_max_point_size[1] = 0.0f;
  60. m_min_max_line_width[0] = 0.0f;
  61. m_min_max_line_width[1] = 0.0f;
  62. // Initialize viewport and scissor
  63. m_viewport[0] = 0;
  64. m_viewport[1] = 0;
  65. m_viewport[2] = 0;
  66. m_viewport[3] = 0;
  67. m_scissor[0] = 0;
  68. m_scissor[1] = 0;
  69. m_scissor[2] = 0;
  70. m_scissor[3] = 0;
  71. // Initialize texture units
  72. for (uint32_t i = 0; i < MAX_TEXTURE_UNITS; i++)
  73. {
  74. m_texture_unit[i] = 0;
  75. m_texture_unit_target[i] = GL_TEXTURE_2D;
  76. }
  77. // Initialize the matrices
  78. for (uint32_t i = 0; i < MT_COUNT; i++)
  79. {
  80. m_matrix[i].load_identity();
  81. }
  82. GLenum err = glewInit();
  83. assert(err == GLEW_OK);
  84. Log::i("GLEW initialized.");
  85. glGetIntegerv(GL_MAX_LIGHTS, &m_max_lights);
  86. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
  87. glGetIntegerv(GL_MAX_TEXTURE_UNITS, &m_max_texture_units);
  88. glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &m_max_vertex_indices);
  89. glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &m_max_vertex_vertices);
  90. // Check for anisotropic filter support
  91. if (GLEW_EXT_texture_filter_anisotropic)
  92. {
  93. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_max_anisotropy);
  94. }
  95. glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, &m_min_max_point_size[0]);
  96. glGetFloatv(GL_LINE_WIDTH_RANGE, &m_min_max_line_width[0]);
  97. const unsigned char* gl_vendor = glGetString(GL_VENDOR);
  98. const unsigned char* gl_renderer = glGetString(GL_RENDERER);
  99. const unsigned char* gl_version = glGetString(GL_VERSION);
  100. Log::i("OpenGL Vendor\t: %s", gl_vendor);
  101. Log::i("OpenGL Renderer\t: %s", gl_renderer);
  102. Log::i("OpenGL Version\t: %s", gl_version);
  103. Log::i("Min Point Size\t: %f", m_min_max_point_size[0]);
  104. Log::i("Max Point Size\t: %f", m_min_max_point_size[1]);
  105. Log::i("Min Line Width\t: %f", m_min_max_line_width[0]);
  106. Log::i("Max Line Width\t: %f", m_min_max_line_width[1]);
  107. Log::i("Max Texture Size\t: %dx%d", m_max_texture_size, m_max_texture_size);
  108. Log::i("Max Texture Units\t: %d", m_max_texture_units);
  109. Log::i("Max Lights\t\t: %d", m_max_lights);
  110. Log::i("Max Vertex Indices\t: %d", m_max_vertex_indices);
  111. Log::i("Max Vertex Vertices\t: %d", m_max_vertex_vertices);
  112. Log::i("Max Anisotropy\t: %f", m_max_anisotropy);
  113. glMatrixMode(GL_PROJECTION);
  114. glLoadIdentity();
  115. glMatrixMode(GL_MODELVIEW);
  116. glLoadIdentity();
  117. glDisable(GL_TEXTURE_2D);
  118. glEnable(GL_LIGHTING);
  119. glEnable(GL_BLEND);
  120. //TODO: Use Premultiplied alpha
  121. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  122. glBlendEquation(GL_FUNC_ADD);
  123. glFrontFace(GL_CCW);
  124. glEnable(GL_CULL_FACE);
  125. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  126. glShadeModel(GL_SMOOTH);
  127. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  128. // Set the global ambient light
  129. float amb[] = { 0.0f, 0.0f, 0.0f, 1.0f };
  130. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
  131. // Some hints
  132. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  133. // Set the framebuffer clear color
  134. glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
  135. // Enable depth test
  136. glEnable(GL_DEPTH_TEST);
  137. glDepthFunc(GL_LEQUAL);
  138. glClearDepth(1.0);
  139. // Enable scissor test
  140. glEnable(GL_SCISSOR_TEST);
  141. // Disable dithering
  142. glDisable(GL_DITHER);
  143. Log::i("OpenGL Renderer initialized.");
  144. }
  145. //-----------------------------------------------------------------------------
  146. GLRenderer::~GLRenderer()
  147. {
  148. }
  149. //-----------------------------------------------------------------------------
  150. void GLRenderer::set_clear_color(const Color4& color)
  151. {
  152. glClearColor(color.r, color.g, color.b, color.a);
  153. }
  154. //-----------------------------------------------------------------------------
  155. void GLRenderer::set_material_params(const Color4& ambient, const Color4& diffuse, const Color4& specular,
  156. const Color4& emission, int32_t shininess)
  157. {
  158. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r);
  159. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r);
  160. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r);
  161. glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &emission.r);
  162. glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  163. }
  164. //-----------------------------------------------------------------------------
  165. void GLRenderer::set_ambient_light(const Color4& color)
  166. {
  167. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.to_float_ptr());
  168. }
  169. //-----------------------------------------------------------------------------
  170. void GLRenderer::set_lighting(bool lighting)
  171. {
  172. if (lighting)
  173. {
  174. glEnable(GL_LIGHTING);
  175. }
  176. else
  177. {
  178. glDisable(GL_LIGHTING);
  179. }
  180. }
  181. //-----------------------------------------------------------------------------
  182. void GLRenderer::set_texturing(uint32_t unit, bool texturing)
  183. {
  184. if (!activate_texture_unit(unit))
  185. return;
  186. if (texturing)
  187. {
  188. glEnable(m_texture_unit_target[unit]);
  189. }
  190. else
  191. {
  192. glDisable(m_texture_unit_target[unit]);
  193. }
  194. }
  195. //-----------------------------------------------------------------------------
  196. void GLRenderer::set_texture(uint32_t unit, TextureId texture)
  197. {
  198. if (!activate_texture_unit(unit))
  199. {
  200. return;
  201. }
  202. m_texture_unit_target[unit] = GL_TEXTURE_2D;
  203. m_texture_unit[unit] = m_textures[texture.index].texture_object;
  204. glEnable(m_texture_unit_target[unit]);
  205. glBindTexture(m_texture_unit_target[unit], m_texture_unit[unit]);
  206. }
  207. //-----------------------------------------------------------------------------
  208. void GLRenderer::set_texture_mode(uint32_t unit, TextureMode mode, const Color4& blendColor)
  209. {
  210. if (!activate_texture_unit(unit))
  211. return;
  212. GLint envMode = GL::GetTextureMode(mode);
  213. if (envMode == GL_BLEND)
  214. {
  215. glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &blendColor.r);
  216. }
  217. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envMode);
  218. }
  219. //-----------------------------------------------------------------------------
  220. void GLRenderer::set_texture_wrap(uint32_t unit, TextureWrap wrap)
  221. {
  222. GLenum glWrap = GL::GetTextureWrap(wrap);
  223. glTexParameteri(m_texture_unit_target[unit], GL_TEXTURE_WRAP_S, glWrap);
  224. glTexParameteri(m_texture_unit_target[unit], GL_TEXTURE_WRAP_T, glWrap);
  225. glTexParameteri(m_texture_unit_target[unit], GL_TEXTURE_WRAP_R, glWrap);
  226. }
  227. //-----------------------------------------------------------------------------
  228. void GLRenderer::set_texture_filter(uint32_t unit, TextureFilter filter)
  229. {
  230. if (!activate_texture_unit(unit))
  231. return;
  232. GLint minFilter;
  233. GLint magFilter;
  234. GL::GetTextureFilter(filter, minFilter, magFilter);
  235. glTexParameteri(m_texture_unit_target[unit], GL_TEXTURE_MIN_FILTER, minFilter);
  236. glTexParameteri(m_texture_unit_target[unit], GL_TEXTURE_MAG_FILTER, magFilter);
  237. }
  238. //-----------------------------------------------------------------------------
  239. void GLRenderer::set_backface_culling(bool culling)
  240. {
  241. if (culling)
  242. {
  243. glEnable(GL_CULL_FACE);
  244. }
  245. else
  246. {
  247. glDisable(GL_CULL_FACE);
  248. }
  249. }
  250. //-----------------------------------------------------------------------------
  251. void GLRenderer::set_separate_specular_color(bool separate)
  252. {
  253. if (separate)
  254. {
  255. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  256. }
  257. else
  258. {
  259. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  260. }
  261. }
  262. //-----------------------------------------------------------------------------
  263. void GLRenderer::set_depth_test(bool test)
  264. {
  265. if (test)
  266. {
  267. glEnable(GL_DEPTH_TEST);
  268. }
  269. else
  270. {
  271. glDisable(GL_DEPTH_TEST);
  272. }
  273. }
  274. //-----------------------------------------------------------------------------
  275. void GLRenderer::set_depth_write(bool write)
  276. {
  277. glDepthMask((GLboolean) write);
  278. }
  279. //-----------------------------------------------------------------------------
  280. void GLRenderer::set_depth_func(CompareFunction func)
  281. {
  282. GLenum glFunc = GL::GetCompareFunction(func);
  283. glDepthFunc(glFunc);
  284. }
  285. //-----------------------------------------------------------------------------
  286. void GLRenderer::set_rescale_normals(bool rescale)
  287. {
  288. if (rescale)
  289. {
  290. glEnable(GL_RESCALE_NORMAL);
  291. }
  292. else
  293. {
  294. glDisable(GL_RESCALE_NORMAL);
  295. }
  296. }
  297. //-----------------------------------------------------------------------------
  298. void GLRenderer::set_blending(bool blending)
  299. {
  300. if (blending)
  301. {
  302. glEnable(GL_BLEND);
  303. }
  304. else
  305. {
  306. glDisable(GL_BLEND);
  307. }
  308. }
  309. //-----------------------------------------------------------------------------
  310. void GLRenderer::set_blending_params(BlendEquation equation, BlendFunction src, BlendFunction dst, const Color4& color)
  311. {
  312. GLenum glEquation = GL::GetBlendEquation(equation);
  313. glBlendEquation(glEquation);
  314. GLenum glSrcFactor = GL::GetBlendFunction(src);
  315. GLenum glDstFactor = GL::GetBlendFunction(dst);
  316. glBlendFunc(glSrcFactor, glDstFactor);
  317. glBlendColor(color.r, color.g, color.b, color.a);
  318. }
  319. //-----------------------------------------------------------------------------
  320. void GLRenderer::set_color_write(bool write)
  321. {
  322. if (write)
  323. {
  324. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  325. }
  326. else
  327. {
  328. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  329. }
  330. }
  331. //-----------------------------------------------------------------------------
  332. void GLRenderer::set_fog(bool fog)
  333. {
  334. if (fog)
  335. {
  336. glEnable(GL_FOG);
  337. }
  338. else
  339. {
  340. glDisable(GL_FOG);
  341. }
  342. }
  343. //-----------------------------------------------------------------------------
  344. void GLRenderer::set_fog_params(FogMode mode, float density, float start, float end, const Color4& color)
  345. {
  346. GLenum glMode = GL::GetFogMode(mode);
  347. glFogi(GL_FOG_MODE, glMode);
  348. glFogf(GL_FOG_DENSITY, density);
  349. glFogf(GL_FOG_START, start);
  350. glFogf(GL_FOG_END, end);
  351. glFogfv(GL_FOG_COLOR, &color.r);
  352. }
  353. //-----------------------------------------------------------------------------
  354. void GLRenderer::set_alpha_test(bool test)
  355. {
  356. if (test)
  357. {
  358. glEnable(GL_ALPHA_TEST);
  359. }
  360. else
  361. {
  362. glDisable(GL_ALPHA_TEST);
  363. }
  364. }
  365. //-----------------------------------------------------------------------------
  366. void GLRenderer::set_alpha_params(CompareFunction func, float ref)
  367. {
  368. GLenum glFunc = GL::GetCompareFunction(func);
  369. glAlphaFunc(glFunc, ref);
  370. }
  371. //-----------------------------------------------------------------------------
  372. void GLRenderer::set_shading_type(ShadingType type)
  373. {
  374. GLenum glMode = GL_SMOOTH;
  375. if (type == ST_FLAT)
  376. {
  377. glMode = GL_FLAT;
  378. }
  379. glShadeModel(glMode);
  380. }
  381. //-----------------------------------------------------------------------------
  382. void GLRenderer::set_polygon_mode(PolygonMode mode)
  383. {
  384. GLenum glMode = GL::GetPolygonMode(mode);
  385. glPolygonMode(GL_FRONT_AND_BACK, glMode);
  386. }
  387. //-----------------------------------------------------------------------------
  388. void GLRenderer::set_front_face(FrontFace face)
  389. {
  390. GLenum glFace = GL_CCW;
  391. if (face == FF_CW)
  392. {
  393. glFace = GL_CW;
  394. }
  395. glFrontFace(glFace);
  396. }
  397. //-----------------------------------------------------------------------------
  398. void GLRenderer::set_viewport_params(int32_t x, int32_t y, int32_t width, int32_t height)
  399. {
  400. m_viewport[0] = x;
  401. m_viewport[1] = y;
  402. m_viewport[2] = width;
  403. m_viewport[3] = height;
  404. glViewport(x, y, width, height);
  405. }
  406. //-----------------------------------------------------------------------------
  407. void GLRenderer::get_viewport_params(int32_t& x, int32_t& y, int32_t& width, int32_t& height)
  408. {
  409. x = m_viewport[0];
  410. y = m_viewport[1];
  411. width = m_viewport[2];
  412. height = m_viewport[3];
  413. }
  414. //-----------------------------------------------------------------------------
  415. void GLRenderer::set_scissor(bool scissor)
  416. {
  417. if (scissor)
  418. {
  419. glEnable(GL_SCISSOR_TEST);
  420. }
  421. else
  422. {
  423. glDisable(GL_SCISSOR_TEST);
  424. }
  425. }
  426. //-----------------------------------------------------------------------------
  427. void GLRenderer::set_scissor_params(int32_t x, int32_t y, int32_t width, int32_t height)
  428. {
  429. m_scissor[0] = x;
  430. m_scissor[1] = y;
  431. m_scissor[2] = width;
  432. m_scissor[3] = height;
  433. glScissor(x, y, width, height);
  434. }
  435. //-----------------------------------------------------------------------------
  436. void GLRenderer::get_scissor_params(int32_t& x, int32_t& y, int32_t& width, int32_t& height)
  437. {
  438. x = m_scissor[0];
  439. y = m_scissor[1];
  440. width = m_scissor[2];
  441. height = m_scissor[3];
  442. }
  443. //-----------------------------------------------------------------------------
  444. void GLRenderer::set_point_sprite(bool sprite)
  445. {
  446. if (sprite)
  447. {
  448. glEnable(GL_POINT_SPRITE);
  449. glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
  450. }
  451. else
  452. {
  453. glDisable(GL_POINT_SPRITE);
  454. glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
  455. }
  456. }
  457. //-----------------------------------------------------------------------------
  458. void GLRenderer::set_point_size(float size)
  459. {
  460. glPointSize(size);
  461. }
  462. //-----------------------------------------------------------------------------
  463. void GLRenderer::set_point_params(float min, float max)
  464. {
  465. glPointParameterf(GL_POINT_SIZE_MIN, min);
  466. glPointParameterf(GL_POINT_SIZE_MAX, max);
  467. }
  468. //-----------------------------------------------------------------------------
  469. void GLRenderer::begin_frame()
  470. {
  471. // Clear frame/depth buffer
  472. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  473. }
  474. //-----------------------------------------------------------------------------
  475. void GLRenderer::end_frame()
  476. {
  477. glFinish();
  478. check_gl_errors();
  479. }
  480. //-----------------------------------------------------------------------------
  481. Mat4 GLRenderer::get_matrix(MatrixType type) const
  482. {
  483. return m_matrix[type];
  484. }
  485. //-----------------------------------------------------------------------------
  486. void GLRenderer::set_matrix(MatrixType type, const Mat4& matrix)
  487. {
  488. m_matrix[type] = matrix;
  489. switch (type)
  490. {
  491. case MT_VIEW:
  492. case MT_MODEL:
  493. glMatrixMode(GL_MODELVIEW);
  494. // Transformations must be listed in reverse order
  495. glLoadMatrixf((m_matrix[MT_VIEW] * m_matrix[MT_MODEL]).to_float_ptr());
  496. break;
  497. case MT_PROJECTION:
  498. glMatrixMode(GL_PROJECTION);
  499. glLoadMatrixf(m_matrix[MT_PROJECTION].to_float_ptr());
  500. break;
  501. case MT_TEXTURE:
  502. glMatrixMode(GL_TEXTURE);
  503. glLoadMatrixf(m_matrix[MT_TEXTURE].to_float_ptr());
  504. break;
  505. case MT_COLOR:
  506. //glMatrixMode(GL_COLOR);
  507. //glLoadMatrixf(m_matrix[MT_COLOR].to_float_ptr());
  508. break;
  509. default:
  510. break;
  511. }
  512. }
  513. //-----------------------------------------------------------------------------
  514. void GLRenderer::draw_vertex_index_buffer(const VertexBuffer* vertices, const IndexBuffer* indices)
  515. {
  516. assert(vertices != NULL);
  517. assert(indices != NULL);
  518. glEnableClientState(GL_VERTEX_ARRAY);
  519. glEnableClientState(GL_NORMAL_ARRAY);
  520. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  521. glEnableClientState(GL_COLOR_ARRAY);
  522. vertices->Bind();
  523. indices->Bind();
  524. glDrawElements(GL_TRIANGLES, indices->GetIndexCount(), GL_UNSIGNED_SHORT, 0);
  525. glDisableClientState(GL_COLOR_ARRAY);
  526. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  527. glDisableClientState(GL_NORMAL_ARRAY);
  528. glDisableClientState(GL_VERTEX_ARRAY);
  529. }
  530. //-----------------------------------------------------------------------------
  531. void GLRenderer::draw_point_buffer(const VertexBuffer* buffer)
  532. {
  533. if (buffer == NULL)
  534. return;
  535. glEnableClientState(GL_VERTEX_ARRAY);
  536. glEnableClientState(GL_NORMAL_ARRAY);
  537. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  538. glEnableClientState(GL_COLOR_ARRAY);
  539. buffer->Bind();
  540. glDrawArrays(GL_POINTS, 0, buffer->GetVertexCount());
  541. glDisableClientState(GL_COLOR_ARRAY);
  542. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  543. glDisableClientState(GL_NORMAL_ARRAY);
  544. glDisableClientState(GL_VERTEX_ARRAY);
  545. }
  546. //-----------------------------------------------------------------------------
  547. bool GLRenderer::activate_texture_unit(uint32_t unit)
  548. {
  549. if (unit >= (uint32_t) m_max_texture_units)
  550. {
  551. return false;
  552. }
  553. glActiveTexture(GL_TEXTURE0 + unit);
  554. m_active_texture_unit = unit;
  555. return true;
  556. }
  557. //-----------------------------------------------------------------------------
  558. void GLRenderer::set_light(uint32_t light, bool active)
  559. {
  560. if (light >= (uint32_t) m_max_lights)
  561. {
  562. return;
  563. }
  564. if (active)
  565. {
  566. glEnable(GL_LIGHT0 + light);
  567. }
  568. else
  569. {
  570. glDisable(GL_LIGHT0 + light);
  571. }
  572. }
  573. //-----------------------------------------------------------------------------
  574. void GLRenderer::set_light_params(uint32_t light, LightType type, const Vec3& position)
  575. {
  576. static float pos[4] =
  577. {
  578. position.x,
  579. position.y,
  580. position.z,
  581. 1.0f
  582. };
  583. if (type == LT_DIRECTION)
  584. {
  585. pos[3] = 0.0f;
  586. }
  587. glLightfv(GL_LIGHT0 + light, GL_POSITION, pos);
  588. }
  589. //-----------------------------------------------------------------------------
  590. void GLRenderer::set_light_color(uint32_t light, const Color4& ambient, const Color4& diffuse, const Color4& specular)
  591. {
  592. glLightfv(GL_LIGHT0 + light, GL_AMBIENT, ambient.to_float_ptr());
  593. glLightfv(GL_LIGHT0 + light, GL_DIFFUSE, diffuse.to_float_ptr());
  594. glLightfv(GL_LIGHT0 + light, GL_SPECULAR, specular.to_float_ptr());
  595. }
  596. //-----------------------------------------------------------------------------
  597. void GLRenderer::set_light_attenuation(uint32_t light, float constant, float linear, float quadratic)
  598. {
  599. glLightf(GL_LIGHT0 + light, GL_CONSTANT_ATTENUATION, constant);
  600. glLightf(GL_LIGHT0 + light, GL_LINEAR_ATTENUATION, linear);
  601. glLightf(GL_LIGHT0 + light, GL_QUADRATIC_ATTENUATION, quadratic);
  602. }
  603. //-----------------------------------------------------------------------------
  604. void GLRenderer::draw_lines(const float* vertices, const float* colors, uint32_t count)
  605. {
  606. glBindBuffer(GL_ARRAY_BUFFER, 0);
  607. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  608. glEnableClientState(GL_VERTEX_ARRAY);
  609. glEnableClientState(GL_COLOR_ARRAY);
  610. glVertexPointer(3, GL_FLOAT, 0, vertices);
  611. glColorPointer(4, GL_FLOAT, 0, colors);
  612. glDrawArrays(GL_LINES, 0, count);
  613. glDisableClientState(GL_COLOR_ARRAY);
  614. glDisableClientState(GL_VERTEX_ARRAY);
  615. }
  616. //-----------------------------------------------------------------------------
  617. void GLRenderer::draw_triangles(const float* vertices, const float* normals, const float* uvs, const uint16_t* indices, uint32_t count)
  618. {
  619. glBindBuffer(GL_ARRAY_BUFFER, 0);
  620. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  621. glEnableClientState(GL_VERTEX_ARRAY);
  622. glEnableClientState(GL_NORMAL_ARRAY);
  623. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  624. glVertexPointer(3, GL_FLOAT, 0, vertices);
  625. glNormalPointer(GL_FLOAT, 0, normals);
  626. glTexCoordPointer(2, GL_FLOAT, 0, uvs);
  627. glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices);
  628. glDisableClientState(GL_VERTEX_ARRAY);
  629. glDisableClientState(GL_NORMAL_ARRAY);
  630. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  631. }
  632. //-----------------------------------------------------------------------------
  633. TextureId GLRenderer::load_texture(TextureResource* texture)
  634. {
  635. // Search for an already existent texture
  636. for (uint32_t i = 0; i < MAX_TEXTURES; i++)
  637. {
  638. if (m_textures[i].texture_resource == texture)
  639. {
  640. return m_textures[i].id;
  641. }
  642. }
  643. // If texture not found, create a new one
  644. GLuint gl_texture_object;
  645. glGenTextures(1, &gl_texture_object);
  646. glBindTexture(GL_TEXTURE_2D, gl_texture_object);
  647. GLint gl_texture_format = GL::GetPixelFormat(texture->format());
  648. //FIXME FIXME FIXME
  649. glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
  650. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width(), texture->height(), 0,
  651. gl_texture_format, GL_UNSIGNED_BYTE, texture->data());
  652. TextureId id;
  653. id.index = m_texture_count;
  654. id.id = 0;
  655. m_textures[id.index].texture_object = gl_texture_object;
  656. m_textures[id.index].texture_resource = texture;
  657. m_textures[id.index].id = id;
  658. m_texture_count++;
  659. return id;
  660. }
  661. //-----------------------------------------------------------------------------
  662. void GLRenderer::unload_texture(TextureResource* texture)
  663. {
  664. // FIXME
  665. (void)texture;
  666. }
  667. //-----------------------------------------------------------------------------
  668. TextureId GLRenderer::reload_texture(TextureResource* old_texture, TextureResource* new_texture)
  669. {
  670. // FIXME
  671. (void)old_texture;
  672. (void)new_texture;
  673. return TextureId();
  674. }
  675. //-----------------------------------------------------------------------------
  676. void GLRenderer::check_gl_errors()
  677. {
  678. GLenum error;
  679. while ((error = glGetError()))
  680. {
  681. switch (error)
  682. {
  683. case GL_INVALID_ENUM:
  684. Log::e("GLRenderer: GL_INVALID_ENUM");
  685. break;
  686. case GL_INVALID_VALUE:
  687. Log::e("GLRenderer: GL_INVALID_VALUE");
  688. break;
  689. case GL_INVALID_OPERATION:
  690. Log::e("GLRenderer: GL_INVALID_OPERATION");
  691. break;
  692. case GL_STACK_OVERFLOW:
  693. Log::e("GLRenderer: GL_STACK_OVERFLOW");
  694. break;
  695. case GL_STACK_UNDERFLOW:
  696. Log::e("GLRenderer: GL_STACK_UNDERFLOW");
  697. break;
  698. case GL_OUT_OF_MEMORY:
  699. Log::e("GLRenderer: GL_OUT_OF_MEMORY");
  700. break;
  701. case GL_TABLE_TOO_LARGE:
  702. Log::e("GLRenderer: GL_OUT_OF_MEMORY");
  703. break;
  704. }
  705. }
  706. }
  707. } // namespace crown