433 rivejä
13 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. #include <cstdio>
  15. #include "core.h"
  16. #include "lolgl.h"
  17. #include "loldebug.h"
  18. using namespace std;
  19. namespace lol
  20. {
  21. /*
  22. * DebugQuad implementation class
  23. */
  24. #define NUM_SHADERS 3
  25. class DebugQuadData
  26. {
  27. friend class DebugQuad;
  28. private:
  29. vec2 orig, step, aa, bb;
  30. int initialised;
  31. float time;
  32. GLuint buflist[3];
  33. Shader *shader[NUM_SHADERS];
  34. GLuint texlist[1];
  35. uint8_t image[1][32 * 32 * 4];
  36. };
  37. /*
  38. * Public DebugQuad class
  39. */
  40. DebugQuad::DebugQuad()
  41. : data(new DebugQuadData())
  42. {
  43. data->initialised = 0;
  44. data->time = RandF(10000.0f);
  45. drawgroup = DRAWGROUP_HUD;
  46. }
  47. void DebugQuad::TickGame(float deltams)
  48. {
  49. Entity::TickGame(deltams);
  50. data->time += deltams;
  51. }
  52. void DebugQuad::TickDraw(float deltams)
  53. {
  54. Entity::TickDraw(deltams);
  55. if (!data->initialised && !IsDestroying())
  56. {
  57. glGenBuffers(3, data->buflist);
  58. static char const *vertexshader =
  59. "//#version 130\n"
  60. "varying vec2 in_Position;\n"
  61. "varying vec4 in_Color;\n"
  62. "varying vec2 in_TexCoord;\n"
  63. "varying vec4 pass_Color;\n"
  64. "void main()\n"
  65. "{\n"
  66. "gl_TexCoord[0] = gl_MultiTexCoord0;\n"
  67. " gl_Position = vec4(in_Position, 0.0f, 1.0f);\n"
  68. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  69. " pass_Color = in_Color;\n"
  70. "}\n";
  71. static char const *fragmentshader =
  72. "//#version 130\n"
  73. "varying vec4 pass_Color;\n"
  74. "uniform sampler2D in_Texture;\n"
  75. "void main()\n"
  76. "{\n"
  77. " vec4 col = pass_Color;\n"
  78. " vec4 tex = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
  79. " gl_FragColor = col * tex;\n"
  80. " gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);\n"
  81. "}\n";
  82. data->shader[0] = Shader::Create(vertexshader, fragmentshader);
  83. glGenTextures(1, data->texlist);
  84. glEnable(GL_TEXTURE_2D);
  85. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  86. for (int j = 0; j < 32; j++)
  87. for (int i = 0; i < 32; i++)
  88. {
  89. uint8_t wb = (((i / 2) ^ (j / 2)) & 1) * 0xff;
  90. data->image[0][(j * 32 + i) * 4 + 0] = wb;
  91. data->image[0][(j * 32 + i) * 4 + 1] = wb;
  92. data->image[0][(j * 32 + i) * 4 + 2] = wb;
  93. data->image[0][(j * 32 + i) * 4 + 3] = wb;
  94. }
  95. /* Use GL_RGBA instead of 4 for the internal format (Android) */
  96. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0,
  97. GL_RGBA, GL_UNSIGNED_BYTE, data->image[0]);
  98. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  99. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  100. /* Quad #4: create texture in fragment shader */
  101. data->shader[0] = Shader::Create(
  102. "#version 120\n"
  103. "void main()"
  104. "{"
  105. " gl_Position = gl_Vertex;"
  106. "}",
  107. "#version 120\n"
  108. "void main()"
  109. "{"
  110. " float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
  111. " float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
  112. " float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
  113. " gl_FragColor = vec4(dx, dy, dz, 1.0);"
  114. "}");
  115. /* Quad #5: pass color from vertex shader to fragment shader */
  116. data->shader[1] = Shader::Create(
  117. "#version 120\n"
  118. "varying vec4 color;"
  119. "void main()"
  120. "{"
  121. " float r = gl_MultiTexCoord0.x;"
  122. " float g = gl_MultiTexCoord0.y;"
  123. " color = vec4(1.0 - r, 1.0 - g, r, 1.0);"
  124. " gl_Position = gl_Vertex;"
  125. "}",
  126. "#version 120\n"
  127. "varying vec4 color;"
  128. "void main()"
  129. "{"
  130. " gl_FragColor = color;"
  131. "}");
  132. /* Quad #6: apply texture in fragment shader */
  133. data->shader[2] = Shader::Create(
  134. "void main()"
  135. "{"
  136. " gl_TexCoord[0] = gl_MultiTexCoord0;"
  137. " gl_Position = gl_Vertex;"
  138. "}",
  139. "uniform sampler2D tex;"
  140. "void main()"
  141. "{"
  142. " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  143. "}");
  144. data->initialised = 1;
  145. }
  146. else if (data->initialised && IsDestroying())
  147. {
  148. glDeleteBuffers(3, data->buflist);
  149. Shader::Destroy(data->shader[0]);
  150. Shader::Destroy(data->shader[1]);
  151. Shader::Destroy(data->shader[2]);
  152. glDeleteTextures(1, data->texlist);
  153. data->initialised = 0;
  154. }
  155. float const st = sinf(0.0005f * data->time);
  156. float const ct = cosf(0.0005f * data->time);
  157. GLfloat const verts[6][2] =
  158. {
  159. { -0.7f * (st + ct), 0.7f * (st - ct) },
  160. { 0.7f * (st - ct), 0.7f * (st + ct) },
  161. { -0.7f * (st - ct), -0.7f * (st + ct) },
  162. { -0.7f * (st - ct), -0.7f * (st + ct) },
  163. { 0.7f * (st - ct), 0.7f * (st + ct) },
  164. { 0.7f * (st + ct), -0.7f * (st - ct) },
  165. };
  166. /* Using only 3 components breaks on Android for some reason. */
  167. static GLfloat const cols[6][4] =
  168. {
  169. { 1.0f, 0.2f, 0.2f, 1.0f },
  170. { 0.2f, 0.2f, 1.0f, 1.0f },
  171. { 1.0f, 1.0f, 0.2f, 1.0f },
  172. { 1.0f, 1.0f, 0.2f, 1.0f },
  173. { 0.2f, 0.2f, 1.0f, 1.0f },
  174. { 0.2f, 1.0f, 0.2f, 1.0f },
  175. };
  176. static GLfloat const tcs[6][2] =
  177. {
  178. { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 0.0f, 0.0f },
  179. { 0.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f },
  180. };
  181. #if defined __CELLOS_LV2__
  182. glEnableClientState(GL_VERTEX_ARRAY);
  183. glEnableClientState(GL_COLOR_ARRAY);
  184. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  185. glActiveTexture(GL_TEXTURE0);
  186. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  187. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
  188. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), verts, GL_STATIC_DRAW);
  189. glVertexPointer(2, GL_FLOAT, GL_FALSE, 0);
  190. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
  191. glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), cols, GL_STATIC_DRAW);
  192. glColorPointer(4, GL_FLOAT, GL_FALSE, 0);
  193. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]);
  194. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tcs, GL_STATIC_DRAW);
  195. glTexCoordPointer(2, GL_FLOAT, GL_FALSE, 0);
  196. glDrawArrays(GL_TRIANGLES, 0, 6);
  197. glDisableClientState(GL_VERTEX_ARRAY);
  198. glDisableClientState(GL_COLOR_ARRAY);
  199. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  200. #else
  201. data->shader[0]->Bind();
  202. GLuint attr_pos, attr_col, attr_tex;
  203. attr_pos = data->shader[0]->GetAttribLocation("in_Position");
  204. attr_col = data->shader[0]->GetAttribLocation("in_Color");
  205. attr_tex = data->shader[0]->GetAttribLocation("in_TexCoord");
  206. glEnableVertexAttribArray(attr_pos);
  207. glEnableVertexAttribArray(attr_col);
  208. glEnableVertexAttribArray(attr_tex);
  209. /* Bind texture */
  210. glActiveTexture(GL_TEXTURE0);
  211. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  212. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
  213. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), verts, GL_STATIC_DRAW);
  214. glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, 0);
  215. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
  216. glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), cols, GL_STATIC_DRAW);
  217. glVertexAttribPointer(attr_col, 4, GL_FLOAT, GL_FALSE, 0, 0);
  218. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]);
  219. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tcs, GL_STATIC_DRAW);
  220. glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, 0);
  221. glDrawArrays(GL_TRIANGLES, 0, 6);
  222. glDisableVertexAttribArray(attr_pos);
  223. glDisableVertexAttribArray(attr_col);
  224. glDisableVertexAttribArray(attr_tex);
  225. #endif
  226. /* Reset GL states */
  227. glMatrixMode(GL_PROJECTION);
  228. glLoadIdentity();
  229. glMatrixMode(GL_MODELVIEW);
  230. glLoadIdentity();
  231. glDisable(GL_TEXTURE_2D);
  232. glUseProgram(0);
  233. /* Prepare our quad coordinates */
  234. vec2i const layout(4, 3);
  235. data->step = vec2(2.0f, -2.0f) / (2 * layout + vec2i(1));
  236. data->orig = vec2(-1.0f, 1.0f) + data->step;
  237. data->aa = data->orig;
  238. data->bb = data->orig + data->step;
  239. /* Generate a few random numbers */
  240. float f1 = 0.5f + 0.5f * sinf(0.00034f * data->time);
  241. float f2 = 0.5f + 0.5f * sinf(0.00053f * data->time + 1.0f);
  242. float f3 = 0.5f + 0.5f * sinf(0.00072f * data->time + 4.0f);
  243. float f4 = 0.5f + 0.5f * sinf(0.00091f * data->time + 8.0f);
  244. /* Quad #1: simple glBegin program */
  245. glColor3f(0.8f, 0.5f, 0.2f);
  246. glBegin(GL_TRIANGLES);
  247. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  248. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  249. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  250. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  251. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  252. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  253. glEnd();
  254. Advance();
  255. /* Quad #2: glBegin program with varying color */
  256. glBegin(GL_TRIANGLES);
  257. glColor3f(f1, f2, f3);
  258. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  259. glColor3f(f4, f2, f1);
  260. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  261. glColor3f(f3, f1, f4);
  262. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  263. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  264. glColor3f(f4, f3, f2);
  265. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  266. glColor3f(f1, f2, f3);
  267. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  268. glEnd();
  269. Advance();
  270. /* Quad #3: textured quad */
  271. glEnable(GL_TEXTURE_2D);
  272. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  273. glColor3f(1.0f, 1.0f, 1.0f);
  274. glBegin(GL_TRIANGLES);
  275. glTexCoord2f(f1, f3);
  276. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  277. glTexCoord2f(f3, f2);
  278. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  279. glTexCoord2f(f2, f4);
  280. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  281. glTexCoord2f(f2, f4);
  282. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  283. glTexCoord2f(f4, f1);
  284. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  285. glTexCoord2f(f1, f3);
  286. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  287. glEnd();
  288. Advance();
  289. /* Quad #4: set color in fragment shader */
  290. data->shader[0]->Bind();
  291. glColor3f(0.0f, 1.0f, 1.0f);
  292. glBegin(GL_TRIANGLES);
  293. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  294. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  295. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  296. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  297. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  298. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  299. glEnd();
  300. glUseProgram(0);
  301. Advance();
  302. /* Quad #5: pass color from vertex shader to fragment shader */
  303. data->shader[1]->Bind();
  304. glColor3f(0.0f, 1.0f, 1.0f);
  305. glBegin(GL_TRIANGLES);
  306. glTexCoord2f(f1, f3);
  307. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  308. glTexCoord2f(f3, f2);
  309. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  310. glTexCoord2f(f2, f4);
  311. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  312. glTexCoord2f(f2, f4);
  313. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  314. glTexCoord2f(f4, f1);
  315. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  316. glTexCoord2f(f1, f3);
  317. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  318. glEnd();
  319. glUseProgram(0);
  320. Advance();
  321. /* Quad #6: apply texture in fragment shader */
  322. data->shader[2]->Bind();
  323. glColor3f(0.0f, 1.0f, 1.0f);
  324. glEnable(GL_TEXTURE_2D);
  325. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  326. glBegin(GL_TRIANGLES);
  327. glTexCoord2f(f1, f3);
  328. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  329. glTexCoord2f(f3, f2);
  330. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  331. glTexCoord2f(f2, f4);
  332. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  333. glTexCoord2f(f2, f4);
  334. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  335. glTexCoord2f(f4, f1);
  336. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  337. glTexCoord2f(f1, f3);
  338. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  339. glEnd();
  340. glUseProgram(0);
  341. Advance();
  342. }
  343. void DebugQuad::Advance()
  344. {
  345. data->aa.x += 2.0f * data->step.x;
  346. data->bb.x += 2.0f * data->step.x;
  347. if (data->bb.x > 1.0f)
  348. {
  349. data->aa.x = data->orig.x;
  350. data->bb.x = data->orig.x + data->step.x;
  351. data->aa.y += 2.0f * data->step.y;
  352. data->bb.y += 2.0f * data->step.y;
  353. }
  354. }
  355. DebugQuad::~DebugQuad()
  356. {
  357. delete data;
  358. }
  359. } /* namespace lol */