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.

1110 lines
33 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. #ifdef WIN32
  14. # define _USE_MATH_DEFINES /* for M_PI */
  15. # define WIN32_LEAN_AND_MEAN
  16. # include <windows.h>
  17. #endif
  18. #include <cmath>
  19. #include <cstdio>
  20. #include <cstring>
  21. #include "core.h"
  22. #include "lolgl.h"
  23. #include "loldebug.h"
  24. using namespace std;
  25. namespace lol
  26. {
  27. /*
  28. * OpenGL Feature list:
  29. *
  30. * Android and iOS don't have GL_VERTEX_ARRAY.
  31. *
  32. * iOS does vertex buffers using glVertexAttribPointer(), and does not
  33. * support glVertexPointer().
  34. *
  35. * PSGL (on the PS3) does vertex buffers using glVertexPointer(), and
  36. * does not support glVertexAttribPointer().
  37. */
  38. /*
  39. * DebugQuad implementation class
  40. */
  41. static int const NUM_ARRAYS = 10;
  42. static int const NUM_BUFFERS = 20;
  43. static int const NUM_ATTRS = 20;
  44. static int const NUM_UNIFORMS = 20;
  45. static int const NUM_SHADERS = 20;
  46. static int const NUM_TEXTURES = 10;
  47. static int const TEX_SIZE = 32;
  48. class DebugQuadData
  49. {
  50. friend class DebugQuad;
  51. private:
  52. vec2 orig, step, aa, bb;
  53. int initialised;
  54. float time;
  55. #if !defined __CELLOS_LV2__ && !defined __ANDROID__
  56. GLuint array[NUM_ARRAYS];
  57. #endif
  58. GLuint buffer[NUM_BUFFERS];
  59. Shader *shader[NUM_SHADERS];
  60. GLuint attr[NUM_ATTRS];
  61. GLuint uni[NUM_UNIFORMS];
  62. GLuint texture[NUM_TEXTURES];
  63. uint8_t image[1][TEX_SIZE * TEX_SIZE * 4];
  64. /* Cache a list of points for a quad at the proper coordinates. */
  65. GLfloat const *GetVertexArray()
  66. {
  67. GLfloat tmp[18] = { aa.x, bb.y, 0, bb.x, bb.y, 0, bb.x, aa.y, 0,
  68. bb.x, aa.y, 0, aa.x, aa.y, 0, aa.x, bb.y, 0 };
  69. memcpy(vertices, tmp, sizeof(tmp));
  70. return vertices;
  71. }
  72. GLfloat vertices[18];
  73. /* Cache a list of points for a sine wave, ensuring constant spacing
  74. * between consecutive points. */
  75. static int const SINE_SIZE = 256;
  76. GLfloat const *GetSineArray()
  77. {
  78. static float const SINE_SPACE = 0.01f;
  79. float x = 0.0f;
  80. for (npoints = 0; npoints < SINE_SIZE && x <= 1.0f; npoints++)
  81. {
  82. float y = 0.5f + 0.5f * lol_sin(x * 2.0f * M_PI + time * 2e-3f);
  83. points[npoints * 2] = aa.x + (bb.x - aa.x) * x;
  84. points[npoints * 2 + 1] = aa.y + (bb.y - aa.y) * y;
  85. float dy = M_PI * lol_cos(x * 2.0f * M_PI + time * 2e-3f);
  86. float dx = SINE_SPACE / sqrtf(1.0f + dy * dy);
  87. x += dx;
  88. }
  89. return points;
  90. }
  91. GLfloat points[2 * SINE_SIZE];
  92. int npoints;
  93. };
  94. /*
  95. * Public DebugQuad class
  96. */
  97. DebugQuad::DebugQuad()
  98. : data(new DebugQuadData())
  99. {
  100. data->initialised = 0;
  101. data->time = RandF(10000.0f);
  102. drawgroup = DRAWGROUP_HUD;
  103. }
  104. DebugQuad::~DebugQuad()
  105. {
  106. delete data;
  107. }
  108. void DebugQuad::Advance()
  109. {
  110. data->aa.x += 4.0f * data->step.x;
  111. data->bb.x += 4.0f * data->step.x;
  112. if (data->bb.x > 1.0f)
  113. {
  114. data->aa.x = data->orig.x;
  115. data->bb.x = data->orig.x + 3.0f * data->step.x;
  116. data->aa.y += 4.0f * data->step.y;
  117. data->bb.y += 4.0f * data->step.y;
  118. }
  119. }
  120. void DebugQuad::TickGame(float deltams)
  121. {
  122. Entity::TickGame(deltams);
  123. data->time += deltams;
  124. }
  125. void DebugQuad::TickDraw(float deltams)
  126. {
  127. Entity::TickDraw(deltams);
  128. if (!data->initialised && !IsDestroying())
  129. {
  130. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  131. glGenVertexArrays(NUM_ARRAYS, data->array);
  132. #endif
  133. glGenBuffers(NUM_BUFFERS, data->buffer);
  134. glGenTextures(NUM_TEXTURES, data->texture);
  135. for (int i = 0; i < NUM_SHADERS; i++)
  136. data->shader[i] = NULL;
  137. /* Checkerboard texture */
  138. glEnable(GL_TEXTURE_2D);
  139. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  140. for (int j = 0; j < TEX_SIZE; j++)
  141. for (int i = 0; i < TEX_SIZE; i++)
  142. {
  143. uint8_t wb = (((i / 2) ^ (j / 2)) & 1) * 0xff;
  144. data->image[0][(j * TEX_SIZE + i) * 4 + 0] = wb;
  145. data->image[0][(j * TEX_SIZE + i) * 4 + 1] = wb;
  146. data->image[0][(j * TEX_SIZE + i) * 4 + 2] = wb;
  147. data->image[0][(j * TEX_SIZE + i) * 4 + 3] = 0xff;
  148. }
  149. /* Use GL_RGBA instead of 4 for the internal format (Android) */
  150. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
  151. GL_RGBA, GL_UNSIGNED_BYTE, data->image[0]);
  152. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  153. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  154. data->initialised = 1;
  155. }
  156. else if (data->initialised && IsDestroying())
  157. {
  158. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  159. glDeleteVertexArrays(NUM_ARRAYS, data->array);
  160. #endif
  161. glDeleteBuffers(NUM_BUFFERS, data->buffer);
  162. glDeleteTextures(NUM_TEXTURES, data->texture);
  163. for (int i = 0; i < NUM_SHADERS; i++)
  164. if (data->shader[i])
  165. Shader::Destroy(data->shader[i]);
  166. data->initialised = 0;
  167. }
  168. /* Prepare our quad coordinates */
  169. ivec2 const layout(7, 5);
  170. data->step = vec2(2.0f, -2.0f) / (4 * layout + ivec2(1));
  171. data->orig = vec2(-1.0f, 1.0f) + data->step;
  172. data->aa = data->orig;
  173. data->bb = data->orig + 3.0f * data->step;
  174. /* These points form a [0,1][0,1] square */
  175. GLfloat points[12] = { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
  176. 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
  177. GLfloat texcoords[12];
  178. mat4 t1 = mat4::translate(0.5f, 0.5f, 0.0f)
  179. * mat4::rotate(0.00054f * data->time, 0.0f, 0.0f, 1.0f)
  180. * mat4::translate(-0.5f, -0.5f, 0.0f);
  181. for (int i = 0; i < 6; i++)
  182. {
  183. vec4 p = t1 * vec4(points[i * 2], points[i * 2 + 1], 0.0f, 1.0f);
  184. texcoords[i * 2] = p.x;
  185. texcoords[i * 2 + 1] = p.y;
  186. }
  187. GLfloat colors[18];
  188. mat4 t2 = mat4::translate(0.5f, 0.5f, 0.5f)
  189. * mat4::rotate(0.00034f * data->time, 0.0f, 0.0f, 1.0f)
  190. * mat4::rotate(0.00041f * data->time, 0.0f, 1.0f, 0.0f)
  191. * mat4::rotate(0.00057f * data->time, 1.0f, 0.0f, 0.0f)
  192. * mat4::translate(-0.5f, -0.5f, 0.0f);
  193. for (int i = 0; i < 6; i++)
  194. {
  195. vec4 p = t2 * vec4(points[i * 2], points[i * 2 + 1], 0.0f, 1.0f);
  196. colors[i * 3] = p.x;
  197. colors[i * 3 + 1] = p.y;
  198. colors[i * 3 + 2] = p.z;
  199. }
  200. /* Our default quad color */
  201. vec4 orange(0.8f, 0.5f, 0.2f, 1.0f);
  202. /* Cheap iterators */
  203. #if !defined __CELLOS_LV2__ && !defined __ANDROID__
  204. GLuint *array = data->array;
  205. #endif
  206. GLuint *buffer = data->buffer;
  207. Shader **shader = data->shader;
  208. GLuint *attr = data->attr;
  209. GLuint *uni = data->uni;
  210. /* These may be shared across calls */
  211. GLfloat const *sine;
  212. ResetState();
  213. /*
  214. * Test #1: simple glBegin + GL_TRIANGLES code
  215. *
  216. * Renders an orange square.
  217. */
  218. #if defined HAVE_GLBEGIN || defined USE_GLEW
  219. glColor3f(orange.x, orange.y, orange.z);
  220. glBegin(GL_TRIANGLES);
  221. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  222. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  223. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  224. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  225. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  226. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  227. glEnd();
  228. #endif
  229. Advance();
  230. ResetState();
  231. /*
  232. * Test #2: glBegin + per-vertex coloring
  233. *
  234. * Renders a multicoloured square with varying colors.
  235. */
  236. #if defined HAVE_GLBEGIN || defined USE_GLEW
  237. glBegin(GL_TRIANGLES);
  238. glColor3f(colors[0], colors[1], colors[2]);
  239. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  240. glColor3f(colors[3], colors[4], colors[5]);
  241. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  242. glColor3f(colors[6], colors[7], colors[8]);
  243. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  244. glColor3f(colors[9], colors[10], colors[11]);
  245. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  246. glColor3f(colors[12], colors[13], colors[14]);
  247. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  248. glColor3f(colors[15], colors[16], colors[17]);
  249. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  250. glEnd();
  251. #endif
  252. Advance();
  253. ResetState();
  254. /*
  255. * Test #3: glBegin + texture
  256. *
  257. * Renders a multicoloured square with varying colors multiplied with an
  258. * animated distorted checkerboard.
  259. */
  260. #if defined HAVE_GLBEGIN || defined USE_GLEW
  261. glEnable(GL_TEXTURE_2D);
  262. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  263. glColor3f(1.0f, 1.0f, 1.0f);
  264. glBegin(GL_TRIANGLES);
  265. glColor3f(colors[0], colors[1], colors[2]);
  266. glTexCoord2f(texcoords[0], texcoords[1]);
  267. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  268. glColor3f(colors[3], colors[4], colors[5]);
  269. glTexCoord2f(texcoords[2], texcoords[3]);
  270. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  271. glColor3f(colors[6], colors[7], colors[8]);
  272. glTexCoord2f(texcoords[4], texcoords[5]);
  273. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  274. glColor3f(colors[9], colors[10], colors[11]);
  275. glTexCoord2f(texcoords[6], texcoords[7]);
  276. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  277. glColor3f(colors[12], colors[13], colors[14]);
  278. glTexCoord2f(texcoords[8], texcoords[9]);
  279. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  280. glColor3f(colors[15], colors[16], colors[17]);
  281. glTexCoord2f(texcoords[10], texcoords[11]);
  282. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  283. glEnd();
  284. glDisable(GL_TEXTURE_2D);
  285. #endif
  286. Advance();
  287. ResetState();
  288. /*
  289. * Test #4: glBegin + color in fragment shader
  290. *
  291. * Renders a static, coloured and tiled pattern.
  292. */
  293. #if defined HAVE_GLBEGIN || defined USE_GLEW
  294. if (!shader[0])
  295. shader[0] = Shader::Create(
  296. "#version 110\n"
  297. "void main()"
  298. "{"
  299. " gl_Position = gl_Vertex;"
  300. "}",
  301. "#version 110\n"
  302. "void main()"
  303. "{"
  304. " float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
  305. " float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
  306. " float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
  307. " gl_FragColor = vec4(dx, dy, dz, 1.0);"
  308. "}");
  309. shader[0]->Bind();
  310. shader++;
  311. glColor3f(0.0f, 1.0f, 1.0f);
  312. glBegin(GL_TRIANGLES);
  313. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  314. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  315. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  316. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  317. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  318. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  319. glEnd();
  320. #endif
  321. Advance();
  322. ResetState();
  323. /*
  324. * Test #5: glBegin + pass vertex coord from vertex shader to fragment
  325. * shader for use as color information.
  326. *
  327. * Renders a multicoloured square with varying colors.
  328. */
  329. #if defined HAVE_GLBEGIN || defined USE_GLEW
  330. if (!shader[0])
  331. shader[0] = Shader::Create(
  332. "#version 110\n"
  333. "varying vec4 pass_Color;"
  334. "void main()"
  335. "{"
  336. " float r = gl_MultiTexCoord0.x;"
  337. " float g = gl_MultiTexCoord0.y;"
  338. " float b = gl_MultiTexCoord0.z;"
  339. " pass_Color = vec4(r, g, b, 1.0);"
  340. " gl_Position = gl_Vertex;"
  341. "}",
  342. "#version 110\n"
  343. "varying vec4 pass_Color;"
  344. "void main()"
  345. "{"
  346. " gl_FragColor = pass_Color;"
  347. "}");
  348. shader[0]->Bind();
  349. shader++;
  350. glColor3f(0.0f, 1.0f, 1.0f);
  351. glBegin(GL_TRIANGLES);
  352. glTexCoord3f(colors[0], colors[1], colors[2]);
  353. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  354. glTexCoord3f(colors[3], colors[4], colors[5]);
  355. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  356. glTexCoord3f(colors[6], colors[7], colors[8]);
  357. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  358. glTexCoord3f(colors[9], colors[10], colors[11]);
  359. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  360. glTexCoord3f(colors[12], colors[13], colors[14]);
  361. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  362. glTexCoord3f(colors[15], colors[16], colors[17]);
  363. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  364. glEnd();
  365. #endif
  366. Advance();
  367. ResetState();
  368. /*
  369. * Test #6: glBegin + apply texture in fragment shader
  370. *
  371. * Renders an animated black-and-white distorted checkerboard with a
  372. * zoom ratio twice the one in test #3.
  373. *
  374. * Note: there is no need to glEnable(GL_TEXTURE_2D) when the
  375. * texture lookup is done in a shader.
  376. */
  377. #if defined HAVE_GLBEGIN || defined USE_GLEW
  378. if (!shader[0])
  379. shader[0] = Shader::Create(
  380. "#version 110\n"
  381. "void main()"
  382. "{"
  383. " gl_TexCoord[0] = gl_MultiTexCoord0;"
  384. " gl_Position = gl_Vertex;"
  385. "}",
  386. "#version 110\n"
  387. "uniform sampler2D tex;"
  388. "void main()"
  389. "{"
  390. " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  391. "}");
  392. shader[0]->Bind();
  393. shader++;
  394. glColor3f(0.0f, 1.0f, 1.0f);
  395. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  396. glBegin(GL_TRIANGLES);
  397. glTexCoord2f(texcoords[0], texcoords[1]);
  398. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  399. glTexCoord2f(texcoords[2], texcoords[3]);
  400. glVertex3f(data->bb.x, data->bb.y, 0.0f);
  401. glTexCoord2f(texcoords[4], texcoords[5]);
  402. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  403. glTexCoord2f(texcoords[6], texcoords[7]);
  404. glVertex3f(data->bb.x, data->aa.y, 0.0f);
  405. glTexCoord2f(texcoords[8], texcoords[9]);
  406. glVertex3f(data->aa.x, data->aa.y, 0.0f);
  407. glTexCoord2f(texcoords[10], texcoords[11]);
  408. glVertex3f(data->aa.x, data->bb.y, 0.0f);
  409. glEnd();
  410. #endif
  411. Advance();
  412. ResetState();
  413. /*
  414. * Test #7: glBegin + GL_POINTS
  415. *
  416. * Renders a green sine wave made of 1-pixel points.
  417. */
  418. #if defined HAVE_GLBEGIN || defined USE_GLEW
  419. glColor3f(0.0f, 1.0f, 0.0f);
  420. glPointSize(1.0f);
  421. sine = data->GetSineArray();
  422. glBegin(GL_POINTS);
  423. for (int i = 0; i < data->npoints; i++)
  424. glVertex3f(sine[i * 2], sine[i * 2 + 1], 0.0f);
  425. glEnd();
  426. #endif
  427. Advance();
  428. ResetState();
  429. /*
  430. * Test #8: simple vertex buffer
  431. *
  432. * Renders an orange square.
  433. */
  434. #if !defined __ANDROID__ && !defined __APPLE__
  435. glColor4f(orange.x, orange.y, orange.z, orange.w);
  436. glEnableClientState(GL_VERTEX_ARRAY);
  437. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  438. glDrawArrays(GL_TRIANGLES, 0, 6);
  439. glDisableClientState(GL_VERTEX_ARRAY);
  440. #endif
  441. Advance();
  442. ResetState();
  443. /*
  444. * Test #9: simple point buffer
  445. *
  446. * Renders a green sine wave made of 1-pixel points.
  447. */
  448. #if !defined __ANDROID__ && !defined __APPLE__
  449. glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
  450. glPointSize(1.0f);
  451. glEnableClientState(GL_VERTEX_ARRAY);
  452. glVertexPointer(2, GL_FLOAT, 0, data->GetSineArray());
  453. glDrawArrays(GL_POINTS, 0, data->npoints);
  454. glDisableClientState(GL_VERTEX_ARRAY);
  455. #endif
  456. Advance();
  457. ResetState();
  458. /*
  459. * Test #10: vertex buffer + per-vertex coloring
  460. *
  461. * Renders a multicoloured square with varying colors.
  462. */
  463. #if !defined __ANDROID__ && !defined __APPLE__
  464. glEnableClientState(GL_VERTEX_ARRAY);
  465. glEnableClientState(GL_COLOR_ARRAY);
  466. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  467. glColorPointer(3, GL_FLOAT, 0, colors);
  468. glDrawArrays(GL_TRIANGLES, 0, 6);
  469. glDisableClientState(GL_VERTEX_ARRAY);
  470. glDisableClientState(GL_COLOR_ARRAY);
  471. #endif
  472. Advance();
  473. ResetState();
  474. /*
  475. * Test #11: vertex buffer + per-vertex coloring + texture
  476. *
  477. * Renders a multicoloured square with varying colors multiplied with an
  478. * animated distorted checkerboard.
  479. */
  480. #if !defined __ANDROID__ && !defined __APPLE__
  481. glEnable(GL_TEXTURE_2D);
  482. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  483. glEnableClientState(GL_VERTEX_ARRAY);
  484. glEnableClientState(GL_COLOR_ARRAY);
  485. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  486. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  487. glColorPointer(3, GL_FLOAT, 0, colors);
  488. glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
  489. glDrawArrays(GL_TRIANGLES, 0, 6);
  490. glDisableClientState(GL_VERTEX_ARRAY);
  491. glDisableClientState(GL_COLOR_ARRAY);
  492. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  493. glDisable(GL_TEXTURE_2D);
  494. #endif
  495. Advance();
  496. ResetState();
  497. /*
  498. * Test #12: vertex buffer + hardcoded color in 1.10 fragment shader
  499. * (GLSL) or in Cg fragment shader (PS3)
  500. *
  501. * Renders an orange square.
  502. */
  503. #if !defined __ANDROID__ && !defined __APPLE__
  504. if (!shader[0])
  505. #if !defined __CELLOS_LV2__
  506. shader[0] = Shader::Create(
  507. "#version 110\n"
  508. "void main()"
  509. "{"
  510. " gl_Position = gl_Vertex;"
  511. "}",
  512. "#version 110\n"
  513. "void main()"
  514. "{"
  515. " gl_FragColor = vec4(0.8, 0.5, 0.2, 1.0);"
  516. "}");
  517. #else
  518. shader[0] = Shader::Create(
  519. "void main(float4 in_Position : POSITION,"
  520. " out float4 out_Position : POSITION)"
  521. "{"
  522. " out_Position = in_Position;"
  523. "}",
  524. "void main(out float4 out_FragColor : COLOR)"
  525. "{"
  526. " out_FragColor = float4(0.8, 0.5, 0.2, 1.0);"
  527. "}");
  528. #endif
  529. shader[0]->Bind();
  530. shader++;
  531. glEnableClientState(GL_VERTEX_ARRAY);
  532. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  533. glDrawArrays(GL_TRIANGLES, 0, 6);
  534. glDisableClientState(GL_VERTEX_ARRAY);
  535. #endif
  536. Advance();
  537. ResetState();
  538. /*
  539. * Test #13: vertex buffer + uniform color in 1.10 fragment shader
  540. * (GLSL) or in Cg fragment shader (PS3)
  541. *
  542. * Renders an orange square.
  543. */
  544. #if !defined __ANDROID__ && !defined __APPLE__
  545. if (!shader[0])
  546. {
  547. #if !defined __CELLOS_LV2__
  548. shader[0] = Shader::Create(
  549. "#version 110\n"
  550. "void main()"
  551. "{"
  552. " gl_Position = gl_Vertex;"
  553. "}",
  554. "#version 110\n"
  555. "uniform vec4 in_Color;"
  556. "void main()"
  557. "{"
  558. " gl_FragColor = in_Color;"
  559. "}");
  560. #else
  561. shader[0] = Shader::Create(
  562. "void main(float4 in_Position : POSITION,"
  563. " out float4 out_Position : POSITION)"
  564. "{"
  565. " out_Position = in_Position;"
  566. "}",
  567. "uniform float4 in_Color;"
  568. "void main(out float4 out_FragColor : COLOR)"
  569. "{"
  570. " out_FragColor = in_Color;"
  571. "}");
  572. #endif
  573. uni[0] = shader[0]->GetUniformLocation("in_Color");
  574. }
  575. shader[0]->Bind();
  576. shader[0]->SetUniform(uni[0], orange);
  577. shader++;
  578. uni++;
  579. glEnableClientState(GL_VERTEX_ARRAY);
  580. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  581. glDrawArrays(GL_TRIANGLES, 0, 6);
  582. glDisableClientState(GL_VERTEX_ARRAY);
  583. #endif
  584. Advance();
  585. ResetState();
  586. /*
  587. * Test #14: vertex buffer + color in 1.10 fragment shader (GLSL) or
  588. * in Cg fragment shader (PS3)
  589. *
  590. * Renders a static, coloured and tiled pattern.
  591. */
  592. #if !defined __ANDROID__ && !defined __APPLE__
  593. if (!shader[0])
  594. #if !defined __CELLOS_LV2__
  595. shader[0] = Shader::Create(
  596. "#version 110\n"
  597. "void main()"
  598. "{"
  599. " gl_Position = gl_Vertex;"
  600. "}",
  601. "#version 110\n"
  602. "void main()"
  603. "{"
  604. " float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
  605. " float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
  606. " float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
  607. " gl_FragColor = vec4(dx, dy, dz, 1.0);"
  608. "}");
  609. #else
  610. shader[0] = Shader::Create(
  611. "void main(float4 in_Position : POSITION,"
  612. " out float4 out_Position : POSITION)"
  613. "{"
  614. " out_Position = in_Position;"
  615. "}",
  616. "void main(float4 in_FragCoord : WPOS,"
  617. " out float4 out_FragColor : COLOR)"
  618. "{"
  619. " float dx = frac(in_FragCoord.x * in_FragCoord.y * 0.5) * 2.0;"
  620. " float dy = frac(in_FragCoord.x * 0.125);"
  621. " float dz = frac(in_FragCoord.y * 0.125);"
  622. " out_FragColor = float4(dx, dy, dz, 1.0);"
  623. "}");
  624. #endif
  625. shader[0]->Bind();
  626. shader++;
  627. glEnableClientState(GL_VERTEX_ARRAY);
  628. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  629. glDrawArrays(GL_TRIANGLES, 0, 6);
  630. glDisableClientState(GL_VERTEX_ARRAY);
  631. #endif
  632. Advance();
  633. ResetState();
  634. /*
  635. * Test #15: vertex buffer + uniform matrix for color transform in 1.10
  636. * or Cg fragment shader
  637. *
  638. * Renders a multicoloured square with varying colors.
  639. */
  640. #if !defined __ANDROID__ && !defined __APPLE__
  641. if (!shader[0])
  642. {
  643. #if !defined __CELLOS_LV2__
  644. shader[0] = Shader::Create(
  645. "#version 110\n"
  646. "varying vec4 pass_Color;"
  647. "uniform mat4 in_Matrix;"
  648. "void main()"
  649. "{"
  650. " gl_Position = gl_Vertex;"
  651. " pass_Color = in_Matrix * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);"
  652. "}",
  653. "#version 110\n"
  654. "varying vec4 pass_Color;"
  655. "void main()"
  656. "{"
  657. " gl_FragColor = pass_Color;"
  658. "}");
  659. #else
  660. shader[0] = Shader::Create(
  661. "void main(float4 in_Position : POSITION,"
  662. " float2 in_TexCoord : TEXCOORD0,"
  663. " uniform float4x4 in_Matrix,"
  664. " out float4 out_Color : COLOR,"
  665. " out float4 out_Position : POSITION)"
  666. "{"
  667. " out_Position = in_Position;"
  668. " out_Color = mul(in_Matrix, float4(in_TexCoord, 0, 1));"
  669. "}",
  670. "void main(float4 in_Color : COLOR,"
  671. " out float4 out_FragColor : COLOR)"
  672. "{"
  673. " out_FragColor = in_Color;"
  674. "}");
  675. #endif
  676. uni[0] = shader[0]->GetUniformLocation("in_Matrix");
  677. }
  678. shader[0]->Bind();
  679. shader[0]->SetUniform(uni[0], t2);
  680. shader++;
  681. uni++;
  682. glEnableClientState(GL_VERTEX_ARRAY);
  683. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  684. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  685. glTexCoordPointer(2, GL_FLOAT, 0, points);
  686. glDrawArrays(GL_TRIANGLES, 0, 6);
  687. glDisableClientState(GL_VERTEX_ARRAY);
  688. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  689. #endif
  690. Advance();
  691. ResetState();
  692. /*
  693. * Test #16: simple point buffer
  694. *
  695. * Renders an antialiased green sine wave made of 1-pixel points.
  696. */
  697. #if !defined __ANDROID__ && !defined __APPLE__ && !defined __CELLOS_LV2__
  698. if (!shader[0])
  699. shader[0] = Shader::Create(
  700. "#version 120\n"
  701. "varying vec4 pass_Color;"
  702. "void main()"
  703. "{"
  704. " pass_Color = vec4(0.0, 1.0, 0.0, 1.0);"
  705. " gl_Position = gl_Vertex;"
  706. "}",
  707. "#version 120\n"
  708. "varying vec4 pass_Color;"
  709. "void main()"
  710. "{"
  711. " vec2 d = gl_PointCoord.st - vec2(0.5, 0.5);"
  712. " float k = max(0.0, 2.0 * (0.5 - sqrt(dot(d, d))));"
  713. " gl_FragColor = vec4(pass_Color.xyz, k);"
  714. "}");
  715. shader[0]->Bind();
  716. shader++;
  717. glEnable(GL_POINT_SPRITE);
  718. glEnable(GL_BLEND);
  719. glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
  720. glPointSize(3.0f);
  721. glEnableClientState(GL_VERTEX_ARRAY);
  722. glVertexPointer(2, GL_FLOAT, 0, data->GetSineArray());
  723. glDrawArrays(GL_POINTS, 0, data->npoints);
  724. glDisableClientState(GL_VERTEX_ARRAY);
  725. glDisable(GL_POINT_SPRITE);
  726. glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
  727. #endif
  728. Advance();
  729. ResetState();
  730. /*
  731. * Test #17: vertex buffer + texture & color in 1.10 fragment shader
  732. *
  733. * Renders a multicoloured square with varying colors xored with an
  734. * animated distorted checkerboard.
  735. */
  736. #if !defined __ANDROID__ && !defined __APPLE__
  737. if (!shader[0])
  738. #if !defined __CELLOS_LV2__
  739. shader[0] = Shader::Create(
  740. "#version 110\n"
  741. "varying vec4 pass_Color;"
  742. "void main()"
  743. "{"
  744. " gl_TexCoord[0] = gl_MultiTexCoord0;"
  745. " pass_Color = gl_Color;"
  746. " gl_Position = gl_Vertex;"
  747. "}",
  748. "#version 110\n"
  749. "varying vec4 pass_Color;"
  750. "uniform sampler2D tex;"
  751. "void main()"
  752. "{"
  753. " vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  754. " gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
  755. "}");
  756. #else
  757. shader[0] = Shader::Create(
  758. "void main(float4 in_Position : POSITION,"
  759. " float2 in_TexCoord : TEXCOORD0,"
  760. " float4 in_Color : COLOR,"
  761. " out float4 out_Color : COLOR,"
  762. " out float4 out_Position : POSITION,"
  763. " out float2 out_TexCoord : TEXCOORD0)"
  764. "{"
  765. " out_TexCoord = in_TexCoord;"
  766. " out_Color = in_Color;"
  767. " out_Position = in_Position;"
  768. "}",
  769. "void main(float2 in_TexCoord : TEXCOORD0,"
  770. " float4 in_Color : COLOR,"
  771. " uniform sampler2D tex,"
  772. " out float4 out_FragColor : COLOR)"
  773. "{"
  774. " float4 tmp = tex2D(tex, in_TexCoord * 0.25);"
  775. " out_FragColor = float4(abs(tmp.xyz - in_Color.xyz), 1);"
  776. "}");
  777. #endif
  778. shader[0]->Bind();
  779. shader++;
  780. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  781. glEnableClientState(GL_VERTEX_ARRAY);
  782. glEnableClientState(GL_COLOR_ARRAY);
  783. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  784. glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
  785. glColorPointer(3, GL_FLOAT, 0, colors);
  786. glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
  787. glDrawArrays(GL_TRIANGLES, 0, 6);
  788. glDisableClientState(GL_VERTEX_ARRAY);
  789. glDisableClientState(GL_COLOR_ARRAY);
  790. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  791. #endif
  792. Advance();
  793. ResetState();
  794. /*
  795. * Test #18: vertex buffer + texture & color in 1.20 fragment shader
  796. *
  797. * Renders a multicoloured square with varying colors xored with an
  798. * animated distorted checkerboard.
  799. */
  800. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  801. if (!shader[0])
  802. {
  803. shader[0] = Shader::Create(
  804. "#version 120\n"
  805. "attribute vec3 in_Vertex;"
  806. "attribute vec3 in_Color;"
  807. "attribute vec2 in_MultiTexCoord0;"
  808. "varying vec4 pass_Color;"
  809. "void main()"
  810. "{"
  811. " gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
  812. " pass_Color = vec4(in_Color, 1.0);"
  813. " gl_Position = vec4(in_Vertex, 1.0);"
  814. "}",
  815. "#version 120\n"
  816. "varying vec4 pass_Color;"
  817. "uniform sampler2D tex;"
  818. "void main()"
  819. "{"
  820. " vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  821. " gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
  822. "}");
  823. attr[0] = shader[0]->GetAttribLocation("in_Vertex");
  824. attr[1] = shader[0]->GetAttribLocation("in_Color");
  825. attr[2] = shader[0]->GetAttribLocation("in_MultiTexCoord0");
  826. }
  827. shader[0]->Bind();
  828. shader++;
  829. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  830. glBindVertexArray(*array++);
  831. glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
  832. glBufferData(GL_ARRAY_BUFFER, 3 * 6 * sizeof(GLfloat),
  833. data->GetVertexArray(), GL_DYNAMIC_DRAW);
  834. glVertexAttribPointer(attr[0], 3, GL_FLOAT, GL_FALSE, 0, 0);
  835. glEnableVertexAttribArray(attr[0]);
  836. glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
  837. glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors,
  838. GL_DYNAMIC_DRAW);
  839. glVertexAttribPointer(attr[1], 3, GL_FLOAT, GL_FALSE, 0, 0);
  840. glEnableVertexAttribArray(attr[1]);
  841. glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
  842. glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
  843. GL_DYNAMIC_DRAW);
  844. glVertexAttribPointer(attr[2], 2, GL_FLOAT, GL_FALSE, 0, 0);
  845. glEnableVertexAttribArray(attr[2]);
  846. glDrawArrays(GL_TRIANGLES, 0, 6);
  847. glBindVertexArray(0);
  848. glDisableVertexAttribArray(*attr++);
  849. glDisableVertexAttribArray(*attr++);
  850. glDisableVertexAttribArray(*attr++);
  851. #endif
  852. Advance();
  853. ResetState();
  854. /*
  855. * Test #19: vertex buffer + texture & color in 1.30 fragment shader
  856. *
  857. * Renders a multicoloured square with varying colors xored with an
  858. * animated distorted checkerboard.
  859. */
  860. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  861. if (!shader[0])
  862. {
  863. shader[0] = Shader::Create(
  864. "#version 130\n"
  865. "in vec3 in_Vertex;"
  866. "in vec3 in_Color;"
  867. "in vec2 in_MultiTexCoord0;"
  868. "out vec4 pass_Color;"
  869. "void main()"
  870. "{"
  871. " gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
  872. " pass_Color = vec4(in_Color, 1.0);"
  873. " gl_Position = vec4(in_Vertex, 1.0);"
  874. "}",
  875. "#version 130\n"
  876. "in vec4 pass_Color;"
  877. "uniform sampler2D tex;"
  878. "void main()"
  879. "{"
  880. " vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
  881. " gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
  882. "}");
  883. attr[0] = shader[0]->GetAttribLocation("in_Vertex");
  884. attr[1] = shader[0]->GetAttribLocation("in_Color");
  885. attr[2] = shader[0]->GetAttribLocation("in_MultiTexCoord0");
  886. }
  887. shader[0]->Bind();
  888. shader++;
  889. glBindTexture(GL_TEXTURE_2D, data->texture[0]);
  890. glBindVertexArray(*array++);
  891. glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
  892. glBufferData(GL_ARRAY_BUFFER, 3 * 6 * sizeof(GLfloat),
  893. data->GetVertexArray(), GL_DYNAMIC_DRAW);
  894. glVertexAttribPointer(attr[0], 3, GL_FLOAT, GL_FALSE, 0, 0);
  895. glEnableVertexAttribArray(attr[0]);
  896. glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
  897. glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors,
  898. GL_DYNAMIC_DRAW);
  899. glVertexAttribPointer(attr[1], 3, GL_FLOAT, GL_FALSE, 0, 0);
  900. glEnableVertexAttribArray(attr[1]);
  901. glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
  902. glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
  903. GL_DYNAMIC_DRAW);
  904. glVertexAttribPointer(attr[2], 2, GL_FLOAT, GL_FALSE, 0, 0);
  905. glEnableVertexAttribArray(attr[2]);
  906. glDrawArrays(GL_TRIANGLES, 0, 6);
  907. glBindVertexArray(0);
  908. glDisableVertexAttribArray(*attr++);
  909. glDisableVertexAttribArray(*attr++);
  910. glDisableVertexAttribArray(*attr++);
  911. #endif
  912. Advance();
  913. ResetState();
  914. /* Check that we didn't overflow our list */
  915. #if !defined __CELLOS_LV2__ && !defined __ANDROID__
  916. if (array > data->array + NUM_ARRAYS)
  917. Log::Error("too many arrays used\n");
  918. #endif
  919. if (buffer > data->buffer + NUM_BUFFERS)
  920. Log::Error("too many buffers used\n");
  921. if (shader > data->shader + NUM_SHADERS)
  922. Log::Error("too many shaders used\n");
  923. if (attr > data->attr + NUM_ATTRS)
  924. Log::Error("too many attributes used\n");
  925. }
  926. void DebugQuad::ResetState()
  927. {
  928. /* Reset GL states to something reasonably safe */
  929. #if defined HAVE_GLBEGIN || defined USE_GLEW || defined __CELLOS_LV2__
  930. glMatrixMode(GL_PROJECTION);
  931. glLoadIdentity();
  932. glMatrixMode(GL_MODELVIEW);
  933. glLoadIdentity();
  934. #endif
  935. #if !defined __ANDROID__ && !defined __APPLE__
  936. glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  937. #endif
  938. glEnable(GL_TEXTURE_2D);
  939. glBindTexture(GL_TEXTURE_2D, 0);
  940. #if defined HAVE_GLBEGIN || defined USE_GLEW || defined __CELLOS_LV2__
  941. glClientActiveTexture(GL_TEXTURE0);
  942. #endif
  943. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  944. glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
  945. #endif
  946. glDisable(GL_TEXTURE_2D);
  947. glDisable(GL_BLEND);
  948. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  949. glDisable(GL_POINT_SPRITE);
  950. #endif
  951. glBindBuffer(GL_ARRAY_BUFFER, 0);
  952. #if !defined __CELLOS_LV2__
  953. glUseProgram(0);
  954. #else
  955. cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
  956. cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
  957. #endif
  958. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  959. glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
  960. #endif
  961. }
  962. } /* namespace lol */