Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

283 wiersze
7.0 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cmath>
  14. #ifdef WIN32
  15. # define WIN32_LEAN_AND_MEAN
  16. # include <windows.h>
  17. #endif
  18. #include "core.h"
  19. #include "lolgl.h"
  20. namespace lol
  21. {
  22. #if defined ANDROID_NDK
  23. vec2i saved_viewport;
  24. #endif
  25. #if defined HAVE_GL_2X || defined HAVE_GLES_2X
  26. Shader *stdshader;
  27. #endif
  28. mat4 proj_matrix, view_matrix, model_matrix;
  29. #if defined HAVE_GL_2X || defined HAVE_GLES_2X
  30. static char const *vertexshader =
  31. #if !defined HAVE_GLES_2X
  32. "#version 130\n"
  33. #endif
  34. "\n"
  35. #if defined HAVE_GLES_2X
  36. "attribute vec3 in_Position;\n"
  37. "attribute vec2 in_TexCoord;\n"
  38. "varying vec2 pass_TexCoord;\n"
  39. #else
  40. "in vec3 in_Position;\n"
  41. "in vec2 in_TexCoord;\n"
  42. #endif
  43. //"in vec3 in_Color;\n"
  44. //"out vec3 pass_Color;\n"
  45. "uniform mat4 proj_matrix;\n"
  46. "uniform mat4 view_matrix;\n"
  47. "uniform mat4 model_matrix;\n"
  48. "\n"
  49. "void main()\n"
  50. "{\n"
  51. " gl_Position = proj_matrix * view_matrix * model_matrix"
  52. " * vec4(in_Position, 1.0f);\n"
  53. //" pass_Color = in_Color;\n"
  54. #if defined HAVE_GLES_2X
  55. " pass_TexCoord = in_TexCoord;\n"
  56. #else
  57. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  58. #endif
  59. "}\n";
  60. static char const *fragmentshader =
  61. #if !defined HAVE_GLES_2X
  62. "#version 130\n"
  63. #endif
  64. "\n"
  65. "uniform sampler2D in_Texture;\n"
  66. //"in vec3 pass_Color;\n"
  67. //"out vec4 out_Color;\n"
  68. #if defined HAVE_GLES_2X
  69. "varying vec2 pass_TexCoord;\n"
  70. #endif
  71. "\n"
  72. "void main()\n"
  73. "{\n"
  74. #if defined HAVE_GLES_2X
  75. " gl_FragColor = texture2D(in_Texture, pass_TexCoord);\n"
  76. //" gl_FragColor = vec4(0.5, 1.0, 0.0, 0.5);\n"
  77. //" gl_FragColor = vec4(pass_TexCoord * 4.0, 0.0, 0.25);\n"
  78. #else
  79. " vec4 col = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
  80. #if 0
  81. " float mul = 2.0;\n"
  82. " float dx1 = mod(gl_FragCoord.x, 2.0);\n"
  83. " float dy1 = mod(gl_FragCoord.y, 2.0);\n"
  84. " float t1 = mod(3.0 * dx1 + 2.0 * dy1, 4.0);\n"
  85. " float dx2 = mod(floor(gl_FragCoord.x * 0.5), 2.0);\n"
  86. " float dy2 = mod(floor(gl_FragCoord.y * 0.5), 2.0);\n"
  87. " float t2 = mod(3.0 * dx2 + 2.0 * dy2, 4.0);\n"
  88. " float dx3 = mod(floor(gl_FragCoord.x * 0.25), 2.0);\n"
  89. " float dy3 = mod(floor(gl_FragCoord.y * 0.25), 2.0);\n"
  90. " float t3 = mod(3.0 * dx3 + 2.0 * dy3, 4.0);\n"
  91. " float t = (1.0 + 16.0 * t1 + 4.0 * t2 + t3) / 65.0;\n"
  92. " float fracx = fract(col.x * mul);\n"
  93. " float fracy = fract(col.y * mul);\n"
  94. " float fracz = fract(col.z * mul);\n"
  95. " fracx = fracx > t ? 1.0 : 0.0;\n"
  96. " fracy = fracy > t ? 1.0 : 0.0;\n"
  97. " fracz = fracz > t ? 1.0 : 0.0;\n"
  98. " col.x = (floor(col.x * mul) + fracx) / mul;\n"
  99. " col.y = (floor(col.y * mul) + fracy) / mul;\n"
  100. " col.z = (floor(col.z * mul) + fracz) / mul;\n"
  101. #endif
  102. " gl_FragColor = col;\n"
  103. #endif
  104. "}\n";
  105. #endif
  106. /*
  107. * Public Video class
  108. */
  109. void Video::Setup(int width, int height)
  110. {
  111. /* Initialise OpenGL */
  112. glViewport(0, 0, width, height);
  113. #if defined ANDROID_NDK
  114. saved_viewport = vec2i(width, height);
  115. #endif
  116. glClearColor(0.1f, 0.2f, 0.3f, 0.0f);
  117. glClearDepthf(1.0);
  118. #if defined HAVE_GL_2X || defined HAVE_GLES_1X
  119. glShadeModel(GL_SMOOTH);
  120. #endif
  121. #if defined HAVE_GL_2X || defined HAVE_GLES_1X
  122. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  123. #endif
  124. #if defined HAVE_GL_2X || defined HAVE_GLES_2X
  125. stdshader = Shader::Create(vertexshader, fragmentshader);
  126. #endif
  127. }
  128. void Video::SetFov(float theta)
  129. {
  130. #undef near /* Fuck Microsoft */
  131. #undef far /* Fuck Microsoft again */
  132. mat4 proj;
  133. float width = GetWidth();
  134. float height = GetHeight();
  135. float near = -width - height;
  136. float far = width + height;
  137. #if defined ANDROID_NDK
  138. width = 640.0f;
  139. height = 480.0f;
  140. #endif
  141. /* Set the projection matrix */
  142. if (theta < 1e-4f)
  143. {
  144. /* The easy way: purely orthogonal projection. */
  145. proj_matrix = mat4::ortho(0, width, 0, height, near, far);
  146. }
  147. else
  148. {
  149. /* Compute a view that approximates the glOrtho view when theta
  150. * approaches zero. This view ensures that the z=0 plane fills
  151. * the screen. */
  152. float t1 = tanf(theta / 2);
  153. float t2 = t1 * height / width;
  154. float dist = (float)width / (2.0f * t1);
  155. near += dist;
  156. far += dist;
  157. if (near <= 0.0f)
  158. {
  159. far -= (near - 1.0f);
  160. near = 1.0f;
  161. }
  162. proj_matrix = mat4::frustum(-near * t1, near * t1,
  163. -near * t2, near * t2, near, far)
  164. * mat4::translate(-0.5f * width, -0.5f * height, -dist);
  165. }
  166. view_matrix = mat4(1.0f);
  167. #if defined HAVE_GL_2X || defined HAVE_GLES_2X
  168. stdshader->Bind(); /* Required on GLES 2.x? */
  169. GLuint uni;
  170. uni = stdshader->GetUniformLocation("proj_matrix");
  171. glUniformMatrix4fv(uni, 1, GL_FALSE, &proj_matrix[0][0]);
  172. uni = stdshader->GetUniformLocation("view_matrix");
  173. glUniformMatrix4fv(uni, 1, GL_FALSE, &view_matrix[0][0]);
  174. #else
  175. glMatrixMode(GL_PROJECTION);
  176. glLoadIdentity();
  177. glMultMatrixf(&proj_matrix[0][0]);
  178. /* Reset the model view matrix, just in case */
  179. glMatrixMode(GL_MODELVIEW);
  180. glLoadIdentity();
  181. glMultMatrixf(&view_matrix[0][0]);
  182. #endif
  183. }
  184. void Video::SetDepth(bool set)
  185. {
  186. if (set)
  187. glEnable(GL_DEPTH_TEST);
  188. else
  189. glDisable(GL_DEPTH_TEST);
  190. }
  191. void Video::Clear()
  192. {
  193. glViewport(0, 0, GetWidth(), GetHeight());
  194. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  195. SetFov(0.0f);
  196. }
  197. void Video::Destroy()
  198. {
  199. #if defined HAVE_GL_2X || defined HAVE_GLES_2X
  200. Shader::Destroy(stdshader);
  201. #endif
  202. }
  203. void Video::Capture(uint32_t *buffer)
  204. {
  205. GLint v[4];
  206. glGetIntegerv(GL_VIEWPORT, v);
  207. int width = v[2], height = v[3];
  208. #if defined HAVE_GL_1X || defined HAVE_GL_2X
  209. glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  210. #endif
  211. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  212. #if defined GL_BGRA
  213. glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
  214. #else
  215. glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  216. #endif
  217. for (int j = 0; j < height / 2; j++)
  218. for (int i = 0; i < width; i++)
  219. {
  220. uint32_t tmp = buffer[j * width + i];
  221. buffer[j * width + i] = buffer[(height - j - 1) * width + i];
  222. buffer[(height - j - 1) * width + i] = tmp;
  223. }
  224. }
  225. int Video::GetWidth()
  226. {
  227. #if defined ANDROID_NDK
  228. return saved_viewport.x;
  229. #else
  230. GLint v[4];
  231. glGetIntegerv(GL_VIEWPORT, v);
  232. return v[2];
  233. #endif
  234. }
  235. int Video::GetHeight()
  236. {
  237. #if defined ANDROID_NDK
  238. return saved_viewport.y;
  239. #else
  240. GLint v[4];
  241. glGetIntegerv(GL_VIEWPORT, v);
  242. return v[3];
  243. #endif
  244. }
  245. } /* namespace lol */