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.
 
 
 

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