wrap_Graphics.cpp 32 KB

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