wrap_Graphics.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. /**
  2. * Copyright (c) 2006-2010 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "wrap_Graphics.h"
  21. #include <image/ImageData.h>
  22. #include <font/Rasterizer.h>
  23. #include <font/FontData.h>
  24. #include <scripts/graphics.lua.h>
  25. namespace love
  26. {
  27. namespace graphics
  28. {
  29. namespace opengl
  30. {
  31. static Graphics * instance = 0;
  32. int w_checkMode(lua_State * L)
  33. {
  34. int w = luaL_checkint(L, 1);
  35. int h = luaL_checkint(L, 2);
  36. bool fs = luax_toboolean(L, 3);
  37. luax_pushboolean(L, instance->checkMode(w, h, fs));
  38. return 1;
  39. }
  40. int w_setMode(lua_State * L)
  41. {
  42. int w = luaL_checkint(L, 1);
  43. int h = luaL_checkint(L, 2);
  44. bool fs = luax_optboolean(L, 3, false);
  45. bool vsync = luax_optboolean(L, 4, true);
  46. int fsaa = luaL_optint(L, 5, 0);
  47. luax_pushboolean(L, instance->setMode(w, h, fs, vsync, fsaa));
  48. return 1;
  49. }
  50. int w_toggleFullscreen(lua_State * L)
  51. {
  52. luax_pushboolean(L, instance->toggleFullscreen());
  53. return 1;
  54. }
  55. int w_reset(lua_State *)
  56. {
  57. instance->reset();
  58. return 0;
  59. }
  60. int w_clear(lua_State *)
  61. {
  62. instance->clear();
  63. return 0;
  64. }
  65. int w_present(lua_State *)
  66. {
  67. instance->present();
  68. return 0;
  69. }
  70. int w_setIcon(lua_State * L)
  71. {
  72. Image * image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  73. instance->setIcon(image);
  74. return 0;
  75. }
  76. int w_setCaption(lua_State * L)
  77. {
  78. const char * str = luaL_checkstring(L, 1);
  79. instance->setCaption(str);
  80. return 0;
  81. }
  82. int w_getCaption(lua_State * L)
  83. {
  84. return instance->getCaption(L);
  85. }
  86. int w_getWidth(lua_State * L)
  87. {
  88. lua_pushnumber(L, instance->getWidth());
  89. return 1;
  90. }
  91. int w_getHeight(lua_State * L)
  92. {
  93. lua_pushnumber(L, instance->getHeight());
  94. return 1;
  95. }
  96. int w_isCreated(lua_State * L)
  97. {
  98. luax_pushboolean(L, instance->isCreated());
  99. return 1;
  100. }
  101. int w_getModes(lua_State * L)
  102. {
  103. return instance->getModes(L);
  104. }
  105. int w_setScissor(lua_State * L)
  106. {
  107. if(lua_gettop(L) == 0)
  108. {
  109. instance->setScissor();
  110. return 0;
  111. }
  112. int x = luaL_checkint(L, 1);
  113. int y = luaL_checkint(L, 2);
  114. int w = luaL_checkint(L, 3);
  115. int h = luaL_checkint(L, 4);
  116. instance->setScissor(x, y, w, h);
  117. return 0;
  118. }
  119. int w_getScissor(lua_State * L)
  120. {
  121. return instance->getScissor(L);
  122. }
  123. int w_newImage(lua_State * L)
  124. {
  125. // Convert to File, if necessary.
  126. if(lua_isstring(L, 1))
  127. luax_convobj(L, 1, "filesystem", "newFile");
  128. // Convert to ImageData, if necessary.
  129. if(luax_istype(L, 1, FILESYSTEM_FILE_T))
  130. luax_convobj(L, 1, "image", "newImageData");
  131. love::image::ImageData * data = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
  132. // Create the image.
  133. Image * image = 0;
  134. try {
  135. image = instance->newImage(data);
  136. } catch (love::Exception & e) {
  137. luaL_error(L, e.what());
  138. }
  139. if(image == 0)
  140. return luaL_error(L, "Could not load image.");
  141. // Push the type.
  142. luax_newtype(L, "Image", GRAPHICS_IMAGE_T, (void*)image);
  143. return 1;
  144. }
  145. int w_newGlyph(lua_State * L)
  146. {
  147. love::font::GlyphData * data = luax_checktype<love::font::GlyphData>(L, 1, "GlyphData", FONT_GLYPH_DATA_T);
  148. // Create the image.
  149. Glyph * t = new Glyph(data);
  150. t->load();
  151. // Push the type.
  152. luax_newtype(L, "Glyph", GRAPHICS_GLYPH_T, (void*)t);
  153. return 1;
  154. }
  155. int w_newQuad(lua_State * L)
  156. {
  157. int x = luaL_checkint(L, 1);
  158. int y = luaL_checkint(L, 2);
  159. int w = luaL_checkint(L, 3);
  160. int h = luaL_checkint(L, 4);
  161. int sw = luaL_checkint(L, 5);
  162. int sh = luaL_checkint(L, 6);
  163. Quad * frame = instance->newQuad(x, y, w, h, sw, sh);
  164. if (frame == 0)
  165. return luaL_error(L, "Could not create frame.");
  166. luax_newtype(L, "Quad", GRAPHICS_QUAD_T, (void*)frame);
  167. return 1;
  168. }
  169. int w_newFont1(lua_State * L)
  170. {
  171. // Convert to File, if necessary.
  172. if(lua_isstring(L, 1))
  173. luax_convobj(L, 1, "filesystem", "newFile");
  174. // Convert to Data, if necessary.
  175. if(luax_istype(L, 1, FILESYSTEM_FILE_T)) {
  176. love::filesystem::File * f = luax_checktype<love::filesystem::File>(L, 1, "File", FILESYSTEM_FILE_T);
  177. Data * d = f->read();
  178. lua_remove(L, 1); // get rid of the file
  179. luax_newtype(L, "Data", DATA_T, (void*)d);
  180. lua_insert(L, 1); // put it at the bottom of the stack
  181. }
  182. // Convert to Rasterizer, if necessary.
  183. if(luax_istype(L, 1, DATA_T) && !luax_istype(L, 1, FONT_FONT_DATA_T)) {
  184. int idxs[] = {1, 2};
  185. luax_convobj(L, idxs, 2, "font", "newRasterizer");
  186. }
  187. // Convert to FontData, if necessary.
  188. if(luax_istype(L, 1, FONT_RASTERIZER_T))
  189. luax_convobj(L, 1, "font", "newFontData");
  190. love::font::FontData * data = luax_checktype<love::font::FontData>(L, 1, "FontData", FONT_FONT_DATA_T);
  191. // Create the font.
  192. Font * font = instance->newFont(data);
  193. if(font == 0)
  194. return luaL_error(L, "Could not load font.");
  195. // Push the type.
  196. luax_newtype(L, "Font", GRAPHICS_FONT_T, (void*)font);
  197. return 1;
  198. }
  199. int w_newImageFont(lua_State * L)
  200. {
  201. // Convert to ImageData if necessary.
  202. if(lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T) || (luax_istype(L, 1, DATA_T) && !luax_istype(L, 1, IMAGE_IMAGE_DATA_T) && !luax_istype(L, 1, FONT_FONT_DATA_T)))
  203. luax_convobj(L, 1, "image", "newImageData");
  204. else if(luax_istype(L, 1, GRAPHICS_IMAGE_T)) {
  205. Image * i = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  206. love::image::ImageData * id = i->getData();
  207. luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void*)id, false);
  208. lua_replace(L, 1);
  209. }
  210. // Convert to Rasterizer if necessary.
  211. if(luax_istype(L, 1, IMAGE_IMAGE_DATA_T)) {
  212. int idxs[] = {1, 2};
  213. luax_convobj(L, idxs, 2, "font", "newRasterizer");
  214. }
  215. // Convert to FontData, if necessary.
  216. if(luax_istype(L, 1, FONT_RASTERIZER_T))
  217. luax_convobj(L, 1, "font", "newFontData");
  218. love::font::FontData * data = luax_checktype<love::font::FontData>(L, 1, "FontData", FONT_FONT_DATA_T);
  219. // Create the font.
  220. Font * font = instance->newFont(data);
  221. if(font == 0)
  222. return luaL_error(L, "Could not load font.");
  223. // Push the type.
  224. luax_newtype(L, "Font", GRAPHICS_FONT_T, (void*)font);
  225. return 1;
  226. }
  227. int w_newSpriteBatch(lua_State * L)
  228. {
  229. Image * image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  230. int size = luaL_optint(L, 2, 1000);
  231. int usage = luaL_optint(L, 3, SpriteBatch::USAGE_DYNAMIC);
  232. SpriteBatch * t = instance->newSpriteBatch(image, size, usage);
  233. luax_newtype(L, "SpriteBatch", GRAPHICS_SPRITE_BATCH_T, (void*)t);
  234. return 1;
  235. }
  236. int w_newParticleSystem(lua_State * L)
  237. {
  238. Image * image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  239. int size = luaL_checkint(L, 2);
  240. ParticleSystem * t = instance->newParticleSystem(image, size);
  241. luax_newtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, (void*)t);
  242. return 1;
  243. }
  244. int w_newFramebuffer(lua_State * L)
  245. {
  246. // check if width and height are given. else default to screen dimensions.
  247. int width = luaL_optint(L, 1, instance->getWidth());
  248. int height = luaL_optint(L, 2, instance->getHeight());
  249. glGetError(); // clear opengl error flag
  250. Framebuffer * framebuffer = instance->newFramebuffer(width, height);
  251. //and there we go with the status... still disliked
  252. if (framebuffer->getStatus() != GL_FRAMEBUFFER_COMPLETE) {
  253. switch (framebuffer->getStatus()) {
  254. case GL_FRAMEBUFFER_UNSUPPORTED:
  255. return luaL_error(L, "Cannot create Framebuffer: "
  256. "Not supported by your OpenGL implementation");
  257. // remaining error codes are highly unlikely:
  258. case GL_FRAMEBUFFER_UNDEFINED:
  259. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
  260. case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
  261. case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
  262. case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
  263. case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
  264. return luaL_error(L, "Cannot create Framebuffer: "
  265. "Error in implementation (please inform the love devs)");
  266. default:
  267. // my intel hda card wrongly returns 0 to glCheckFramebufferStatus() but sets
  268. // no error flag. I think it meant to return GL_FRAMEBUFFER_UNSUPPORTED, but who
  269. // knows.
  270. if (glGetError() == GL_NO_ERROR)
  271. return luaL_error(L, "Cannot create Framebuffer: "
  272. "May not be supported by your OpenGL implementation.");
  273. // the remaining error is an indication of a serious fuckup since it should
  274. // only be returned if glCheckFramebufferStatus() was called with the wrong
  275. // arguments.
  276. return luaL_error(L, "Cannot create Framebuffer: Aliens did it (OpenGL error code: %d)", glGetError());
  277. }
  278. }
  279. luax_newtype(L, "Framebuffer", GRAPHICS_FRAMEBUFFER_T, (void*)framebuffer);
  280. return 1;
  281. }
  282. int w_setColor(lua_State * L)
  283. {
  284. Color c;
  285. if (lua_istable(L, 1)) {
  286. lua_pushinteger(L, 1);
  287. lua_gettable(L, -2);
  288. c.r = (unsigned char)luaL_checkint(L, -1);
  289. lua_pop(L, 1);
  290. lua_pushinteger(L, 2);
  291. lua_gettable(L, -2);
  292. c.g = (unsigned char)luaL_checkint(L, -1);
  293. lua_pop(L, 1);
  294. lua_pushinteger(L, 3);
  295. lua_gettable(L, -2);
  296. c.b = (unsigned char)luaL_checkint(L, -1);
  297. lua_pop(L, 1);
  298. lua_pushinteger(L, 4);
  299. lua_gettable(L, -2);
  300. c.a = (unsigned char)luaL_optint(L, -1, 255);
  301. lua_pop(L, 1);
  302. }
  303. else
  304. {
  305. c.r = (unsigned char)luaL_checkint(L, 1);
  306. c.g = (unsigned char)luaL_checkint(L, 2);
  307. c.b = (unsigned char)luaL_checkint(L, 3);
  308. c.a = (unsigned char)luaL_optint(L, 4, 255);
  309. }
  310. instance->setColor(c);
  311. return 0;
  312. }
  313. int w_getColor(lua_State * L)
  314. {
  315. Color c = instance->getColor();
  316. lua_pushinteger(L, c.r);
  317. lua_pushinteger(L, c.g);
  318. lua_pushinteger(L, c.b);
  319. lua_pushinteger(L, c.a);
  320. return 4;
  321. }
  322. int w_setBackgroundColor(lua_State * L)
  323. {
  324. Color c;
  325. c.r = (unsigned char)luaL_checkint(L, 1);
  326. c.g = (unsigned char)luaL_checkint(L, 2);
  327. c.b = (unsigned char)luaL_checkint(L, 3);
  328. c.a = 255;
  329. instance->setBackgroundColor(c);
  330. return 0;
  331. }
  332. int w_getBackgroundColor(lua_State * L)
  333. {
  334. Color c = instance->getBackgroundColor();
  335. lua_pushinteger(L, c.r);
  336. lua_pushinteger(L, c.g);
  337. lua_pushinteger(L, c.b);
  338. lua_pushinteger(L, c.a);
  339. return 4;
  340. }
  341. int w_setFont1(lua_State * L)
  342. {
  343. // The second parameter is an optional int.
  344. int size = luaL_optint(L, 2, 12);
  345. Font * font;
  346. bool created = false;
  347. // If the first parameter isn't a Font, create a new one
  348. if (!luax_istype(L, 1, GRAPHICS_FONT_T)) {
  349. created = true;
  350. lua_pushinteger(L, size); // push the size
  351. lua_insert(L, 2); // move it to its proper place
  352. // Convert to File, if necessary.
  353. if(lua_isstring(L, 1))
  354. luax_convobj(L, 1, "filesystem", "newFile");
  355. // Convert to Data, if necessary.
  356. if(luax_istype(L, 1, FILESYSTEM_FILE_T)) {
  357. love::filesystem::File * f = luax_checktype<love::filesystem::File>(L, 1, "File", FILESYSTEM_FILE_T);
  358. Data * d = f->read();
  359. lua_remove(L, 1); // get rid of the file
  360. luax_newtype(L, "Data", DATA_T, (void*)d);
  361. lua_insert(L, 1); // put it at the bottom of the stack
  362. }
  363. // Convert to Rasterizer, if necessary.
  364. if(luax_istype(L, 1, DATA_T) && !luax_istype(L, 1, FONT_FONT_DATA_T)) {
  365. int idxs[] = {1, 2};
  366. luax_convobj(L, idxs, 2, "font", "newRasterizer");
  367. }
  368. // Convert to FontData, if necessary.
  369. if(luax_istype(L, 1, FONT_RASTERIZER_T))
  370. luax_convobj(L, 1, "font", "newFontData");
  371. love::font::FontData * data = luax_checktype<love::font::FontData>(L, 1, "FontData", FONT_FONT_DATA_T);
  372. // Create the font.
  373. font = instance->newFont(data);
  374. if(font == 0)
  375. return luaL_error(L, "Could not load font.");
  376. }
  377. else font = luax_checktype<Font>(L, 1, "Font", GRAPHICS_FONT_T);
  378. instance->setFont(font);
  379. if (created)
  380. font->release();
  381. return 0;
  382. }
  383. int w_getFont(lua_State * L)
  384. {
  385. Font * f = instance->getFont();
  386. if(f == 0)
  387. return 0;
  388. f->retain();
  389. luax_newtype(L, "Font", GRAPHICS_FONT_T, (void*)f);
  390. return 1;
  391. }
  392. int w_setBlendMode(lua_State * L)
  393. {
  394. Graphics::BlendMode mode;
  395. const char * str = luaL_checkstring(L, 1);
  396. if(!Graphics::getConstant(str, mode))
  397. return luaL_error(L, "Invalid blend mode: %s", str);
  398. instance->setBlendMode(mode);
  399. return 0;
  400. }
  401. int w_setColorMode(lua_State * L)
  402. {
  403. Graphics::ColorMode mode;
  404. const char * str = luaL_checkstring(L, 1);
  405. if(!Graphics::getConstant(str, mode))
  406. return luaL_error(L, "Invalid color mode: %s", str);
  407. instance->setColorMode(mode);
  408. return 0;
  409. }
  410. int w_getBlendMode(lua_State * L)
  411. {
  412. Graphics::BlendMode mode = instance->getBlendMode();
  413. const char * str;
  414. if(!Graphics::getConstant(mode, str))
  415. return luaL_error(L, "Invalid blend mode: %s", str);
  416. lua_pushstring(L, str);
  417. return 1;
  418. }
  419. int w_getColorMode(lua_State * L)
  420. {
  421. Graphics::ColorMode mode = instance->getColorMode();
  422. const char * str;
  423. if(!Graphics::getConstant(mode, str))
  424. return luaL_error(L, "Invalid color mode: %s", str);
  425. lua_pushstring(L, str);
  426. return 1;
  427. }
  428. int w_setLineWidth(lua_State * L)
  429. {
  430. float width = (float)luaL_checknumber(L, 1);
  431. instance->setLineWidth(width);
  432. return 0;
  433. }
  434. int w_setLineStyle(lua_State * L)
  435. {
  436. Graphics::LineStyle style;
  437. const char * str = luaL_checkstring(L, 1);
  438. if(!Graphics::getConstant(str, style))
  439. return luaL_error(L, "Invalid line style: %s", str);
  440. instance->setLineStyle(style);
  441. return 0;
  442. }
  443. int w_setLine(lua_State * L)
  444. {
  445. float width = (float)luaL_checknumber(L, 1);
  446. Graphics::LineStyle style = Graphics::LINE_SMOOTH;
  447. if(lua_gettop(L) >= 2)
  448. {
  449. const char * str = luaL_checkstring(L, 2);
  450. if(!Graphics::getConstant(str, style))
  451. return luaL_error(L, "Invalid line style: %s", str);
  452. }
  453. instance->setLine(width, style);
  454. return 0;
  455. }
  456. int w_setLineStipple(lua_State * L)
  457. {
  458. if(lua_gettop(L) == 0)
  459. {
  460. instance->setLineStipple();
  461. return 0;
  462. }
  463. unsigned short pattern = (unsigned short)luaL_checkint(L, 1);
  464. int repeat = luaL_optint(L, 2, 1);
  465. instance->setLineStipple(pattern, repeat);
  466. return 0;
  467. }
  468. int w_getLineWidth(lua_State * L)
  469. {
  470. lua_pushnumber(L, instance->getLineWidth());
  471. return 1;
  472. }
  473. int w_getLineStyle(lua_State * L)
  474. {
  475. Graphics::LineStyle style = instance->getLineStyle();
  476. const char *str;
  477. Graphics::getConstant(style, str);
  478. lua_pushstring(L, str);
  479. return 1;
  480. }
  481. int w_getLineStipple(lua_State * L)
  482. {
  483. return instance->getLineStipple(L);
  484. }
  485. int w_setPointSize(lua_State * L)
  486. {
  487. float size = (float)luaL_checknumber(L, 1);
  488. instance->setPointSize(size);
  489. return 0;
  490. }
  491. int w_setPointStyle(lua_State * L)
  492. {
  493. Graphics::PointStyle style = Graphics::POINT_SMOOTH;
  494. if(lua_gettop(L) >= 2)
  495. {
  496. const char * str = luaL_checkstring(L, 1);
  497. if(!Graphics::getConstant(str, style))
  498. return luaL_error(L, "Invalid point style: %s", str);
  499. }
  500. instance->setPointStyle(style);
  501. return 0;
  502. }
  503. int w_setPoint(lua_State * L)
  504. {
  505. float size = (float)luaL_checknumber(L, 1);
  506. Graphics::PointStyle style;
  507. const char * str = luaL_checkstring(L, 2);
  508. if(!Graphics::getConstant(str, style))
  509. return luaL_error(L, "Invalid point style: %s", str);
  510. instance->setPoint(size, style);
  511. return 0;
  512. }
  513. int w_getPointSize(lua_State * L)
  514. {
  515. lua_pushnumber(L, instance->getPointSize());
  516. return 1;
  517. }
  518. int w_getPointStyle(lua_State * L)
  519. {
  520. lua_pushinteger(L, instance->getPointStyle());
  521. return 1;
  522. }
  523. int w_getMaxPointSize(lua_State * L)
  524. {
  525. lua_pushnumber(L, instance->getMaxPointSize());
  526. return 1;
  527. }
  528. int w_newScreenshot(lua_State * L)
  529. {
  530. love::image::Image * image = luax_getmodule<love::image::Image>(L, "image", MODULE_IMAGE_T);
  531. love::image::ImageData * i = instance->newScreenshot(image);
  532. luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)i);
  533. return 1;
  534. }
  535. int w_setRenderTarget(lua_State * L)
  536. {
  537. // called with nil or none -> reset to default buffer
  538. if (lua_isnoneornil(L,1)) {
  539. Framebuffer::bindDefaultBuffer();
  540. return 0;
  541. }
  542. Framebuffer * fbo = luax_checkfbo(L, 1);
  543. // this unbinds the previous fbo
  544. fbo->startGrab();
  545. return 0;
  546. }
  547. /**
  548. * Draws an Image at the specified coordinates, with rotation and
  549. * scaling along both axes.
  550. * @param x The x-coordinate.
  551. * @param y The y-coordinate.
  552. * @param angle The amount of rotation.
  553. * @param sx The scale factor along the x-axis. (1 = normal).
  554. * @param sy The scale factor along the y-axis. (1 = normal).
  555. * @param ox The offset along the x-axis.
  556. * @param oy The offset along the y-axis.
  557. **/
  558. int w_draw(lua_State * L)
  559. {
  560. Drawable * drawable = luax_checktype<Drawable>(L, 1, "Drawable", GRAPHICS_DRAWABLE_T);
  561. float x = (float)luaL_optnumber(L, 2, 0.0f);
  562. float y = (float)luaL_optnumber(L, 3, 0.0f);
  563. float angle = (float)luaL_optnumber(L, 4, 0.0f);
  564. float sx = (float)luaL_optnumber(L, 5, 1.0f);
  565. float sy = (float)luaL_optnumber(L, 6, sx);
  566. float ox = (float)luaL_optnumber(L, 7, 0);
  567. float oy = (float)luaL_optnumber(L, 8, 0);
  568. drawable->draw(x, y, angle, sx, sy, ox, oy);
  569. return 0;
  570. }
  571. /**
  572. * Draws an Quad of an Image at the specified coordinates,
  573. * with rotation and scaling along both axes.
  574. *
  575. * @param q The Quad to draw.
  576. * @param x The x-coordinate.
  577. * @param y The y-coordinate.
  578. * @param angle The amount of rotation.
  579. * @param sx The scale factor along the x-axis. (1 = normal).
  580. * @param sy The scale factor along the y-axis. (1 = normal).
  581. * @param ox The offset along the x-axis.
  582. * @param oy The offset along the y-axis.
  583. **/
  584. int w_drawq(lua_State * L)
  585. {
  586. Image * image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  587. Quad * q = luax_checkframe(L, 2);
  588. float x = (float)luaL_checknumber(L, 3);
  589. float y = (float)luaL_checknumber(L, 4);
  590. float angle = (float)luaL_optnumber(L, 5, 0);
  591. float sx = (float)luaL_optnumber(L, 6, 1);
  592. float sy = (float)luaL_optnumber(L, 7, sx);
  593. float ox = (float)luaL_optnumber(L, 8, 0);
  594. float oy = (float)luaL_optnumber(L, 9, 0);
  595. image->drawq(q, x, y, angle, sx, sy, ox, oy);
  596. return 0;
  597. }
  598. int w_drawTest(lua_State * L)
  599. {
  600. Image * image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  601. float x = (float)luaL_optnumber(L, 2, 0.0f);
  602. float y = (float)luaL_optnumber(L, 3, 0.0f);
  603. float angle = (float)luaL_optnumber(L, 4, 0.0f);
  604. float sx = (float)luaL_optnumber(L, 5, 1.0f);
  605. float sy = (float)luaL_optnumber(L, 6, sx);
  606. float ox = (float)luaL_optnumber(L, 7, 0);
  607. float oy = (float)luaL_optnumber(L, 8, 0);
  608. instance->drawTest(image, x, y, angle, sx, sy, ox, oy);
  609. return 0;
  610. }
  611. int w_print1(lua_State * L)
  612. {
  613. const char * str = luaL_checkstring(L, 1);
  614. float x = (float)luaL_checknumber(L, 2);
  615. float y = (float)luaL_checknumber(L, 3);
  616. float angle = (float)luaL_optnumber(L, 4, 0.0f);
  617. float sx = (float)luaL_optnumber(L, 5, 1.0f);
  618. float sy = (float)luaL_optnumber(L, 6, sx);
  619. switch(lua_gettop(L))
  620. {
  621. case 3:
  622. instance->print(str, x, y);
  623. break;
  624. case 4:
  625. instance->print(str, x, y, angle);
  626. break;
  627. case 5:
  628. instance->print(str, x, y, angle, sx);
  629. break;
  630. case 6:
  631. instance->print(str, x, y, angle, sx, sy);
  632. break;
  633. default:
  634. return luaL_error(L, "Incorrect number of parameters");
  635. }
  636. return 0;
  637. }
  638. int w_printf1(lua_State * L)
  639. {
  640. const char * str = luaL_checkstring(L, 1);
  641. float x = (float)luaL_checknumber(L, 2);
  642. float y = (float)luaL_checknumber(L, 3);
  643. float wrap = (float)luaL_checknumber(L, 4);
  644. Graphics::AlignMode align = Graphics::ALIGN_LEFT;
  645. if(lua_gettop(L) >= 5)
  646. {
  647. const char * str = luaL_checkstring(L, 5);
  648. if(!Graphics::getConstant(str, align))
  649. return luaL_error(L, "Incorrect alignment: %s", str);
  650. }
  651. instance->printf(str, x, y, wrap, align);
  652. return 0;
  653. }
  654. int w_point(lua_State * L)
  655. {
  656. float x = (float)luaL_checknumber(L, 1);
  657. float y = (float)luaL_checknumber(L, 2);
  658. instance->point(x, y);
  659. return 0;
  660. }
  661. int w_line(lua_State * L)
  662. {
  663. int args = lua_gettop(L);
  664. if( args == 1 || args > 4) {
  665. instance->polyline(L);
  666. } else {
  667. float x1 = (float)luaL_checknumber(L, 1);
  668. float y1 = (float)luaL_checknumber(L, 2);
  669. float x2 = (float)luaL_checknumber(L, 3);
  670. float y2 = (float)luaL_checknumber(L, 4);
  671. instance->line(x1, y1, x2, y2);
  672. }
  673. return 0;
  674. }
  675. int w_triangle(lua_State * L)
  676. {
  677. Graphics::DrawMode mode;
  678. const char * str = luaL_checkstring(L, 1);
  679. if(!Graphics::getConstant(str, mode))
  680. return luaL_error(L, "Incorrect draw mode %s", str);
  681. float x1 = (float)luaL_checknumber(L, 2);
  682. float y1 = (float)luaL_checknumber(L, 3);
  683. float x2 = (float)luaL_checknumber(L, 4);
  684. float y2 = (float)luaL_checknumber(L, 5);
  685. float x3 = (float)luaL_checknumber(L, 6);
  686. float y3 = (float)luaL_checknumber(L, 7);
  687. instance->triangle(mode, x1, y1, x2, y2, x3, y3);
  688. return 0;
  689. }
  690. int w_rectangle(lua_State * L)
  691. {
  692. Graphics::DrawMode mode;
  693. const char * str = luaL_checkstring(L, 1);
  694. if(!Graphics::getConstant(str, mode))
  695. return luaL_error(L, "Incorrect draw mode %s", str);
  696. float x = (float)luaL_checknumber(L, 2);
  697. float y = (float)luaL_checknumber(L, 3);
  698. float w = (float)luaL_checknumber(L, 4);
  699. float h = (float)luaL_checknumber(L, 5);
  700. instance->rectangle(mode, x, y, w, h);
  701. return 0;
  702. }
  703. int w_quad(lua_State * L)
  704. {
  705. Graphics::DrawMode mode;
  706. const char * str = luaL_checkstring(L, 1);
  707. if(!Graphics::getConstant(str, mode))
  708. return luaL_error(L, "Incorrect draw mode %s", str);
  709. float x1 = (float)luaL_checknumber(L, 2);
  710. float y1 = (float)luaL_checknumber(L, 3);
  711. float x2 = (float)luaL_checknumber(L, 4);
  712. float y2 = (float)luaL_checknumber(L, 5);
  713. float x3 = (float)luaL_checknumber(L, 6);
  714. float y3 = (float)luaL_checknumber(L, 7);
  715. float x4 = (float)luaL_checknumber(L, 8);
  716. float y4 = (float)luaL_checknumber(L, 9);
  717. instance->quad(mode, x1, y1, x2, y2, x3, y3, x4, y4);
  718. return 0;
  719. }
  720. int w_circle(lua_State * L)
  721. {
  722. Graphics::DrawMode mode;
  723. const char * str = luaL_checkstring(L, 1);
  724. if(!Graphics::getConstant(str, mode))
  725. return luaL_error(L, "Incorrect draw mode %s", str);
  726. float x = (float)luaL_checknumber(L, 2);
  727. float y = (float)luaL_checknumber(L, 3);
  728. float radius = (float)luaL_checknumber(L, 4);
  729. int points = luaL_optint(L, 5, 10);
  730. instance->circle(mode, x, y, radius, points);
  731. return 0;
  732. }
  733. int w_polygon(lua_State * L)
  734. {
  735. return instance->polygon(L);
  736. }
  737. int w_push(lua_State *)
  738. {
  739. instance->push();
  740. return 0;
  741. }
  742. int w_pop(lua_State *)
  743. {
  744. instance->pop();
  745. return 0;
  746. }
  747. int w_rotate(lua_State * L)
  748. {
  749. float deg = (float)luaL_checknumber(L, 1);
  750. instance->rotate(deg);
  751. return 0;
  752. }
  753. int w_scale(lua_State * L)
  754. {
  755. float sx = (float)luaL_optnumber(L, 1, 1.0f);
  756. float sy = (float)luaL_optnumber(L, 2, sx);
  757. instance->scale(sx, sy);
  758. return 0;
  759. }
  760. int w_translate(lua_State * L)
  761. {
  762. float x = (float)luaL_checknumber(L, 1);
  763. float y = (float)luaL_checknumber(L, 2);
  764. instance->translate(x, y);
  765. return 0;
  766. }
  767. // List of functions to wrap.
  768. static const luaL_Reg functions[] = {
  769. { "checkMode", w_checkMode },
  770. { "setMode", w_setMode },
  771. { "toggleFullscreen", w_toggleFullscreen },
  772. { "reset", w_reset },
  773. { "clear", w_clear },
  774. { "present", w_present },
  775. { "newImage", w_newImage },
  776. { "newGlyph", w_newGlyph },
  777. { "newQuad", w_newQuad },
  778. { "newFont1", w_newFont1 },
  779. { "newImageFont", w_newImageFont },
  780. { "newSpriteBatch", w_newSpriteBatch },
  781. { "newParticleSystem", w_newParticleSystem },
  782. { "newFramebuffer", w_newFramebuffer },
  783. { "setColor", w_setColor },
  784. { "getColor", w_getColor },
  785. { "setBackgroundColor", w_setBackgroundColor },
  786. { "getBackgroundColor", w_getBackgroundColor },
  787. { "setFont1", w_setFont1 },
  788. { "getFont", w_getFont },
  789. { "setBlendMode", w_setBlendMode },
  790. { "setColorMode", w_setColorMode },
  791. { "getBlendMode", w_getBlendMode },
  792. { "getColorMode", w_getColorMode },
  793. { "setLineWidth", w_setLineWidth },
  794. { "setLineStyle", w_setLineStyle },
  795. { "setLine", w_setLine },
  796. { "setLineStipple", w_setLineStipple },
  797. { "getLineWidth", w_getLineWidth },
  798. { "getLineStyle", w_getLineStyle },
  799. { "getLineStipple", w_getLineStipple },
  800. { "setPointSize", w_setPointSize },
  801. { "setPointStyle", w_setPointStyle },
  802. { "setPoint", w_setPoint },
  803. { "getPointSize", w_getPointSize },
  804. { "getPointStyle", w_getPointStyle },
  805. { "getMaxPointSize", w_getMaxPointSize },
  806. { "newScreenshot", w_newScreenshot },
  807. { "setRenderTarget", w_setRenderTarget },
  808. { "draw", w_draw },
  809. { "drawq", w_drawq },
  810. { "drawTest", w_drawTest },
  811. { "print1", w_print1 },
  812. { "printf1", w_printf1 },
  813. { "setCaption", w_setCaption },
  814. { "getCaption", w_getCaption },
  815. { "setIcon", w_setIcon },
  816. { "getWidth", w_getWidth },
  817. { "getHeight", w_getHeight },
  818. { "isCreated", w_isCreated },
  819. { "getModes", w_getModes },
  820. { "setScissor", w_setScissor },
  821. { "getScissor", w_getScissor },
  822. { "point", w_point },
  823. { "line", w_line },
  824. { "triangle", w_triangle },
  825. { "rectangle", w_rectangle },
  826. { "quad", w_quad },
  827. { "circle", w_circle },
  828. { "polygon", w_polygon },
  829. { "push", w_push },
  830. { "pop", w_pop },
  831. { "rotate", w_rotate },
  832. { "scale", w_scale },
  833. { "translate", w_translate },
  834. { 0, 0 }
  835. };
  836. // Types for this module.
  837. static const lua_CFunction types[] = {
  838. luaopen_font,
  839. luaopen_image,
  840. luaopen_glyph,
  841. luaopen_frame,
  842. luaopen_spritebatch,
  843. luaopen_particlesystem,
  844. luaopen_framebuffer,
  845. 0
  846. };
  847. int luaopen_love_graphics(lua_State * L)
  848. {
  849. if(instance == 0)
  850. {
  851. try
  852. {
  853. instance = new Graphics();
  854. }
  855. catch(Exception & e)
  856. {
  857. return luaL_error(L, e.what());
  858. }
  859. }
  860. else
  861. instance->retain();
  862. WrappedModule w;
  863. w.module = instance;
  864. w.name = "graphics";
  865. w.flags = MODULE_T;
  866. w.functions = functions;
  867. w.types = types;
  868. luax_register_module(L, w);
  869. if (luaL_loadbuffer(L, (const char *)graphics_lua, sizeof(graphics_lua), "graphics.lua") == 0)
  870. lua_call(L, 0, 0);
  871. return 0;
  872. }
  873. } // opengl
  874. } // graphics
  875. } // love