/examples/glcubes.winxed

http://github.com/NotFound/winxed · Unknown · 402 lines · 349 code · 53 blank · 0 comment · 0 complexity · 3df784f736f5332ce323019a2b2d894d MD5 · raw file

  1. #! winxed
  2. // glcubes.winxed
  3. // Opengl demo
  4. //**********************************************************************
  5. const float PI = 3.1415926;
  6. const float ToRad = PI / 180.0;
  7. const int
  8. GLUT_RGBA = 0x0000,
  9. GLUT_DOUBLE = 0x0002,
  10. GLUT_DEPTH = 0x0010,
  11. GLUT_KEY_LEFT = 0x0064,
  12. GLUT_KEY_RIGHT = 0x0066,
  13. GLUT_KEY_UP = 0x0065,
  14. GLUT_KEY_DOWN = 0x0067,
  15. GL_COLOR_BUFFER_BIT = 0x00004000,
  16. GL_DEPTH_BUFFER_BIT = 0x00000100,
  17. GL_TRIANGLES = 0x0004,
  18. GL_QUADS = 0x0007,
  19. GL_BACK = 0x0405,
  20. GL_DEPTH_TEST = 0x0B71,
  21. GL_MODELVIEW = 0x1700,
  22. GL_PROJECTION = 0x1701;
  23. /***********************************************************************
  24. Callbacks
  25. OpenGL callbacks take no parameters, work around that by creating
  26. funtion objects for each callback that forward to the corresponding
  27. methods in a OpenGlWindow object.
  28. ***********************************************************************/
  29. class OpenGlCallback
  30. {
  31. var w; // The window this callback refers
  32. // The callback mechanics checks 'does invokable',
  33. // overriding does takes care of that requisite.
  34. function does[vtable](string doname)
  35. {
  36. return doname == 'invokable';
  37. }
  38. // Initialize
  39. function set(var w)
  40. {
  41. self.w = w;
  42. }
  43. }
  44. class Reshape : OpenGlCallback
  45. {
  46. function invoke[vtable](int w, int h)
  47. {
  48. self.w.reshape(w, h);
  49. }
  50. }
  51. class Draw : OpenGlCallback
  52. {
  53. function invoke[vtable]()
  54. {
  55. self.w.draw();
  56. }
  57. }
  58. class Idle : OpenGlCallback
  59. {
  60. function invoke[vtable]()
  61. {
  62. self.w.idle();
  63. }
  64. }
  65. class Keyboard : OpenGlCallback
  66. {
  67. function invoke[vtable](int key, int x, int y)
  68. {
  69. self.w.keyboard(key, x, y);
  70. }
  71. }
  72. class Special : OpenGlCallback
  73. {
  74. function invoke[vtable](int key, int x, int y)
  75. {
  76. self.w.specialKey(key, x, y);
  77. }
  78. }
  79. //**********************************************************************
  80. class Cube
  81. {
  82. var r;
  83. var g;
  84. var b;
  85. var x;
  86. var y;
  87. var z;
  88. function Cube(float r, float g, float b, float x, float y, float z)
  89. {
  90. self.r = r;
  91. self.g = g;
  92. self.b = b;
  93. self.x = x;
  94. self.y = y;
  95. self.z = z;
  96. }
  97. function quad()
  98. {
  99. glBegin(GL_QUADS);
  100. glVertex3f( 0.5, 0.5, 0.0);
  101. glVertex3f( 0.5, -0.5, 0.0);
  102. glVertex3f(-0.5, -0.5, 0.0);
  103. glVertex3f(-0.5, 0.5, 0.0);
  104. glEnd();
  105. }
  106. function wire()
  107. {
  108. float x = self.x;
  109. float y = self.y;
  110. float z = self.z;
  111. glPushMatrix();
  112. glTranslatef(x, y, z);
  113. glColor4f(1.0, 1.0, 1.0, 0.2);
  114. glutWireCube(1.3);
  115. glPopMatrix();
  116. }
  117. function draw()
  118. {
  119. float r = self.r;
  120. float g = self.g;
  121. float b = self.b;
  122. float x = self.x;
  123. float y = self.y;
  124. float z = self.z;
  125. float f = 0.8;
  126. glColor3f(r * f, g * f, b * f);
  127. glPushMatrix();
  128. glTranslatef(x, y, z);
  129. glTranslatef(0.0, 0.0, -0.5);
  130. self.quad();
  131. f = 0.4;
  132. glColor3f(r * f, g * f, b * f);
  133. glPushMatrix();
  134. glTranslatef(0.0, 0.0, 1.0);
  135. glRotatef(180.0, 0.0, 1.0, 0.0);
  136. self.quad();
  137. glPopMatrix();
  138. f = 0.7;
  139. glColor3f(r * f, g * f, b * f);
  140. glPushMatrix();
  141. glRotatef(90.0, 0.0, 1.0, 0.0);
  142. glTranslatef(-0.5, 0.0, -0.5);
  143. self.quad();
  144. f = 0.6;
  145. glColor3f(r * f, g * f, b * f);
  146. glTranslatef(0.0, 0.0, 1.0);
  147. self.quad();
  148. glPopMatrix();
  149. f = 1.0;
  150. glColor3f(r * f, g * f, b * f);
  151. glPushMatrix();
  152. glRotatef(90.0, 1.0, 0.0, 0.0);
  153. glTranslatef( 0.0, 0.5, -0.5);
  154. self.quad();
  155. f = 0.3;
  156. glColor3f(r * f, g * f, b * f);
  157. glTranslatef(0.0, 0.0, 1.0);
  158. self.quad();
  159. glPopMatrix();
  160. glPopMatrix();
  161. }
  162. }
  163. //**********************************************************************
  164. class OpenGlWindow
  165. {
  166. const float basestepvangle = 1.0;
  167. const float basestephangle = 0.1;
  168. var savecb;
  169. var w;
  170. var init;
  171. var withwires;
  172. var aspect;
  173. var ipos;
  174. var vangle;
  175. var angle;
  176. var stephangle;
  177. var distance;
  178. var cubes;
  179. function create(string title)
  180. {
  181. int w = glutCreateWindow(title);
  182. self.w = w;
  183. self.withwires = true;
  184. self.aspect = 1.0;
  185. self.vangle = 20.0;
  186. self.angle = 0.0;
  187. self.stephangle = basestephangle;
  188. self.ipos = 0;
  189. self.distance = 6.0;
  190. var cubes = [];
  191. self.cubes = cubes;
  192. cubes.push(new Cube(0.0, 1.0, 0.0, 0.0, 0.0, 0.0));
  193. cubes.push(new Cube(0.5, 0.7, 0.5, 2.0, 0.0, 0.0));
  194. cubes.push(new Cube(1.0, 1.0, 0.0, -2.0, 0.0, 0.0));
  195. cubes.push(new Cube(0.0, 1.0, 1.0, 0.0, 0.0, 2.0));
  196. cubes.push(new Cube(1.0, 0.0, 1.0, 0.0, 0.0, -2.0));
  197. cubes.push(new Cube(1.0, 1.0, 1.0, -2.0, 0.0, -2.0));
  198. cubes.push(new Cube(0.5, 0.5, 1.0, -2.0, 0.0, 2.0));
  199. cubes.push(new Cube(0.5, 0.8, 0.7, 2.0, 0.0, -2.0));
  200. cubes.push(new Cube(1.0, 0.8, 0.8, 2.0, 0.0, 2.0));
  201. cubes.push(new Cube(1.0, 0.0, 0.0, 0.0, 2.0, 0.0));
  202. var savecb = [];
  203. self.savecb = savecb;
  204. var d = new Reshape; d.set(self);
  205. savecb.push(d);
  206. glutReshapeFunc(d);
  207. d = new Draw; d.set(self);
  208. savecb.push(d);
  209. glutDisplayFunc(d);
  210. d = new Keyboard; d.set(self);
  211. savecb.push(d);
  212. glutKeyboardFunc(d);
  213. d = new Special; d.set(self);
  214. savecb.push(d);
  215. glutSpecialFunc(d);
  216. float now;
  217. ${ time now };
  218. self.init = now;
  219. d = new Idle; d.set(self);
  220. savecb.push(d);
  221. glutIdleFunc(d);
  222. }
  223. function idle()
  224. {
  225. float init = self.init;
  226. float now;
  227. ${ time now };
  228. float dt = (now - init) * 100.0;
  229. int it = dt;
  230. int ipos = self.ipos;
  231. if (it != ipos) {
  232. self.ipos =: it;
  233. self.angle += self.stephangle;
  234. glutPostRedisplay();
  235. }
  236. }
  237. function reshape(int w, int h)
  238. {
  239. float aspect = w;
  240. aspect = aspect / h;
  241. self.aspect =: aspect;
  242. glViewport(0, 0, w, h);
  243. }
  244. function draw()
  245. {
  246. int buffers = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
  247. glClear(buffers);
  248. glMatrixMode(GL_PROJECTION);
  249. glLoadIdentity();
  250. gluPerspective(60.0, self.aspect, 0.1, 60.0);
  251. float angle = self.angle;
  252. float hangle = angle * ToRad;
  253. float distance = self.distance;
  254. float vangle = self.vangle;
  255. vangle = vangle * ToRad;
  256. float ypos = distance * sin(vangle);
  257. float hdistance = distance * cos(vangle);
  258. float xpos = hdistance * sin(hangle);
  259. float zpos = hdistance * cos(hangle);
  260. glMatrixMode(GL_MODELVIEW);
  261. glLoadIdentity();
  262. gluLookAt(
  263. xpos, ypos, zpos,
  264. 0.0, 0.0, 0.0,
  265. 0.0, 1.0, 0.0);
  266. var withwires = self.withwires;
  267. if (distance < 20.0 && withwires)
  268. for (var cube in self.cubes)
  269. cube.wire();
  270. for (var cube in self.cubes)
  271. cube.draw();
  272. glutSwapBuffers();
  273. // Without this sweep it leaks memory continuously.
  274. // Don't know if it's a problem with the opengl module
  275. // or in parrot internals.
  276. ${ sweep 1 };
  277. }
  278. function keyboard(int key, int x, int y)
  279. {
  280. float distance = self.distance;
  281. const float step = 0.1;
  282. switch (key) {
  283. case ord(' '):
  284. self.withwires =: ! self.withwires;
  285. break;
  286. case ord("\e"):
  287. glutDestroyWindow(self.w);
  288. break;
  289. case ord("+"):
  290. distance = distance - step;
  291. self.distance =: distance;
  292. break;
  293. case ord("-"):
  294. distance = distance + step;
  295. self.distance =: distance;
  296. break;
  297. }
  298. }
  299. function specialKey(int key, int x, int y)
  300. {
  301. float vangle = self.vangle;
  302. float stephangle = self.stephangle;
  303. const float step = 0.1;
  304. switch (key) {
  305. case GLUT_KEY_LEFT:
  306. if (stephangle < 0)
  307. stephangle = basestephangle;
  308. else
  309. stephangle += basestephangle;
  310. self.stephangle =: stephangle;
  311. break;
  312. case GLUT_KEY_RIGHT:
  313. if (stephangle > 0)
  314. stephangle = -basestephangle;
  315. else
  316. stephangle -= basestephangle;
  317. self.stephangle =: stephangle;
  318. break;
  319. case GLUT_KEY_UP:
  320. vangle = vangle + basestepvangle;
  321. if (vangle < 90.0)
  322. self.vangle =: vangle;
  323. break;
  324. case GLUT_KEY_DOWN:
  325. vangle = vangle - basestepvangle;
  326. if (vangle > -90.0)
  327. self.vangle =: vangle;
  328. break;
  329. }
  330. }
  331. }
  332. //**********************************************************************
  333. function main(var argv)
  334. {
  335. using extern OpenGL;
  336. using OpenGL._export_all_functions;
  337. _export_all_functions();
  338. using extern NCI.Utils;
  339. using NCI.Utils.call_toolkit_init;
  340. using OpenGL.glutInit;
  341. call_toolkit_init(glutInit, argv);
  342. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  343. var window = new OpenGlWindow;
  344. window.create('glcubes - Winxed OpenGL demo');
  345. glCullFace(GL_BACK);
  346. glEnable(GL_DEPTH_TEST);
  347. glutMainLoop();
  348. }
  349. // End