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
24namespace love
25{
26namespace graphics
27{
28
29Canvas *luax_checkcanvas(lua_State *L, int idx)
30{
31 return luax_checktype<Canvas>(L, idx);
32}
33
34int 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
41int 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
89int 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
119int 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
126int 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
137static 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
147extern "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