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.
 
 
 

272 rivejä
6.9 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. using namespace std;
  21. namespace lol
  22. {
  23. #if defined ANDROID_NDK
  24. vec2i saved_viewport;
  25. #endif
  26. Shader *stdshader;
  27. mat4 proj_matrix, view_matrix, model_matrix;
  28. static char const *vertexshader =
  29. #if defined HAVE_GL_2X
  30. "#version 130\n"
  31. #endif
  32. "\n"
  33. #if defined HAVE_GLES_2X
  34. "attribute vec3 in_Position;\n"
  35. "attribute vec2 in_TexCoord;\n"
  36. "varying vec2 pass_TexCoord;\n"
  37. #else
  38. "in vec3 in_Position;\n"
  39. "in vec2 in_TexCoord;\n"
  40. #endif
  41. //"in vec3 in_Color;\n"
  42. //"out vec3 pass_Color;\n"
  43. "uniform mat4 proj_matrix;\n"
  44. "uniform mat4 view_matrix;\n"
  45. "uniform mat4 model_matrix;\n"
  46. "\n"
  47. "void main()\n"
  48. "{\n"
  49. " gl_Position = proj_matrix * view_matrix * model_matrix"
  50. " * vec4(in_Position, 1.0);\n"
  51. //" pass_Color = in_Color;\n"
  52. #if defined HAVE_GLES_2X
  53. " pass_TexCoord = in_TexCoord;\n"
  54. #else
  55. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  56. #endif
  57. "}\n";
  58. static char const *fragmentshader =
  59. #if !defined HAVE_GLES_2X
  60. "#version 130\n"
  61. #endif
  62. "\n"
  63. "uniform sampler2D in_Texture;\n"
  64. //"in vec3 pass_Color;\n"
  65. //"out vec4 out_Color;\n"
  66. #if defined HAVE_GLES_2X
  67. "varying vec2 pass_TexCoord;\n"
  68. #endif
  69. "\n"
  70. "void main()\n"
  71. "{\n"
  72. #if defined HAVE_GLES_2X
  73. " vec4 col = texture2D(in_Texture, pass_TexCoord);\n"
  74. //" vec4 col = vec4(0.5, 1.0, 0.0, 0.5);\n"
  75. //" vec4 col = vec4(pass_TexCoord * 4.0, 0.0, 0.25);\n"
  76. #else
  77. " vec4 col = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
  78. #endif
  79. #if 0
  80. " float mul = 2.0;\n"
  81. #if 0
  82. " vec2 d1 = mod(vec2(gl_FragCoord), vec2(2.0, 2.0));\n"
  83. " float t1 = mod(3.0 * d1.x + 2.0 * d1.y, 4.0);\n"
  84. " float dx2 = mod(floor(gl_FragCoord.x * 0.5), 2.0);\n"
  85. " float dy2 = mod(floor(gl_FragCoord.y * 0.5), 2.0);\n"
  86. " float t2 = mod(3.0 * dx2 + 2.0 * dy2, 4.0);\n"
  87. " float dx3 = mod(floor(gl_FragCoord.x * 0.25), 2.0);\n"
  88. " float dy3 = mod(floor(gl_FragCoord.y * 0.25), 2.0);\n"
  89. " float t3 = mod(3.0 * dx3 + 2.0 * dy3, 4.0);\n"
  90. " float t1 = (1.0 + 16.0 * t1 + 4.0 * t2 + t3) / 65.0;\n"
  91. " float t2 = t1;\n"
  92. " float t3 = t1;\n"
  93. #else
  94. " float rand = sin(gl_FragCoord.x * 1.23456) * 123.456\n"
  95. " + cos(gl_FragCoord.y * 2.34567) * 789.012;\n"
  96. " float t1 = mod(sin(rand) * 17.13043, 1.0);\n"
  97. " float t2 = mod(sin(rand) * 27.13043, 1.0);\n"
  98. " float t3 = mod(sin(rand) * 37.13043, 1.0);\n"
  99. #endif
  100. " float fracx = fract(col.x * mul);\n"
  101. " float fracy = fract(col.y * mul);\n"
  102. " float fracz = fract(col.z * mul);\n"
  103. " fracx = fracx > t1 ? 1.0 : 0.0;\n"
  104. " fracy = fracy > t2 ? 1.0 : 0.0;\n"
  105. " fracz = fracz > t3 ? 1.0 : 0.0;\n"
  106. " col.x = (floor(col.x * mul) + fracx) / mul;\n"
  107. " col.y = (floor(col.y * mul) + fracy) / mul;\n"
  108. " col.z = (floor(col.z * mul) + fracz) / mul;\n"
  109. #endif
  110. " gl_FragColor = col;\n"
  111. "}\n";
  112. /*
  113. * Public Video class
  114. */
  115. void Video::Setup(vec2i size)
  116. {
  117. /* Initialise OpenGL */
  118. glViewport(0, 0, size.x, size.y);
  119. #if defined ANDROID_NDK
  120. saved_viewport = vec2i(size.x, size.y);
  121. #endif
  122. glClearColor(0.1f, 0.2f, 0.3f, 0.0f);
  123. glClearDepthf(1.0);
  124. #if defined HAVE_GL_2X
  125. glShadeModel(GL_SMOOTH);
  126. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  127. #endif
  128. stdshader = Shader::Create(vertexshader, fragmentshader);
  129. }
  130. void Video::SetFov(float theta)
  131. {
  132. #undef near /* Fuck Microsoft */
  133. #undef far /* Fuck Microsoft again */
  134. mat4 proj;
  135. vec2 size = GetSize();
  136. float near = -size.x - size.y;
  137. float far = size.x + size.y;
  138. #if defined ANDROID_NDK
  139. size = vec(640.0f, 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, size.x, 0, size.y, 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 * size.y / size.y;
  154. float dist = size.x / (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 * size.x, -0.5f * size.y, -dist);
  165. }
  166. view_matrix = mat4(1.0f);
  167. stdshader->Bind(); /* Required on GLES 2.x? */
  168. #if !defined __CELLOS_LV2__ // Use cgGetNamedParameter etc.
  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. #endif
  175. }
  176. void Video::SetDepth(bool set)
  177. {
  178. if (set)
  179. glEnable(GL_DEPTH_TEST);
  180. else
  181. glDisable(GL_DEPTH_TEST);
  182. }
  183. void Video::Clear()
  184. {
  185. vec2i size = GetSize();
  186. glViewport(0, 0, size.x, size.y);
  187. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  188. SetFov(0.0f);
  189. }
  190. void Video::Destroy()
  191. {
  192. Shader::Destroy(stdshader);
  193. }
  194. void Video::Capture(uint32_t *buffer)
  195. {
  196. GLint v[4];
  197. #if defined __CELLOS_LV2__
  198. // FIXME: use psglCreateDeviceAuto && psglGetDeviceDimensions
  199. v[2] = 1920;
  200. v[3] = 1080;
  201. #else
  202. glGetIntegerv(GL_VIEWPORT, v);
  203. #endif
  204. int width = v[2], height = v[3];
  205. #if defined HAVE_GL_2X
  206. glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  207. #endif
  208. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  209. #if defined GL_BGRA
  210. glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
  211. #else
  212. glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  213. #endif
  214. for (int j = 0; j < height / 2; j++)
  215. for (int i = 0; i < width; i++)
  216. {
  217. uint32_t tmp = buffer[j * width + i];
  218. buffer[j * width + i] = buffer[(height - j - 1) * width + i];
  219. buffer[(height - j - 1) * width + i] = tmp;
  220. }
  221. }
  222. vec2i Video::GetSize()
  223. {
  224. #if defined ANDROID_NDK
  225. return saved_viewport;
  226. #elif defined __CELLOS_LV2__
  227. // FIXME: use psglCreateDeviceAuto && psglGetDeviceDimensions
  228. return vec2i(1920, 1080);
  229. #else
  230. GLint v[4];
  231. glGetIntegerv(GL_VIEWPORT, v);
  232. return vec2i(v[2], v[3]);
  233. #endif
  234. }
  235. } /* namespace lol */