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.
 
 
 

525 line
16 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 4
  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. #if 0
  58. glGenBuffers(3, data->buflist);
  59. static char const *vertexshader =
  60. "//#version 130\n"
  61. "varying vec2 in_Position;\n"
  62. "varying vec4 in_Color;\n"
  63. "varying vec2 in_TexCoord;\n"
  64. "varying vec4 pass_Color;\n"
  65. "void main()\n"
  66. "{\n"
  67. "gl_TexCoord[0] = gl_MultiTexCoord0;\n"
  68. " gl_Position = vec4(in_Position, 0.0f, 1.0f);\n"
  69. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  70. " pass_Color = in_Color;\n"
  71. "}\n";
  72. static char const *fragmentshader =
  73. "//#version 130\n"
  74. "varying vec4 pass_Color;\n"
  75. "uniform sampler2D in_Texture;\n"
  76. "void main()\n"
  77. "{\n"
  78. " vec4 col = pass_Color;\n"
  79. " vec4 tex = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
  80. " gl_FragColor = col * tex;\n"
  81. " gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);\n"
  82. "}\n";
  83. data->shader[0] = Shader::Create(vertexshader, fragmentshader);
  84. glGenTextures(1, data->texlist);
  85. #endif
  86. /* Checkerboard texture */
  87. glEnable(GL_TEXTURE_2D);
  88. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  89. for (int j = 0; j < 32; j++)
  90. for (int i = 0; i < 32; i++)
  91. {
  92. uint8_t wb = (((i / 2) ^ (j / 2)) & 1) * 0xff;
  93. data->image[0][(j * 32 + i) * 4 + 0] = wb;
  94. data->image[0][(j * 32 + i) * 4 + 1] = wb;
  95. data->image[0][(j * 32 + i) * 4 + 2] = wb;
  96. data->image[0][(j * 32 + i) * 4 + 3] = 0xff;
  97. }
  98. /* Use GL_RGBA instead of 4 for the internal format (Android) */
  99. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0,
  100. GL_RGBA, GL_UNSIGNED_BYTE, data->image[0]);
  101. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  102. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  103. /* Quad #4: create texture in fragment shader */
  104. data->shader[0] = Shader::Create(
  105. "#version 130\n"
  106. "in vec2 in_Vertex;"
  107. "void main()"
  108. "{"
  109. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  110. "}",
  111. "#version 130\n"
  112. "void main()"
  113. "{"
  114. " float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
  115. " float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
  116. " float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
  117. " gl_FragColor = vec4(dx, dy, dz, 1.0);"
  118. "}");
  119. /* Quad #5: pass color from vertex shader to fragment shader */
  120. data->shader[1] = Shader::Create(
  121. "#version 130\n"
  122. "in vec2 in_Vertex;"
  123. "in vec2 in_MultiTexCoord0;"
  124. "varying vec4 pass_Color;"
  125. "void main()"
  126. "{"
  127. " float r = in_MultiTexCoord0.x;"
  128. " float g = in_MultiTexCoord0.y;"
  129. " pass_Color = vec4(1.0 - r, 1.0 - g, r, 1.0);"
  130. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  131. "}",
  132. "#version 130\n"
  133. "varying vec4 pass_Color;"
  134. "void main()"
  135. "{"
  136. " gl_FragColor = pass_Color;"
  137. "}");
  138. /* Quad #6: apply texture in fragment shader */
  139. data->shader[2] = Shader::Create(
  140. "#version 130\n"
  141. "in vec2 in_Vertex;"
  142. "in vec2 in_MultiTexCoord0;"
  143. "void main()"
  144. "{"
  145. " gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
  146. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  147. "}",
  148. "#version 130\n"
  149. "uniform sampler2D tex;"
  150. "void main()"
  151. "{"
  152. " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  153. "}");
  154. /* Quad #8: vertex buffer, apply texture in fragment shader */
  155. data->shader[3] = Shader::Create(
  156. "#version 130\n"
  157. "in vec2 in_Vertex;"
  158. "in vec2 in_MultiTexCoord0;"
  159. "in vec4 in_Color;"
  160. "varying vec4 pass_Color;"
  161. "void main()"
  162. "{"
  163. " gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
  164. " pass_Color = in_Color;"
  165. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  166. "}",
  167. "#version 130\n"
  168. "varying vec4 pass_Color;"
  169. "uniform sampler2D tex;"
  170. "void main()"
  171. "{"
  172. " vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  173. " gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
  174. "}");
  175. data->initialised = 1;
  176. }
  177. else if (data->initialised && IsDestroying())
  178. {
  179. #if 0
  180. glDeleteBuffers(3, data->buflist);
  181. #endif
  182. Shader::Destroy(data->shader[0]);
  183. Shader::Destroy(data->shader[1]);
  184. Shader::Destroy(data->shader[2]);
  185. Shader::Destroy(data->shader[3]);
  186. glDeleteTextures(1, data->texlist);
  187. data->initialised = 0;
  188. }
  189. #if 0
  190. float const st = sinf(0.0005f * data->time);
  191. float const ct = cosf(0.0005f * data->time);
  192. GLfloat const verts[6][2] =
  193. {
  194. { -0.7f * (st + ct), 0.7f * (st - ct) },
  195. { 0.7f * (st - ct), 0.7f * (st + ct) },
  196. { -0.7f * (st - ct), -0.7f * (st + ct) },
  197. { -0.7f * (st - ct), -0.7f * (st + ct) },
  198. { 0.7f * (st - ct), 0.7f * (st + ct) },
  199. { 0.7f * (st + ct), -0.7f * (st - ct) },
  200. };
  201. /* Using only 3 components breaks on Android for some reason. */
  202. static GLfloat const cols[6][4] =
  203. {
  204. { 1.0f, 0.2f, 0.2f, 1.0f },
  205. { 0.2f, 0.2f, 1.0f, 1.0f },
  206. { 1.0f, 1.0f, 0.2f, 1.0f },
  207. { 1.0f, 1.0f, 0.2f, 1.0f },
  208. { 0.2f, 0.2f, 1.0f, 1.0f },
  209. { 0.2f, 1.0f, 0.2f, 1.0f },
  210. };
  211. static GLfloat const tcs[6][2] =
  212. {
  213. { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 0.0f, 0.0f },
  214. { 0.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f },
  215. };
  216. #if defined __CELLOS_LV2__
  217. glEnableClientState(GL_VERTEX_ARRAY);
  218. glEnableClientState(GL_COLOR_ARRAY);
  219. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  220. glActiveTexture(GL_TEXTURE0);
  221. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  222. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
  223. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), verts, GL_STATIC_DRAW);
  224. glVertexPointer(2, GL_FLOAT, GL_FALSE, 0);
  225. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
  226. glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), cols, GL_STATIC_DRAW);
  227. glColorPointer(4, GL_FLOAT, GL_FALSE, 0);
  228. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]);
  229. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tcs, GL_STATIC_DRAW);
  230. glTexCoordPointer(2, GL_FLOAT, GL_FALSE, 0);
  231. glDrawArrays(GL_TRIANGLES, 0, 6);
  232. glDisableClientState(GL_VERTEX_ARRAY);
  233. glDisableClientState(GL_COLOR_ARRAY);
  234. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  235. #else
  236. data->shader[0]->Bind();
  237. GLuint attr_pos, attr_col, attr_tex;
  238. attr_pos = data->shader[0]->GetAttribLocation("in_Position");
  239. attr_col = data->shader[0]->GetAttribLocation("in_Color");
  240. attr_tex = data->shader[0]->GetAttribLocation("in_TexCoord");
  241. glEnableVertexAttribArray(attr_pos);
  242. glEnableVertexAttribArray(attr_col);
  243. glEnableVertexAttribArray(attr_tex);
  244. /* Bind texture */
  245. glActiveTexture(GL_TEXTURE0);
  246. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  247. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
  248. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), verts, GL_STATIC_DRAW);
  249. glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, 0);
  250. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
  251. glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), cols, GL_STATIC_DRAW);
  252. glVertexAttribPointer(attr_col, 4, GL_FLOAT, GL_FALSE, 0, 0);
  253. glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]);
  254. glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tcs, GL_STATIC_DRAW);
  255. glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, 0);
  256. glBindBuffer(GL_ARRAY_BUFFER, 0);
  257. glDrawArrays(GL_TRIANGLES, 0, 6);
  258. glDisableVertexAttribArray(attr_pos);
  259. glDisableVertexAttribArray(attr_col);
  260. glDisableVertexAttribArray(attr_tex);
  261. #endif
  262. #endif
  263. /* Reset GL states */
  264. glMatrixMode(GL_PROJECTION);
  265. glLoadIdentity();
  266. glMatrixMode(GL_MODELVIEW);
  267. glLoadIdentity();
  268. glDisable(GL_TEXTURE_2D);
  269. glBindBuffer(GL_ARRAY_BUFFER, 0);
  270. glUseProgram(0);
  271. /* Prepare our quad coordinates */
  272. vec2i const layout(3, 3);
  273. data->step = vec2(2.0f, -2.0f) / (3 * layout + vec2i(1));
  274. data->orig = vec2(-1.0f, 1.0f) + data->step;
  275. data->aa = data->orig;
  276. data->bb = data->orig + 2.0f * data->step;
  277. /* Generate a few random numbers */
  278. float f1 = 0.5f + 0.5f * sinf(0.00034f * data->time);
  279. float f2 = 0.5f + 0.5f * sinf(0.00053f * data->time + 1.0f);
  280. float f3 = 0.5f + 0.5f * sinf(0.00072f * data->time + 4.0f);
  281. float f4 = 0.5f + 0.5f * sinf(0.00091f * data->time + 8.0f);
  282. GLfloat const colors[] = { f1, f2, f3, f4, f2, f1, f3, f1, f4,
  283. f3, f1, f4, f4, f3, f2, f1, f2, f3 };
  284. GLfloat const texcoords[] = { f1, f3, f3, f2, f2, f4,
  285. f2, f4, f4, f1, f1, f3 };
  286. /* Quad #1: simple glBegin program */
  287. glColor3f(0.8f, 0.5f, 0.2f);
  288. glBegin(GL_TRIANGLES);
  289. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  290. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  291. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  292. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  293. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  294. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  295. glEnd();
  296. Advance();
  297. /* Quad #2: glBegin program with varying color */
  298. glBegin(GL_TRIANGLES);
  299. glColor3f(f1, f2, f3);
  300. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  301. glColor3f(f4, f2, f1);
  302. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  303. glColor3f(f3, f1, f4);
  304. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  305. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  306. glColor3f(f4, f3, f2);
  307. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  308. glColor3f(f1, f2, f3);
  309. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  310. glEnd();
  311. Advance();
  312. /* Quad #3: textured quad */
  313. glEnable(GL_TEXTURE_2D);
  314. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  315. glColor3f(1.0f, 1.0f, 1.0f);
  316. glBegin(GL_TRIANGLES);
  317. glTexCoord2f(f1, f3);
  318. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  319. glTexCoord2f(f3, f2);
  320. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  321. glTexCoord2f(f2, f4);
  322. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  323. glTexCoord2f(f2, f4);
  324. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  325. glTexCoord2f(f4, f1);
  326. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  327. glTexCoord2f(f1, f3);
  328. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  329. glEnd();
  330. glDisable(GL_TEXTURE_2D);
  331. Advance();
  332. /* Quad #4: set color in fragment shader */
  333. data->shader[0]->Bind();
  334. glColor3f(0.0f, 1.0f, 1.0f);
  335. glBegin(GL_TRIANGLES);
  336. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  337. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  338. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  339. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  340. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  341. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  342. glEnd();
  343. glUseProgram(0);
  344. Advance();
  345. /* Quad #5: pass color from vertex shader to fragment shader */
  346. data->shader[1]->Bind();
  347. glColor3f(0.0f, 1.0f, 1.0f);
  348. glBegin(GL_TRIANGLES);
  349. glTexCoord2f(f1, f3);
  350. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  351. glTexCoord2f(f3, f2);
  352. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  353. glTexCoord2f(f2, f4);
  354. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  355. glTexCoord2f(f2, f4);
  356. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  357. glTexCoord2f(f4, f1);
  358. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  359. glTexCoord2f(f1, f3);
  360. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  361. glEnd();
  362. glUseProgram(0);
  363. Advance();
  364. /* Quad #6: apply texture in fragment shader */
  365. data->shader[2]->Bind();
  366. glColor3f(0.0f, 1.0f, 1.0f);
  367. glEnable(GL_TEXTURE_2D);
  368. glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
  369. glBegin(GL_TRIANGLES);
  370. glTexCoord2f(f1, f3);
  371. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  372. glTexCoord2f(f3, f2);
  373. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  374. glTexCoord2f(f2, f4);
  375. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  376. glTexCoord2f(f2, f4);
  377. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  378. glTexCoord2f(f4, f1);
  379. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  380. glTexCoord2f(f1, f3);
  381. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  382. glEnd();
  383. glUseProgram(0);
  384. glDisable(GL_TEXTURE_2D);
  385. Advance();
  386. /* Quad #7: simple vertex buffer */
  387. GLfloat const vertices1[] = { data->aa.x, data->bb.y, 0.0f,
  388. data->bb.x, data->bb.y, 0.0f,
  389. data->bb.x, data->aa.y, 0.0f,
  390. data->bb.x, data->aa.y, 0.0f,
  391. data->aa.x, data->aa.y, 0.0f,
  392. data->aa.x, data->bb.y, 0.0f };
  393. glEnableClientState(GL_COLOR_ARRAY);
  394. glEnableClientState(GL_VERTEX_ARRAY);
  395. glColorPointer(3, GL_FLOAT, 0, colors);
  396. glVertexPointer(3, GL_FLOAT, 0, vertices1);
  397. glDrawArrays(GL_TRIANGLES, 0, 6);
  398. glDisableClientState(GL_VERTEX_ARRAY);
  399. glDisableClientState(GL_COLOR_ARRAY);
  400. Advance();
  401. /* Quad #8: vertex buffer, apply texture and color in fragment shader */
  402. data->shader[3]->Bind();
  403. GLfloat const vertices2[] = { data->aa.x, data->bb.y, 0.0f,
  404. data->bb.x, data->bb.y, 0.0f,
  405. data->bb.x, data->aa.y, 0.0f,
  406. data->bb.x, data->aa.y, 0.0f,
  407. data->aa.x, data->aa.y, 0.0f,
  408. data->aa.x, data->bb.y, 0.0f };
  409. glEnableClientState(GL_VERTEX_ARRAY);
  410. glEnableClientState(GL_COLOR_ARRAY);
  411. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  412. glVertexPointer(3, GL_FLOAT, 0, vertices2);
  413. glColorPointer(3, GL_FLOAT, 0, colors);
  414. glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
  415. glDrawArrays(GL_TRIANGLES, 0, 6);
  416. glDisableClientState(GL_VERTEX_ARRAY);
  417. glDisableClientState(GL_COLOR_ARRAY);
  418. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  419. Advance();
  420. }
  421. void DebugQuad::Advance()
  422. {
  423. data->aa.x += 3.0f * data->step.x;
  424. data->bb.x += 3.0f * data->step.x;
  425. if (data->bb.x > 1.0f)
  426. {
  427. data->aa.x = data->orig.x;
  428. data->bb.x = data->orig.x + 2.0f * data->step.x;
  429. data->aa.y += 3.0f * data->step.y;
  430. data->bb.y += 3.0f * data->step.y;
  431. }
  432. }
  433. DebugQuad::~DebugQuad()
  434. {
  435. delete data;
  436. }
  437. } /* namespace lol */