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_Texture.h"
22
23namespace love
24{
25namespace graphics
26{
27
28Texture *luax_checktexture(lua_State *L, int idx)
29{
30 return luax_checktype<Texture>(L, idx);
31}
32
33int w_Texture_getTextureType(lua_State *L)
34{
35 Texture *t = luax_checktexture(L, 1);
36 const char *tstr;
37 if (!Texture::getConstant(t->getTextureType(), tstr))
38 return luax_enumerror(L, "texture type", Texture::getConstants(TEXTURE_MAX_ENUM), tstr);
39 lua_pushstring(L, tstr);
40 return 1;
41}
42
43static int w__optMipmap(lua_State *L, Texture *t, int idx)
44{
45 int mipmap = 0;
46
47 if (!lua_isnoneornil(L, idx))
48 {
49 mipmap = (int) luaL_checkinteger(L, idx) - 1;
50
51 if (mipmap < 0 || mipmap >= t->getMipmapCount())
52 luaL_error(L, "Invalid mipmap index: %d", mipmap + 1);
53 }
54
55 return mipmap;
56}
57
58int w_Texture_getWidth(lua_State *L)
59{
60 Texture *t = luax_checktexture(L, 1);
61 lua_pushnumber(L, t->getWidth(w__optMipmap(L, t, 2)));
62 return 1;
63}
64
65int w_Texture_getHeight(lua_State *L)
66{
67 Texture *t = luax_checktexture(L, 1);
68 lua_pushnumber(L, t->getHeight(w__optMipmap(L, t, 2)));
69 return 1;
70}
71
72int w_Texture_getDimensions(lua_State *L)
73{
74 Texture *t = luax_checktexture(L, 1);
75 int mipmap = w__optMipmap(L, t, 2);
76 lua_pushnumber(L, t->getWidth(mipmap));
77 lua_pushnumber(L, t->getHeight(mipmap));
78 return 2;
79}
80
81int w_Texture_getDepth(lua_State *L)
82{
83 Texture *t = luax_checktexture(L, 1);
84 lua_pushnumber(L, t->getDepth(w__optMipmap(L, t, 2)));
85 return 1;
86}
87
88int w_Texture_getLayerCount(lua_State *L)
89{
90 Texture *t = luax_checktexture(L, 1);
91 lua_pushnumber(L, t->getLayerCount());
92 return 1;
93}
94
95int w_Texture_getMipmapCount(lua_State *L)
96{
97 Texture *t = luax_checktexture(L, 1);
98 lua_pushnumber(L, t->getMipmapCount());
99 return 1;
100}
101
102int w_Texture_getPixelWidth(lua_State *L)
103{
104 Texture *t = luax_checktexture(L, 1);
105 lua_pushnumber(L, t->getPixelWidth(w__optMipmap(L, t, 2)));
106 return 1;
107}
108
109int w_Texture_getPixelHeight(lua_State *L)
110{
111 Texture *t = luax_checktexture(L, 1);
112 lua_pushnumber(L, t->getPixelHeight(w__optMipmap(L, t, 2)));
113 return 1;
114}
115
116int w_Texture_getPixelDimensions(lua_State *L)
117{
118 Texture *t = luax_checktexture(L, 1);
119 int mipmap = w__optMipmap(L, t, 2);
120 lua_pushnumber(L, t->getPixelWidth(mipmap));
121 lua_pushnumber(L, t->getPixelHeight(mipmap));
122 return 2;
123}
124
125int w_Texture_getDPIScale(lua_State *L)
126{
127 Texture *t = luax_checktexture(L, 1);
128 lua_pushnumber(L, t->getDPIScale());
129 return 1;
130}
131
132int w_Texture_setFilter(lua_State *L)
133{
134 Texture *t = luax_checktexture(L, 1);
135 Texture::Filter f = t->getFilter();
136
137 const char *minstr = luaL_checkstring(L, 2);
138 const char *magstr = luaL_optstring(L, 3, minstr);
139
140 if (!Texture::getConstant(minstr, f.min))
141 return luax_enumerror(L, "filter mode", Texture::getConstants(f.min), minstr);
142 if (!Texture::getConstant(magstr, f.mag))
143 return luax_enumerror(L, "filter mode", Texture::getConstants(f.mag), magstr);
144
145 f.anisotropy = (float) luaL_optnumber(L, 4, 1.0);
146
147 luax_catchexcept(L, [&](){ t->setFilter(f); });
148 return 0;
149}
150
151int w_Texture_getFilter(lua_State *L)
152{
153 Texture *t = luax_checktexture(L, 1);
154 const Texture::Filter f = t->getFilter();
155
156 const char *minstr = nullptr;
157 const char *magstr = nullptr;
158
159 if (!Texture::getConstant(f.min, minstr))
160 return luaL_error(L, "Unknown filter mode.");
161 if (!Texture::getConstant(f.mag, magstr))
162 return luaL_error(L, "Unknown filter mode.");
163
164 lua_pushstring(L, minstr);
165 lua_pushstring(L, magstr);
166 lua_pushnumber(L, f.anisotropy);
167 return 3;
168}
169
170int w_Texture_setMipmapFilter(lua_State *L)
171{
172 Texture *t = luax_checktexture(L, 1);
173 Texture::Filter f = t->getFilter();
174
175 if (lua_isnoneornil(L, 2))
176 f.mipmap = Texture::FILTER_NONE; // mipmapping is disabled if no argument is given
177 else
178 {
179 const char *mipmapstr = luaL_checkstring(L, 2);
180 if (!Texture::getConstant(mipmapstr, f.mipmap))
181 return luax_enumerror(L, "filter mode", Texture::getConstants(f.mipmap), mipmapstr);
182 }
183
184 luax_catchexcept(L, [&](){ t->setFilter(f); });
185 t->setMipmapSharpness((float) luaL_optnumber(L, 3, 0.0));
186
187 return 0;
188}
189
190int w_Texture_getMipmapFilter(lua_State *L)
191{
192 Texture *t = luax_checktexture(L, 1);
193
194 const Texture::Filter &f = t->getFilter();
195
196 const char *mipmapstr;
197 if (Texture::getConstant(f.mipmap, mipmapstr))
198 lua_pushstring(L, mipmapstr);
199 else
200 lua_pushnil(L); // only return a mipmap filter if mipmapping is enabled
201
202 lua_pushnumber(L, t->getMipmapSharpness());
203 return 2;
204}
205
206int w_Texture_setWrap(lua_State *L)
207{
208 Texture *t = luax_checktexture(L, 1);
209 Texture::Wrap w;
210
211 const char *sstr = luaL_checkstring(L, 2);
212 const char *tstr = luaL_optstring(L, 3, sstr);
213 const char *rstr = luaL_optstring(L, 4, sstr);
214
215 if (!Texture::getConstant(sstr, w.s))
216 return luax_enumerror(L, "wrap mode", Texture::getConstants(w.s), sstr);
217 if (!Texture::getConstant(tstr, w.t))
218 return luax_enumerror(L, "wrap mode", Texture::getConstants(w.t), tstr);
219 if (!Texture::getConstant(rstr, w.r))
220 return luax_enumerror(L, "wrap mode", Texture::getConstants(w.r), rstr);
221
222 luax_pushboolean(L, t->setWrap(w));
223 return 1;
224}
225
226int w_Texture_getWrap(lua_State *L)
227{
228 Texture *t = luax_checktexture(L, 1);
229 const Texture::Wrap w = t->getWrap();
230
231 const char *sstr = nullptr;
232 const char *tstr = nullptr;
233 const char *rstr = nullptr;
234
235 if (!Texture::getConstant(w.s, sstr))
236 return luaL_error(L, "Unknown wrap mode.");
237 if (!Texture::getConstant(w.t, tstr))
238 return luaL_error(L, "Unknown wrap mode.");
239 if (!Texture::getConstant(w.r, rstr))
240 return luaL_error(L, "Unknown wrap mode.");
241
242 lua_pushstring(L, sstr);
243 lua_pushstring(L, tstr);
244 lua_pushstring(L, rstr);
245 return 3;
246}
247
248int w_Texture_getFormat(lua_State *L)
249{
250 Texture *t = luax_checktexture(L, 1);
251 PixelFormat format = t->getPixelFormat();
252 const char *str;
253 if (!getConstant(format, str))
254 return luaL_error(L, "Unknown pixel format.");
255
256 lua_pushstring(L, str);
257 return 1;
258}
259
260int w_Texture_isReadable(lua_State *L)
261{
262 Texture *t = luax_checktexture(L, 1);
263 luax_pushboolean(L, t->isReadable());
264 return 1;
265}
266
267int w_Texture_setDepthSampleMode(lua_State *L)
268{
269 Texture *t = luax_checktexture(L, 1);
270
271 Optional<CompareMode> mode;
272 if (!lua_isnoneornil(L, 2))
273 {
274 const char *str = luaL_checkstring(L, 2);
275
276 mode.hasValue = true;
277 if (!getConstant(str, mode.value))
278 return luax_enumerror(L, "compare mode", getConstants(mode.value), str);
279 }
280
281 luax_catchexcept(L, [&]() { t->setDepthSampleMode(mode); });
282 return 0;
283}
284
285int w_Texture_getDepthSampleMode(lua_State *L)
286{
287 Texture *t = luax_checktexture(L, 1);
288 Optional<CompareMode> mode = t->getDepthSampleMode();
289
290 if (mode.hasValue)
291 {
292 const char *str = nullptr;
293 if (!getConstant(mode.value, str))
294 return luaL_error(L, "Unknown compare mode.");
295 lua_pushstring(L, str);
296 }
297 else
298 lua_pushnil(L);
299
300 return 1;
301}
302
303const luaL_Reg w_Texture_functions[] =
304{
305 { "getTextureType", w_Texture_getTextureType },
306 { "getWidth", w_Texture_getWidth },
307 { "getHeight", w_Texture_getHeight },
308 { "getDimensions", w_Texture_getDimensions },
309 { "getDepth", w_Texture_getDepth },
310 { "getLayerCount", w_Texture_getLayerCount },
311 { "getMipmapCount", w_Texture_getMipmapCount },
312 { "getPixelWidth", w_Texture_getPixelWidth },
313 { "getPixelHeight", w_Texture_getPixelHeight },
314 { "getPixelDimensions", w_Texture_getPixelDimensions },
315 { "getDPIScale", w_Texture_getDPIScale },
316 { "setFilter", w_Texture_setFilter },
317 { "getFilter", w_Texture_getFilter },
318 { "setMipmapFilter", w_Texture_setMipmapFilter },
319 { "getMipmapFilter", w_Texture_getMipmapFilter },
320 { "setWrap", w_Texture_setWrap },
321 { "getWrap", w_Texture_getWrap },
322 { "getFormat", w_Texture_getFormat },
323 { "isReadable", w_Texture_isReadable },
324 { "getDepthSampleMode", w_Texture_getDepthSampleMode },
325 { "setDepthSampleMode", w_Texture_setDepthSampleMode },
326 { 0, 0 }
327};
328
329extern "C" int luaopen_texture(lua_State *L)
330{
331 return luax_register_type(L, &Texture::type, w_Texture_functions, nullptr);
332}
333
334} // graphics
335} // love
336