2
0

wrap_Graphics.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376
  1. /**
  2. * Copyright (c) 2006-2012 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 "GLee.h"
  22. #include "graphics/DrawQable.h"
  23. #include "image/ImageData.h"
  24. #include "font/Rasterizer.h"
  25. #include "scripts/graphics.lua.h"
  26. #include <cassert>
  27. namespace love
  28. {
  29. namespace graphics
  30. {
  31. namespace opengl
  32. {
  33. static Graphics *instance = 0;
  34. int w_checkMode(lua_State *L)
  35. {
  36. int w = luaL_checkint(L, 1);
  37. int h = luaL_checkint(L, 2);
  38. bool fs = luax_toboolean(L, 3);
  39. luax_pushboolean(L, instance->checkMode(w, h, fs));
  40. return 1;
  41. }
  42. int w_setMode(lua_State *L)
  43. {
  44. int w = luaL_checkint(L, 1);
  45. int h = luaL_checkint(L, 2);
  46. bool fs = luax_optboolean(L, 3, false);
  47. bool vsync = luax_optboolean(L, 4, true);
  48. int fsaa = luaL_optint(L, 5, 0);
  49. luax_pushboolean(L, instance->setMode(w, h, fs, vsync, fsaa));
  50. return 1;
  51. }
  52. int w_getMode(lua_State *L)
  53. {
  54. int w, h, fsaa;
  55. bool fs, vsync;
  56. instance->getMode(w, h, fs, vsync, fsaa);
  57. lua_pushnumber(L, w);
  58. lua_pushnumber(L, h);
  59. lua_pushboolean(L, fs);
  60. lua_pushboolean(L, vsync);
  61. lua_pushnumber(L, fsaa);
  62. return 5;
  63. }
  64. int w_toggleFullscreen(lua_State *L)
  65. {
  66. luax_pushboolean(L, instance->toggleFullscreen());
  67. return 1;
  68. }
  69. int w_reset(lua_State *)
  70. {
  71. instance->reset();
  72. return 0;
  73. }
  74. int w_clear(lua_State *)
  75. {
  76. instance->clear();
  77. return 0;
  78. }
  79. int w_present(lua_State *)
  80. {
  81. instance->present();
  82. return 0;
  83. }
  84. int w_setIcon(lua_State *L)
  85. {
  86. Image *image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  87. instance->setIcon(image);
  88. return 0;
  89. }
  90. int w_setCaption(lua_State *L)
  91. {
  92. const char *str = luaL_checkstring(L, 1);
  93. instance->setCaption(str);
  94. return 0;
  95. }
  96. int w_getCaption(lua_State *L)
  97. {
  98. return instance->getCaption(L);
  99. }
  100. int w_getWidth(lua_State *L)
  101. {
  102. lua_pushnumber(L, instance->getWidth());
  103. return 1;
  104. }
  105. int w_getHeight(lua_State *L)
  106. {
  107. lua_pushnumber(L, instance->getHeight());
  108. return 1;
  109. }
  110. int w_isCreated(lua_State *L)
  111. {
  112. luax_pushboolean(L, instance->isCreated());
  113. return 1;
  114. }
  115. int w_getModes(lua_State *L)
  116. {
  117. return instance->getModes(L);
  118. }
  119. int w_setScissor(lua_State *L)
  120. {
  121. if (lua_gettop(L) == 0)
  122. {
  123. instance->setScissor();
  124. return 0;
  125. }
  126. int x = luaL_checkint(L, 1);
  127. int y = luaL_checkint(L, 2);
  128. int w = luaL_checkint(L, 3);
  129. int h = luaL_checkint(L, 4);
  130. if (w < 0 || h < 0)
  131. return luaL_error(L, "Can't set scissor with negative width and/or height.");
  132. instance->setScissor(x, y, w, h);
  133. return 0;
  134. }
  135. int w_getScissor(lua_State *L)
  136. {
  137. return instance->getScissor(L);
  138. }
  139. int w_newStencil(lua_State *L)
  140. {
  141. // just return the function
  142. if (!lua_isfunction(L, 1))
  143. return luaL_typerror(L, 1, "function");
  144. lua_settop(L, 1);
  145. return 1;
  146. }
  147. static int setStencil(lua_State *L, bool invert)
  148. {
  149. // no argument -> clear mask
  150. if (lua_isnoneornil(L, 1))
  151. {
  152. instance->discardStencil();
  153. return 0;
  154. }
  155. if (!lua_isfunction(L, 1))
  156. return luaL_typerror(L, 1, "mask");
  157. instance->defineStencil();
  158. lua_call(L, lua_gettop(L) - 1, 0); // call mask(...)
  159. instance->useStencil(invert);
  160. return 0;
  161. }
  162. int w_setStencil(lua_State *L)
  163. {
  164. return setStencil(L, false);
  165. }
  166. int w_setInvertedStencil(lua_State *L)
  167. {
  168. return setStencil(L, true);
  169. }
  170. int w_newImage(lua_State *L)
  171. {
  172. // Convert to File, if necessary.
  173. if (lua_isstring(L, 1))
  174. luax_convobj(L, 1, "filesystem", "newFile");
  175. // Convert to ImageData, if necessary.
  176. if (luax_istype(L, 1, FILESYSTEM_FILE_T))
  177. luax_convobj(L, 1, "image", "newImageData");
  178. love::image::ImageData *data = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
  179. // Create the image.
  180. Image *image = 0;
  181. try
  182. {
  183. image = instance->newImage(data);
  184. }
  185. catch(love::Exception &e)
  186. {
  187. luaL_error(L, e.what());
  188. }
  189. if (image == 0)
  190. return luaL_error(L, "Could not load image.");
  191. // Push the type.
  192. luax_newtype(L, "Image", GRAPHICS_IMAGE_T, (void *)image);
  193. return 1;
  194. }
  195. int w_newQuad(lua_State *L)
  196. {
  197. float x = (float) luaL_checknumber(L, 1);
  198. float y = (float) luaL_checknumber(L, 2);
  199. float w = (float) luaL_checknumber(L, 3);
  200. float h = (float) luaL_checknumber(L, 4);
  201. float sw = (float) luaL_checknumber(L, 5);
  202. float sh = (float) luaL_checknumber(L, 6);
  203. Quad *frame = instance->newQuad(x, y, w, h, sw, sh);
  204. if (frame == 0)
  205. return luaL_error(L, "Could not create frame.");
  206. luax_newtype(L, "Quad", GRAPHICS_QUAD_T, (void *)frame);
  207. return 1;
  208. }
  209. int w_newFont(lua_State *L)
  210. {
  211. Data *font_data = NULL;
  212. // Convert to File, if necessary.
  213. if (lua_isstring(L, 1))
  214. luax_convobj(L, 1, "filesystem", "newFile");
  215. // Convert to Data, if necessary.
  216. if (luax_istype(L, 1, FILESYSTEM_FILE_T))
  217. {
  218. love::filesystem::File *f = luax_checktype<love::filesystem::File>(L, 1, "File", FILESYSTEM_FILE_T);
  219. try
  220. {
  221. font_data = f->read();
  222. }
  223. catch(love::Exception &e)
  224. {
  225. return luaL_error(L, e.what());
  226. }
  227. lua_remove(L, 1); // get rid of the file
  228. luax_newtype(L, "Data", DATA_T, (void *)font_data);
  229. lua_insert(L, 1); // put it at the bottom of the stack
  230. }
  231. // Convert to Rasterizer, if necessary.
  232. if (luax_istype(L, 1, DATA_T))
  233. {
  234. int idxs[] = {1, 2};
  235. luax_convobj(L, idxs, 2, "font", "newRasterizer");
  236. }
  237. if (font_data)
  238. font_data->release();
  239. love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
  240. // Create the font.
  241. Font *font = instance->newFont(rasterizer, instance->getDefaultImageFilter());
  242. if (font == 0)
  243. return luaL_error(L, "Could not load font.");
  244. // Push the type.
  245. luax_newtype(L, "Font", GRAPHICS_FONT_T, (void *)font);
  246. return 1;
  247. }
  248. int w_newImageFont(lua_State *L)
  249. {
  250. // filter for glyphs, defaults to linear/linear
  251. Image::Filter img_filter;
  252. bool setFilter = false;
  253. // For the filter modes..
  254. int startIndex = 2;
  255. // Convert to ImageData if necessary.
  256. 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)))
  257. luax_convobj(L, 1, "image", "newImageData");
  258. else if (luax_istype(L, 1, GRAPHICS_IMAGE_T))
  259. {
  260. Image *i = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  261. img_filter = i->getFilter();
  262. setFilter = true;
  263. love::image::ImageData *id = i->getData();
  264. luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)id, false);
  265. lua_replace(L, 1);
  266. }
  267. // Convert to Rasterizer if necessary.
  268. if (luax_istype(L, 1, IMAGE_IMAGE_DATA_T))
  269. {
  270. int idxs[] = {1, 2};
  271. luax_convobj(L, idxs, 2, "font", "newRasterizer");
  272. startIndex = 3; // There's a glyphs args in there, move up
  273. }
  274. love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
  275. if (lua_isstring(L, startIndex) && lua_isstring(L, startIndex+1))
  276. {
  277. Image::FilterMode min;
  278. Image::FilterMode mag;
  279. const char *minstr = luaL_checkstring(L, startIndex);
  280. const char *magstr = luaL_checkstring(L, startIndex+1);
  281. if (!Image::getConstant(minstr, min))
  282. return luaL_error(L, "Invalid filter mode: %s", minstr);
  283. if (!Image::getConstant(magstr, mag))
  284. return luaL_error(L, "Invalid filter mode: %s", magstr);
  285. img_filter.min = min;
  286. img_filter.mag = mag;
  287. setFilter = true;
  288. }
  289. if (!setFilter)
  290. img_filter = instance->getDefaultImageFilter();
  291. // Create the font.
  292. Font *font = instance->newFont(rasterizer, img_filter);
  293. if (font == 0)
  294. return luaL_error(L, "Could not load font.");
  295. // Push the type.
  296. luax_newtype(L, "Font", GRAPHICS_FONT_T, (void *)font);
  297. return 1;
  298. }
  299. int w_newSpriteBatch(lua_State *L)
  300. {
  301. Image *image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  302. int size = luaL_optint(L, 2, 1000);
  303. SpriteBatch::UsageHint usage = SpriteBatch::USAGE_DYNAMIC;
  304. if (lua_gettop(L) > 2)
  305. {
  306. if (!SpriteBatch::getConstant(luaL_checkstring(L, 3), usage))
  307. usage = SpriteBatch::USAGE_DYNAMIC;
  308. }
  309. SpriteBatch *t = NULL;
  310. try
  311. {
  312. t = instance->newSpriteBatch(image, size, usage);
  313. }
  314. catch(love::Exception &e)
  315. {
  316. return luaL_error(L, e.what());
  317. }
  318. luax_newtype(L, "SpriteBatch", GRAPHICS_SPRITE_BATCH_T, (void *)t);
  319. return 1;
  320. }
  321. int w_newParticleSystem(lua_State *L)
  322. {
  323. Image *image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  324. int size = luaL_checkint(L, 2);
  325. ParticleSystem *t = instance->newParticleSystem(image, size);
  326. luax_newtype(L, "ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_T, (void *)t);
  327. return 1;
  328. }
  329. int w_newCanvas(lua_State *L)
  330. {
  331. // check if width and height are given. else default to screen dimensions.
  332. int width = luaL_optint(L, 1, instance->getWidth());
  333. int height = luaL_optint(L, 2, instance->getHeight());
  334. const char *str = luaL_optstring(L, 3, "normal");
  335. Canvas::TextureType texture_type;
  336. if (!Canvas::getConstant(str, texture_type))
  337. return luaL_error(L, "Invalid canvas type: %s", str);
  338. Canvas *canvas = NULL;
  339. try
  340. {
  341. canvas = instance->newCanvas(width, height, texture_type);
  342. }
  343. catch(Exception &e)
  344. {
  345. return luaL_error(L, e.what());
  346. }
  347. if (NULL == canvas)
  348. return luaL_error(L, "Canvas not created, but no error thrown. I don't even...");
  349. luax_newtype(L, "Canvas", GRAPHICS_CANVAS_T, (void *)canvas);
  350. return 1;
  351. }
  352. int w_newPixelEffect(lua_State *L)
  353. {
  354. if (!PixelEffect::isSupported())
  355. return luaL_error(L, "Sorry, your graphics card does not support pixel effects.");
  356. try
  357. {
  358. luaL_checkstring(L, 1);
  359. luax_getfunction(L, "graphics", "_effectCodeToGLSL");
  360. lua_pushvalue(L, 1);
  361. lua_pcall(L, 1, 1, 0);
  362. const char *code = lua_tostring(L, -1);
  363. PixelEffect *effect = instance->newPixelEffect(code);
  364. luax_newtype(L, "PixelEffect", GRAPHICS_PIXELEFFECT_T, (void *)effect);
  365. }
  366. catch(const love::Exception &e)
  367. {
  368. // memory is freed in Graphics::newPixelEffect
  369. luax_getfunction(L, "graphics", "_transformGLSLErrorMessages");
  370. lua_pushstring(L, e.what());
  371. lua_pcall(L, 1,1, 0);
  372. const char *err = lua_tostring(L, -1);
  373. return luaL_error(L, "%s", err);
  374. }
  375. return 1;
  376. }
  377. int w_setColor(lua_State *L)
  378. {
  379. Color c;
  380. if (lua_istable(L, 1))
  381. {
  382. lua_pushinteger(L, 1);
  383. lua_gettable(L, -2);
  384. c.r = (unsigned char)luaL_checkint(L, -1);
  385. lua_pop(L, 1);
  386. lua_pushinteger(L, 2);
  387. lua_gettable(L, -2);
  388. c.g = (unsigned char)luaL_checkint(L, -1);
  389. lua_pop(L, 1);
  390. lua_pushinteger(L, 3);
  391. lua_gettable(L, -2);
  392. c.b = (unsigned char)luaL_checkint(L, -1);
  393. lua_pop(L, 1);
  394. lua_pushinteger(L, 4);
  395. lua_gettable(L, -2);
  396. c.a = (unsigned char)luaL_optint(L, -1, 255);
  397. lua_pop(L, 1);
  398. }
  399. else
  400. {
  401. c.r = (unsigned char)luaL_checkint(L, 1);
  402. c.g = (unsigned char)luaL_checkint(L, 2);
  403. c.b = (unsigned char)luaL_checkint(L, 3);
  404. c.a = (unsigned char)luaL_optint(L, 4, 255);
  405. }
  406. instance->setColor(c);
  407. return 0;
  408. }
  409. int w_getColor(lua_State *L)
  410. {
  411. Color c = instance->getColor();
  412. lua_pushinteger(L, c.r);
  413. lua_pushinteger(L, c.g);
  414. lua_pushinteger(L, c.b);
  415. lua_pushinteger(L, c.a);
  416. return 4;
  417. }
  418. int w_setBackgroundColor(lua_State *L)
  419. {
  420. Color c;
  421. if (lua_istable(L, 1))
  422. {
  423. lua_pushinteger(L, 1);
  424. lua_gettable(L, -2);
  425. c.r = (unsigned char)luaL_checkint(L, -1);
  426. lua_pop(L, 1);
  427. lua_pushinteger(L, 2);
  428. lua_gettable(L, -2);
  429. c.g = (unsigned char)luaL_checkint(L, -1);
  430. lua_pop(L, 1);
  431. lua_pushinteger(L, 3);
  432. lua_gettable(L, -2);
  433. c.b = (unsigned char)luaL_checkint(L, -1);
  434. lua_pop(L, 1);
  435. lua_pushinteger(L, 4);
  436. lua_gettable(L, -2);
  437. c.a = (unsigned char)luaL_optint(L, -1, 255);
  438. lua_pop(L, 1);
  439. }
  440. else
  441. {
  442. c.r = (unsigned char)luaL_checkint(L, 1);
  443. c.g = (unsigned char)luaL_checkint(L, 2);
  444. c.b = (unsigned char)luaL_checkint(L, 3);
  445. c.a = (unsigned char)luaL_optint(L, 4, 255);
  446. }
  447. instance->setBackgroundColor(c);
  448. return 0;
  449. }
  450. int w_getBackgroundColor(lua_State *L)
  451. {
  452. Color c = instance->getBackgroundColor();
  453. lua_pushinteger(L, c.r);
  454. lua_pushinteger(L, c.g);
  455. lua_pushinteger(L, c.b);
  456. lua_pushinteger(L, c.a);
  457. return 4;
  458. }
  459. int w_setFont(lua_State *L)
  460. {
  461. Font *font = luax_checktype<Font>(L, 1, "Font", GRAPHICS_FONT_T);
  462. instance->setFont(font);
  463. return 0;
  464. }
  465. int w_getFont(lua_State *L)
  466. {
  467. Font *f = instance->getFont();
  468. if (f == 0)
  469. return 0;
  470. f->retain();
  471. luax_newtype(L, "Font", GRAPHICS_FONT_T, (void *)f);
  472. return 1;
  473. }
  474. int w_setBlendMode(lua_State *L)
  475. {
  476. Graphics::BlendMode mode;
  477. const char *str = luaL_checkstring(L, 1);
  478. if (!Graphics::getConstant(str, mode))
  479. return luaL_error(L, "Invalid blend mode: %s", str);
  480. try
  481. {
  482. instance->setBlendMode(mode);
  483. }
  484. catch(love::Exception &e)
  485. {
  486. return luaL_error(L, e.what());
  487. }
  488. return 0;
  489. }
  490. int w_setColorMode(lua_State *L)
  491. {
  492. Graphics::ColorMode mode;
  493. const char *str = luaL_checkstring(L, 1);
  494. if (!Graphics::getConstant(str, mode))
  495. return luaL_error(L, "Invalid color mode: %s", str);
  496. instance->setColorMode(mode);
  497. return 0;
  498. }
  499. int w_setDefaultImageFilter(lua_State *L)
  500. {
  501. Image::FilterMode min;
  502. Image::FilterMode mag;
  503. const char *minstr = luaL_checkstring(L, 1);
  504. const char *magstr = luaL_optstring(L, 2, minstr);
  505. if (!Image::getConstant(minstr, min))
  506. return luaL_error(L, "Invalid filter mode: %s", minstr);
  507. if (!Image::getConstant(magstr, mag))
  508. return luaL_error(L, "Invalid filter mode: %s", magstr);
  509. Image::Filter f;
  510. f.min = min;
  511. f.mag = mag;
  512. instance->setDefaultImageFilter(f);
  513. return 0;
  514. }
  515. int w_getBlendMode(lua_State *L)
  516. {
  517. Graphics::BlendMode mode = instance->getBlendMode();
  518. const char *str;
  519. if (!Graphics::getConstant(mode, str))
  520. return luaL_error(L, "Invalid blend mode: %s", str);
  521. lua_pushstring(L, str);
  522. return 1;
  523. }
  524. int w_getColorMode(lua_State *L)
  525. {
  526. Graphics::ColorMode mode = instance->getColorMode();
  527. const char *str;
  528. if (!Graphics::getConstant(mode, str))
  529. return luaL_error(L, "Invalid color mode: %s", str);
  530. lua_pushstring(L, str);
  531. return 1;
  532. }
  533. int w_getDefaultImageFilter(lua_State *L)
  534. {
  535. const Image::Filter &f = instance->getDefaultImageFilter();
  536. const char *minstr;
  537. const char *magstr;
  538. Image::getConstant(f.min, minstr);
  539. Image::getConstant(f.mag, magstr);
  540. lua_pushstring(L, minstr);
  541. lua_pushstring(L, magstr);
  542. return 2;
  543. }
  544. int w_setLineWidth(lua_State *L)
  545. {
  546. float width = (float)luaL_checknumber(L, 1);
  547. instance->setLineWidth(width);
  548. return 0;
  549. }
  550. int w_setLineStyle(lua_State *L)
  551. {
  552. Graphics::LineStyle style;
  553. const char *str = luaL_checkstring(L, 1);
  554. if (!Graphics::getConstant(str, style))
  555. return luaL_error(L, "Invalid line style: %s", str);
  556. instance->setLineStyle(style);
  557. return 0;
  558. }
  559. int w_setLine(lua_State *L)
  560. {
  561. float width = (float)luaL_checknumber(L, 1);
  562. Graphics::LineStyle style = Graphics::LINE_SMOOTH;
  563. if (lua_gettop(L) >= 2)
  564. {
  565. const char *str = luaL_checkstring(L, 2);
  566. if (!Graphics::getConstant(str, style))
  567. return luaL_error(L, "Invalid line style: %s", str);
  568. }
  569. instance->setLine(width, style);
  570. return 0;
  571. }
  572. int w_getLineWidth(lua_State *L)
  573. {
  574. lua_pushnumber(L, instance->getLineWidth());
  575. return 1;
  576. }
  577. int w_getLineStyle(lua_State *L)
  578. {
  579. Graphics::LineStyle style = instance->getLineStyle();
  580. const char *str;
  581. Graphics::getConstant(style, str);
  582. lua_pushstring(L, str);
  583. return 1;
  584. }
  585. int w_setPointSize(lua_State *L)
  586. {
  587. float size = (float)luaL_checknumber(L, 1);
  588. instance->setPointSize(size);
  589. return 0;
  590. }
  591. int w_setPointStyle(lua_State *L)
  592. {
  593. Graphics::PointStyle style = Graphics::POINT_SMOOTH;
  594. if (lua_gettop(L) >= 2)
  595. {
  596. const char *str = luaL_checkstring(L, 1);
  597. if (!Graphics::getConstant(str, style))
  598. return luaL_error(L, "Invalid point style: %s", str);
  599. }
  600. instance->setPointStyle(style);
  601. return 0;
  602. }
  603. int w_setPoint(lua_State *L)
  604. {
  605. float size = (float)luaL_checknumber(L, 1);
  606. Graphics::PointStyle style;
  607. const char *str = luaL_checkstring(L, 2);
  608. if (!Graphics::getConstant(str, style))
  609. return luaL_error(L, "Invalid point style: %s", str);
  610. instance->setPoint(size, style);
  611. return 0;
  612. }
  613. int w_getPointSize(lua_State *L)
  614. {
  615. lua_pushnumber(L, instance->getPointSize());
  616. return 1;
  617. }
  618. int w_getPointStyle(lua_State *L)
  619. {
  620. lua_pushinteger(L, instance->getPointStyle());
  621. return 1;
  622. }
  623. int w_getMaxPointSize(lua_State *L)
  624. {
  625. lua_pushnumber(L, instance->getMaxPointSize());
  626. return 1;
  627. }
  628. int w_newScreenshot(lua_State *L)
  629. {
  630. love::image::Image *image = luax_getmodule<love::image::Image>(L, "image", MODULE_IMAGE_T);
  631. love::image::ImageData *i = instance->newScreenshot(image);
  632. luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)i);
  633. return 1;
  634. }
  635. int w_setCanvas(lua_State *L)
  636. {
  637. // discard stencil testing
  638. instance->discardStencil();
  639. // called with none -> reset to default buffer
  640. // nil is an error, to help people with typoes
  641. if (lua_isnone(L,1))
  642. {
  643. Canvas::bindDefaultCanvas();
  644. return 0;
  645. }
  646. Canvas *canvas = luax_checkcanvas(L, 1);
  647. // this unbinds the previous fbo
  648. canvas->startGrab();
  649. return 0;
  650. }
  651. int w_getCanvas(lua_State *L)
  652. {
  653. Canvas *canvas = Canvas::current;
  654. if (canvas)
  655. {
  656. canvas->retain();
  657. luax_newtype(L, "Canvas", GRAPHICS_CANVAS_T, (void *) canvas);
  658. }
  659. else
  660. lua_pushnil(L);
  661. return 1;
  662. }
  663. int w_setPixelEffect(lua_State *L)
  664. {
  665. if (lua_isnoneornil(L,1))
  666. {
  667. PixelEffect::detach();
  668. return 0;
  669. }
  670. PixelEffect *effect = luax_checkpixeleffect(L, 1);
  671. effect->attach();
  672. return 0;
  673. }
  674. int w_getPixelEffect(lua_State *L)
  675. {
  676. PixelEffect *effect = PixelEffect::current;
  677. if (effect)
  678. {
  679. effect->retain();
  680. luax_newtype(L, "PixelEffect", GRAPHICS_PIXELEFFECT_T, (void *) effect);
  681. }
  682. else
  683. lua_pushnil(L);
  684. return 1;
  685. }
  686. int w_isSupported(lua_State *L)
  687. {
  688. bool supported = true;
  689. size_t len = lua_gettop(L);
  690. Graphics::Support support;
  691. for (unsigned int i = 1; i <= len; i++)
  692. {
  693. const char *str = luaL_checkstring(L, i);
  694. if (!Graphics::getConstant(str, support))
  695. supported = false;
  696. switch (support)
  697. {
  698. case Graphics::SUPPORT_CANVAS:
  699. if (!Canvas::isSupported())
  700. supported = false;
  701. break;
  702. case Graphics::SUPPORT_HDR_CANVAS:
  703. if (!Canvas::isHdrSupported())
  704. supported = false;
  705. break;
  706. case Graphics::SUPPORT_PIXELEFFECT:
  707. if (!PixelEffect::isSupported())
  708. supported = false;
  709. break;
  710. case Graphics::SUPPORT_NPOT:
  711. if (!Image::hasNpot())
  712. supported = false;
  713. break;
  714. case Graphics::SUPPORT_SUBTRACTIVE:
  715. supported = (GLEE_VERSION_1_4 || GLEE_ARB_imaging) || (GLEE_EXT_blend_minmax && GLEE_EXT_blend_subtract);
  716. break;
  717. default:
  718. supported = false;
  719. }
  720. if (!supported)
  721. break;
  722. }
  723. lua_pushboolean(L, supported);
  724. return 1;
  725. }
  726. /**
  727. * Draws an Image at the specified coordinates, with rotation and
  728. * scaling along both axes.
  729. * @param x The x-coordinate.
  730. * @param y The y-coordinate.
  731. * @param angle The amount of rotation.
  732. * @param sx The scale factor along the x-axis. (1 = normal).
  733. * @param sy The scale factor along the y-axis. (1 = normal).
  734. * @param ox The offset along the x-axis.
  735. * @param oy The offset along the y-axis.
  736. * @param kx Shear along the x-axis.
  737. * @param ky Shear along the y-axis.
  738. **/
  739. int w_draw(lua_State *L)
  740. {
  741. Drawable *drawable = luax_checktype<Drawable>(L, 1, "Drawable", GRAPHICS_DRAWABLE_T);
  742. float x = (float)luaL_optnumber(L, 2, 0.0f);
  743. float y = (float)luaL_optnumber(L, 3, 0.0f);
  744. float angle = (float)luaL_optnumber(L, 4, 0.0f);
  745. float sx = (float)luaL_optnumber(L, 5, 1.0f);
  746. float sy = (float)luaL_optnumber(L, 6, sx);
  747. float ox = (float)luaL_optnumber(L, 7, 0);
  748. float oy = (float)luaL_optnumber(L, 8, 0);
  749. float kx = (float)luaL_optnumber(L, 9, 0);
  750. float ky = (float)luaL_optnumber(L, 10, 0);
  751. drawable->draw(x, y, angle, sx, sy, ox, oy, kx, ky);
  752. return 0;
  753. }
  754. /**
  755. * Draws an Quad of a DrawQable at the specified coordinates,
  756. * with rotation and scaling along both axes.
  757. *
  758. * @param q The Quad to draw.
  759. * @param x The x-coordinate.
  760. * @param y The y-coordinate.
  761. * @param angle The amount of rotation.
  762. * @param sx The scale factor along the x-axis. (1 = normal).
  763. * @param sy The scale factor along the y-axis. (1 = normal).
  764. * @param ox The offset along the x-axis.
  765. * @param oy The offset along the y-axis.
  766. * @param kx Shear along the x-axis.
  767. * @param ky Shear along the y-axis.
  768. **/
  769. int w_drawq(lua_State *L)
  770. {
  771. DrawQable *dq = luax_checktype<DrawQable>(L, 1, "DrawQable", GRAPHICS_DRAWQABLE_T);
  772. Quad *q = luax_checkframe(L, 2);
  773. float x = (float)luaL_checknumber(L, 3);
  774. float y = (float)luaL_checknumber(L, 4);
  775. float angle = (float)luaL_optnumber(L, 5, 0);
  776. float sx = (float)luaL_optnumber(L, 6, 1);
  777. float sy = (float)luaL_optnumber(L, 7, sx);
  778. float ox = (float)luaL_optnumber(L, 8, 0);
  779. float oy = (float)luaL_optnumber(L, 9, 0);
  780. float kx = (float)luaL_optnumber(L, 10, 0);
  781. float ky = (float)luaL_optnumber(L, 11, 0);
  782. dq->drawq(q, x, y, angle, sx, sy, ox, oy, kx, ky);
  783. return 0;
  784. }
  785. int w_drawTest(lua_State *L)
  786. {
  787. Image *image = luax_checktype<Image>(L, 1, "Image", GRAPHICS_IMAGE_T);
  788. float x = (float)luaL_optnumber(L, 2, 0.0f);
  789. float y = (float)luaL_optnumber(L, 3, 0.0f);
  790. float angle = (float)luaL_optnumber(L, 4, 0.0f);
  791. float sx = (float)luaL_optnumber(L, 5, 1.0f);
  792. float sy = (float)luaL_optnumber(L, 6, sx);
  793. float ox = (float)luaL_optnumber(L, 7, 0);
  794. float oy = (float)luaL_optnumber(L, 8, 0);
  795. instance->drawTest(image, x, y, angle, sx, sy, ox, oy);
  796. return 0;
  797. }
  798. int w_print(lua_State *L)
  799. {
  800. const char *str = luaL_checkstring(L, 1);
  801. float x = (float)luaL_checknumber(L, 2);
  802. float y = (float)luaL_checknumber(L, 3);
  803. float angle = (float)luaL_optnumber(L, 4, 0.0f);
  804. float sx = (float)luaL_optnumber(L, 5, 1.0f);
  805. float sy = (float)luaL_optnumber(L, 6, sx);
  806. float ox = (float)luaL_optnumber(L, 7, 0.0f);
  807. float oy = (float)luaL_optnumber(L, 8, 0.0f);
  808. float kx = (float)luaL_optnumber(L, 9, 0.0f);
  809. float ky = (float)luaL_optnumber(L, 10, 0.0f);
  810. try
  811. {
  812. instance->print(str, x, y, angle, sx, sy, ox, oy, kx,ky);
  813. }
  814. catch(love::Exception e)
  815. {
  816. return luaL_error(L, "Decoding error: %s", e.what());
  817. }
  818. return 0;
  819. }
  820. int w_printf(lua_State *L)
  821. {
  822. const char *str = luaL_checkstring(L, 1);
  823. float x = (float)luaL_checknumber(L, 2);
  824. float y = (float)luaL_checknumber(L, 3);
  825. float wrap = (float)luaL_checknumber(L, 4);
  826. Graphics::AlignMode align = Graphics::ALIGN_LEFT;
  827. if (lua_gettop(L) >= 5)
  828. {
  829. const char *str = luaL_checkstring(L, 5);
  830. if (!Graphics::getConstant(str, align))
  831. return luaL_error(L, "Incorrect alignment: %s", str);
  832. }
  833. try
  834. {
  835. instance->printf(str, x, y, wrap, align);
  836. }
  837. catch(love::Exception e)
  838. {
  839. return luaL_error(L, "Decoding error: %s", e.what());
  840. }
  841. return 0;
  842. }
  843. int w_point(lua_State *L)
  844. {
  845. float x = (float)luaL_checknumber(L, 1);
  846. float y = (float)luaL_checknumber(L, 2);
  847. instance->point(x, y);
  848. return 0;
  849. }
  850. int w_line(lua_State *L)
  851. {
  852. int args = lua_gettop(L);
  853. bool is_table = false;
  854. if (args == 1 && lua_istable(L, 1))
  855. {
  856. args = lua_objlen(L, 1);
  857. is_table = true;
  858. }
  859. if (args % 2 != 0)
  860. return luaL_error(L, "Number of vertices must be a multiple of two");
  861. else if (args < 4)
  862. return luaL_error(L, "Need at least two vertices to draw a line");
  863. float *coords = new float[args];
  864. if (is_table)
  865. {
  866. for (int i = 0; i < args; ++i)
  867. {
  868. lua_pushnumber(L, i + 1);
  869. lua_rawget(L, 1);
  870. coords[i] = luax_tofloat(L, -1);
  871. lua_pop(L, 1);
  872. }
  873. }
  874. else
  875. {
  876. for (int i = 0; i < args; ++i)
  877. coords[i] = luax_tofloat(L, i + 1);
  878. }
  879. instance->polyline(coords, args);
  880. delete[] coords;
  881. return 0;
  882. }
  883. int w_triangle(lua_State *L)
  884. {
  885. Graphics::DrawMode mode;
  886. const char *str = luaL_checkstring(L, 1);
  887. if (!Graphics::getConstant(str, mode))
  888. return luaL_error(L, "Incorrect draw mode %s", str);
  889. float x1 = (float)luaL_checknumber(L, 2);
  890. float y1 = (float)luaL_checknumber(L, 3);
  891. float x2 = (float)luaL_checknumber(L, 4);
  892. float y2 = (float)luaL_checknumber(L, 5);
  893. float x3 = (float)luaL_checknumber(L, 6);
  894. float y3 = (float)luaL_checknumber(L, 7);
  895. instance->triangle(mode, x1, y1, x2, y2, x3, y3);
  896. return 0;
  897. }
  898. int w_rectangle(lua_State *L)
  899. {
  900. Graphics::DrawMode mode;
  901. const char *str = luaL_checkstring(L, 1);
  902. if (!Graphics::getConstant(str, mode))
  903. return luaL_error(L, "Incorrect draw mode %s", str);
  904. float x = (float)luaL_checknumber(L, 2);
  905. float y = (float)luaL_checknumber(L, 3);
  906. float w = (float)luaL_checknumber(L, 4);
  907. float h = (float)luaL_checknumber(L, 5);
  908. instance->rectangle(mode, x, y, w, h);
  909. return 0;
  910. }
  911. int w_quad(lua_State *L)
  912. {
  913. Graphics::DrawMode mode;
  914. const char *str = luaL_checkstring(L, 1);
  915. if (!Graphics::getConstant(str, mode))
  916. return luaL_error(L, "Incorrect draw mode %s", str);
  917. float x1 = (float)luaL_checknumber(L, 2);
  918. float y1 = (float)luaL_checknumber(L, 3);
  919. float x2 = (float)luaL_checknumber(L, 4);
  920. float y2 = (float)luaL_checknumber(L, 5);
  921. float x3 = (float)luaL_checknumber(L, 6);
  922. float y3 = (float)luaL_checknumber(L, 7);
  923. float x4 = (float)luaL_checknumber(L, 8);
  924. float y4 = (float)luaL_checknumber(L, 9);
  925. instance->quad(mode, x1, y1, x2, y2, x3, y3, x4, y4);
  926. return 0;
  927. }
  928. int w_circle(lua_State *L)
  929. {
  930. Graphics::DrawMode mode;
  931. const char *str = luaL_checkstring(L, 1);
  932. if (!Graphics::getConstant(str, mode))
  933. return luaL_error(L, "Incorrect draw mode %s", str);
  934. float x = (float)luaL_checknumber(L, 2);
  935. float y = (float)luaL_checknumber(L, 3);
  936. float radius = (float)luaL_checknumber(L, 4);
  937. int points;
  938. if (lua_isnoneornil(L, 5))
  939. points = radius > 10 ? (int)(radius) : 10;
  940. else
  941. points = luaL_checkint(L, 5);
  942. instance->circle(mode, x, y, radius, points);
  943. return 0;
  944. }
  945. int w_arc(lua_State *L)
  946. {
  947. Graphics::DrawMode mode;
  948. const char *str = luaL_checkstring(L, 1);
  949. if (!Graphics::getConstant(str, mode))
  950. return luaL_error(L, "Incorrect draw mode %s", str);
  951. float x = (float)luaL_checknumber(L, 2);
  952. float y = (float)luaL_checknumber(L, 3);
  953. float radius = (float)luaL_checknumber(L, 4);
  954. float angle1 = (float)luaL_checknumber(L, 5);
  955. float angle2 = (float)luaL_checknumber(L, 6);
  956. int points;
  957. if (lua_isnoneornil(L, 7))
  958. points = radius > 10 ? (int)(radius) : 10;
  959. else
  960. points = luaL_checkint(L, 7);
  961. instance->arc(mode, x, y, radius, angle1, angle2, points);
  962. return 0;
  963. }
  964. int w_polygon(lua_State *L)
  965. {
  966. int args = lua_gettop(L) - 1;
  967. Graphics::DrawMode mode;
  968. const char *str = luaL_checkstring(L, 1);
  969. if (!Graphics::getConstant(str, mode))
  970. return luaL_error(L, "Invalid draw mode: %s", str);
  971. bool is_table = false;
  972. float *coords;
  973. if (args == 1 && lua_istable(L, 2))
  974. {
  975. args = lua_objlen(L, 2);
  976. is_table = true;
  977. }
  978. if (args % 2 != 0)
  979. return luaL_error(L, "Number of vertices must be a multiple of two");
  980. else if (args < 6)
  981. return luaL_error(L, "Need at least three vertices to draw a polygon");
  982. // fetch coords
  983. coords = new float[args + 2];
  984. if (is_table)
  985. {
  986. for (int i = 0; i < args; ++i)
  987. {
  988. lua_pushnumber(L, i + 1);
  989. lua_rawget(L, 2);
  990. coords[i] = luax_tofloat(L, -1);
  991. lua_pop(L, 1);
  992. }
  993. }
  994. else
  995. {
  996. for (int i = 0; i < args; ++i)
  997. coords[i] = luax_tofloat(L, i + 2);
  998. }
  999. // make a closed loop
  1000. coords[args] = coords[0];
  1001. coords[args+1] = coords[1];
  1002. instance->polygon(mode, coords, args+2);
  1003. delete[] coords;
  1004. return 0;
  1005. }
  1006. int w_push(lua_State *L)
  1007. {
  1008. try
  1009. {
  1010. instance->push();
  1011. }
  1012. catch(love::Exception e)
  1013. {
  1014. return luaL_error(L, e.what());
  1015. }
  1016. return 0;
  1017. }
  1018. int w_pop(lua_State *L)
  1019. {
  1020. try
  1021. {
  1022. instance->pop();
  1023. }
  1024. catch(love::Exception e)
  1025. {
  1026. return luaL_error(L, e.what());
  1027. }
  1028. return 0;
  1029. }
  1030. int w_rotate(lua_State *L)
  1031. {
  1032. float deg = (float)luaL_checknumber(L, 1);
  1033. instance->rotate(deg);
  1034. return 0;
  1035. }
  1036. int w_scale(lua_State *L)
  1037. {
  1038. float sx = (float)luaL_optnumber(L, 1, 1.0f);
  1039. float sy = (float)luaL_optnumber(L, 2, sx);
  1040. instance->scale(sx, sy);
  1041. return 0;
  1042. }
  1043. int w_translate(lua_State *L)
  1044. {
  1045. float x = (float)luaL_checknumber(L, 1);
  1046. float y = (float)luaL_checknumber(L, 2);
  1047. instance->translate(x, y);
  1048. return 0;
  1049. }
  1050. int w_shear(lua_State *L)
  1051. {
  1052. float kx = (float)luaL_checknumber(L, 1);
  1053. float ky = (float)luaL_checknumber(L, 2);
  1054. instance->shear(kx, ky);
  1055. return 0;
  1056. }
  1057. int w_hasFocus(lua_State *L)
  1058. {
  1059. luax_pushboolean(L, instance->hasFocus());
  1060. return 1;
  1061. }
  1062. // List of functions to wrap.
  1063. static const luaL_Reg functions[] =
  1064. {
  1065. { "checkMode", w_checkMode },
  1066. { "setMode", w_setMode },
  1067. { "getMode", w_getMode },
  1068. { "toggleFullscreen", w_toggleFullscreen },
  1069. { "reset", w_reset },
  1070. { "clear", w_clear },
  1071. { "present", w_present },
  1072. { "newImage", w_newImage },
  1073. { "newQuad", w_newQuad },
  1074. { "newFont", w_newFont },
  1075. { "newImageFont", w_newImageFont },
  1076. { "newSpriteBatch", w_newSpriteBatch },
  1077. { "newParticleSystem", w_newParticleSystem },
  1078. { "newCanvas", w_newCanvas },
  1079. { "newPixelEffect", w_newPixelEffect },
  1080. { "setColor", w_setColor },
  1081. { "getColor", w_getColor },
  1082. { "setBackgroundColor", w_setBackgroundColor },
  1083. { "getBackgroundColor", w_getBackgroundColor },
  1084. { "setFont", w_setFont },
  1085. { "getFont", w_getFont },
  1086. { "setBlendMode", w_setBlendMode },
  1087. { "setColorMode", w_setColorMode },
  1088. { "setDefaultImageFilter", w_setDefaultImageFilter },
  1089. { "getBlendMode", w_getBlendMode },
  1090. { "getColorMode", w_getColorMode },
  1091. { "getDefaultImageFilter", w_getDefaultImageFilter },
  1092. { "setLineWidth", w_setLineWidth },
  1093. { "setLineStyle", w_setLineStyle },
  1094. { "setLine", w_setLine },
  1095. { "getLineWidth", w_getLineWidth },
  1096. { "getLineStyle", w_getLineStyle },
  1097. { "setPointSize", w_setPointSize },
  1098. { "setPointStyle", w_setPointStyle },
  1099. { "setPoint", w_setPoint },
  1100. { "getPointSize", w_getPointSize },
  1101. { "getPointStyle", w_getPointStyle },
  1102. { "getMaxPointSize", w_getMaxPointSize },
  1103. { "newScreenshot", w_newScreenshot },
  1104. { "setCanvas", w_setCanvas },
  1105. { "getCanvas", w_getCanvas },
  1106. { "setPixelEffect", w_setPixelEffect },
  1107. { "getPixelEffect", w_getPixelEffect },
  1108. { "isSupported", w_isSupported },
  1109. { "draw", w_draw },
  1110. { "drawq", w_drawq },
  1111. { "drawTest", w_drawTest },
  1112. { "print", w_print },
  1113. { "printf", w_printf },
  1114. { "setCaption", w_setCaption },
  1115. { "getCaption", w_getCaption },
  1116. { "setIcon", w_setIcon },
  1117. { "getWidth", w_getWidth },
  1118. { "getHeight", w_getHeight },
  1119. { "isCreated", w_isCreated },
  1120. { "getModes", w_getModes },
  1121. { "setScissor", w_setScissor },
  1122. { "getScissor", w_getScissor },
  1123. { "newStencil", w_newStencil },
  1124. { "setStencil", w_setStencil },
  1125. { "setInvertedStencil", w_setInvertedStencil },
  1126. { "point", w_point },
  1127. { "line", w_line },
  1128. { "triangle", w_triangle },
  1129. { "rectangle", w_rectangle },
  1130. { "quad", w_quad },
  1131. { "circle", w_circle },
  1132. { "arc", w_arc },
  1133. { "polygon", w_polygon },
  1134. { "push", w_push },
  1135. { "pop", w_pop },
  1136. { "rotate", w_rotate },
  1137. { "scale", w_scale },
  1138. { "translate", w_translate },
  1139. { "shear", w_shear },
  1140. { "hasFocus", w_hasFocus },
  1141. { 0, 0 }
  1142. };
  1143. // Types for this module.
  1144. static const lua_CFunction types[] =
  1145. {
  1146. luaopen_font,
  1147. luaopen_image,
  1148. luaopen_frame,
  1149. luaopen_spritebatch,
  1150. luaopen_particlesystem,
  1151. luaopen_canvas,
  1152. luaopen_pixeleffect,
  1153. 0
  1154. };
  1155. extern "C" int luaopen_love_graphics(lua_State *L)
  1156. {
  1157. if (instance == 0)
  1158. {
  1159. try
  1160. {
  1161. instance = new Graphics();
  1162. }
  1163. catch(Exception &e)
  1164. {
  1165. return luaL_error(L, e.what());
  1166. }
  1167. }
  1168. else
  1169. instance->retain();
  1170. WrappedModule w;
  1171. w.module = instance;
  1172. w.name = "graphics";
  1173. w.flags = MODULE_T;
  1174. w.functions = functions;
  1175. w.types = types;
  1176. int n = luax_register_module(L, w);
  1177. if (luaL_loadbuffer(L, (const char *)graphics_lua, sizeof(graphics_lua), "graphics.lua") == 0)
  1178. lua_call(L, 0, 0);
  1179. return n;
  1180. }
  1181. } // opengl
  1182. } // graphics
  1183. } // love