1 | /** |
2 | * Copyright (c) 2006-2023 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 | |
21 | #include "wrap_Canvas.h" |
22 | #include "Graphics.h" |
23 | |
24 | namespace love |
25 | { |
26 | namespace graphics |
27 | { |
28 | |
29 | Canvas *luax_checkcanvas(lua_State *L, int idx) |
30 | { |
31 | return luax_checktype<Canvas>(L, idx); |
32 | } |
33 | |
34 | int w_Canvas_getMSAA(lua_State *L) |
35 | { |
36 | Canvas *canvas = luax_checkcanvas(L, 1); |
37 | lua_pushinteger(L, canvas->getMSAA()); |
38 | return 1; |
39 | } |
40 | |
41 | int w_Canvas_renderTo(lua_State *L) |
42 | { |
43 | Graphics::RenderTarget rt(luax_checkcanvas(L, 1)); |
44 | |
45 | int args = lua_gettop(L); |
46 | |
47 | int startidx = 2; |
48 | |
49 | if (rt.canvas->getTextureType() != TEXTURE_2D) |
50 | { |
51 | rt.slice = (int) luaL_checkinteger(L, 2) - 1; |
52 | startidx++; |
53 | } |
54 | |
55 | luaL_checktype(L, startidx, LUA_TFUNCTION); |
56 | |
57 | auto graphics = Module::getInstance<Graphics>(Module::M_GRAPHICS); |
58 | |
59 | if (graphics) |
60 | { |
61 | // Save the current render targets so we can restore them when we're done. |
62 | Graphics::RenderTargets oldtargets = graphics->getCanvas(); |
63 | |
64 | for (auto c : oldtargets.colors) |
65 | c.canvas->retain(); |
66 | |
67 | if (oldtargets.depthStencil.canvas != nullptr) |
68 | oldtargets.depthStencil.canvas->retain(); |
69 | |
70 | luax_catchexcept(L, [&](){ graphics->setCanvas(rt, false); }); |
71 | |
72 | int status = lua_pcall(L, args - startidx, 0, 0); |
73 | |
74 | graphics->setCanvas(oldtargets); |
75 | |
76 | for (auto c : oldtargets.colors) |
77 | c.canvas->release(); |
78 | |
79 | if (oldtargets.depthStencil.canvas != nullptr) |
80 | oldtargets.depthStencil.canvas->release(); |
81 | |
82 | if (status != 0) |
83 | return lua_error(L); |
84 | } |
85 | |
86 | return 0; |
87 | } |
88 | |
89 | int w_Canvas_newImageData(lua_State *L) |
90 | { |
91 | Canvas *canvas = luax_checkcanvas(L, 1); |
92 | love::image::Image *image = luax_getmodule<love::image::Image>(L, love::image::Image::type); |
93 | |
94 | int slice = 0; |
95 | int mipmap = 0; |
96 | Rect rect = {0, 0, canvas->getPixelWidth(), canvas->getPixelHeight()}; |
97 | |
98 | if (canvas->getTextureType() != TEXTURE_2D) |
99 | slice = (int) luaL_checkinteger(L, 2) - 1; |
100 | |
101 | mipmap = (int) luaL_optinteger(L, 3, 1) - 1; |
102 | |
103 | if (!lua_isnoneornil(L, 4)) |
104 | { |
105 | rect.x = (int) luaL_checkinteger(L, 4); |
106 | rect.y = (int) luaL_checkinteger(L, 5); |
107 | rect.w = (int) luaL_checkinteger(L, 6); |
108 | rect.h = (int) luaL_checkinteger(L, 7); |
109 | } |
110 | |
111 | love::image::ImageData *img = nullptr; |
112 | luax_catchexcept(L, [&](){ img = canvas->newImageData(image, slice, mipmap, rect); }); |
113 | |
114 | luax_pushtype(L, img); |
115 | img->release(); |
116 | return 1; |
117 | } |
118 | |
119 | int w_Canvas_generateMipmaps(lua_State *L) |
120 | { |
121 | Canvas *c = luax_checkcanvas(L, 1); |
122 | luax_catchexcept(L, [&]() { c->generateMipmaps(); }); |
123 | return 0; |
124 | } |
125 | |
126 | int w_Canvas_getMipmapMode(lua_State *L) |
127 | { |
128 | Canvas *c = luax_checkcanvas(L, 1); |
129 | const char *str; |
130 | if (!Canvas::getConstant(c->getMipmapMode(), str)) |
131 | return luax_enumerror(L, "mipmap mode" , Canvas::getConstants(Canvas::MIPMAPS_MAX_ENUM), str); |
132 | |
133 | lua_pushstring(L, str); |
134 | return 1; |
135 | } |
136 | |
137 | static const luaL_Reg w_Canvas_functions[] = |
138 | { |
139 | { "getMSAA" , w_Canvas_getMSAA }, |
140 | { "renderTo" , w_Canvas_renderTo }, |
141 | { "newImageData" , w_Canvas_newImageData }, |
142 | { "generateMipmaps" , w_Canvas_generateMipmaps }, |
143 | { "getMipmapMode" , w_Canvas_getMipmapMode }, |
144 | { 0, 0 } |
145 | }; |
146 | |
147 | extern "C" int luaopen_canvas(lua_State *L) |
148 | { |
149 | return luax_register_type(L, &Canvas::type, w_Texture_functions, w_Canvas_functions, nullptr); |
150 | } |
151 | |
152 | } // graphics |
153 | } // love |
154 | |