naev 0.11.5
nlua_canvas.c
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
11
12#include "naev.h"
15#include "nlua_canvas.h"
16
17#include "log.h"
18#include "nluadef.h"
19#include "nlua_tex.h"
20#include "nlua_colour.h"
21#include "render.h"
22
23static int nlua_canvas_counter = 0;
24static GLuint previous_fbo = 0;
25static int previous_fbo_set = 0;
26static int was_scissored = 0;
27
28/* Canvas metatable methods. */
29static int canvasL_gc( lua_State *L );
30static int canvasL_eq( lua_State *L );
31static int canvasL_new( lua_State *L );
32static int canvasL_set( lua_State *L );
33static int canvasL_dims( lua_State *L );
34static int canvasL_getTex( lua_State *L );
35static int canvasL_clear( lua_State *L );
36static const luaL_Reg canvasL_methods[] = {
37 { "__gc", canvasL_gc },
38 { "__eq", canvasL_eq },
39 { "new", canvasL_new },
40 { "set", canvasL_set },
41 { "dims", canvasL_dims },
42 { "getTex", canvasL_getTex },
43 { "clear", canvasL_clear },
44 {0,0}
45};
53int nlua_loadCanvas( nlua_env env )
54{
55 nlua_register(env, CANVAS_METATABLE, canvasL_methods, 1);
56 return 0;
57}
58
73LuaCanvas_t* lua_tocanvas( lua_State *L, int ind )
74{
75 return (LuaCanvas_t*) lua_touserdata(L,ind);
76}
84LuaCanvas_t* luaL_checkcanvas( lua_State *L, int ind )
85{
86 if (lua_iscanvas(L,ind))
87 return lua_tocanvas(L,ind);
88 luaL_typerror(L, ind, CANVAS_METATABLE);
89 return NULL;
90}
98LuaCanvas_t* lua_pushcanvas( lua_State *L, LuaCanvas_t canvas )
99{
100 LuaCanvas_t *c = (LuaCanvas_t*) lua_newuserdata(L, sizeof(LuaCanvas_t));
101 *c = canvas;
102 luaL_getmetatable(L, CANVAS_METATABLE);
103 lua_setmetatable(L, -2);
104 return c;
105}
113int lua_iscanvas( lua_State *L, int ind )
114{
115 int ret;
116
117 if (lua_getmetatable(L,ind)==0)
118 return 0;
119 lua_getfield(L, LUA_REGISTRYINDEX, CANVAS_METATABLE);
120
121 ret = 0;
122 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
123 ret = 1;
124
125 lua_pop(L, 2); /* remove both metatables */
126 return ret;
127}
128
135static int canvasL_gc( lua_State *L )
136{
137 const LuaCanvas_t *lc = luaL_checkcanvas(L,1);
138 glDeleteFramebuffers( 1, &lc->fbo );
139 gl_freeTexture( lc->tex );
140 gl_checkErr();
141 return 0;
142}
143
152static int canvasL_eq( lua_State *L )
153{
154 LuaCanvas_t *c1, *c2;
155 c1 = luaL_checkcanvas(L,1);
156 c2 = luaL_checkcanvas(L,2);
157 lua_pushboolean( L, (memcmp( c1, c2, sizeof(LuaCanvas_t) )==0) );
158 return 1;
159}
160
168int canvas_new( LuaCanvas_t *lc, int w, int h )
169{
170 GLenum status;
171 char *name;
172
173 memset( lc, 0, sizeof(LuaCanvas_t) );
174
175 /* Create the texture. */
176 SDL_asprintf( &name, "nlua_canvas_%03d", ++nlua_canvas_counter );
177 lc->tex = gl_loadImageData( NULL, w, h, 1, 1, name );
178 lc->tex->flags |= OPENGL_TEX_VFLIP; /* Long story, but love stuff inverts Y axis for canvases so we have to redo that here for spob targetting stuff to work properly. */
179 free( name );
180
181 /* Create the frame buffer. */
182 glGenFramebuffers( 1, &lc->fbo );
183 glBindFramebuffer(GL_FRAMEBUFFER, lc->fbo);
184
185 /* Attach the colour buffer. */
186 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lc->tex->texture, 0);
187
188 /* Check status. */
189 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
190 if (status != GL_FRAMEBUFFER_COMPLETE)
191 return -1;
192
193 /* Clear the canvas. */
194 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
195
196 /* Restore state. */
197 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
198
199 gl_checkErr();
200 return 0;
201}
202
211static int canvasL_new( lua_State *L )
212{
213 LuaCanvas_t lc;
214
215 int w = luaL_checkint(L,1);
216 int h = luaL_checkint(L,2);
217
218 if (canvas_new( &lc, w, h ))
219 return NLUA_ERROR( L, _("Error setting up framebuffer!"));
220 lua_pushcanvas( L, lc );
221 return 1;
222}
223
231static int canvasL_set( lua_State *L )
232{
233 if (!lua_isnoneornil(L,1)) {
234 const LuaCanvas_t *lc = luaL_checkcanvas(L,1);
235 if (!previous_fbo_set) {
236 previous_fbo = gl_screen.current_fbo;
237 previous_fbo_set = 1;
238 was_scissored = glIsEnabled(GL_SCISSOR_TEST);
239 }
241 glDisable(GL_SCISSOR_TEST);
242 glViewport( 0, 0, lc->tex->w, lc->tex->h );
243 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
244 render_needsReset();
245 }
246 else
247 canvas_reset();
248
249 return 0;
250}
251
259static int canvasL_dims( lua_State *L )
260{
261 const LuaCanvas_t *lc = luaL_checkcanvas(L,1);
262 lua_pushnumber( L, lc->tex->w );
263 lua_pushnumber( L, lc->tex->h );
264 return 2;
265}
266
274static int canvasL_getTex( lua_State *L )
275{
276 const LuaCanvas_t *lc = luaL_checkcanvas(L,1);
277 lua_pushtex( L, gl_dupTexture(lc->tex) );
278 return 1;
279}
280
288static int canvasL_clear( lua_State *L )
289{
290 const LuaCanvas_t *lc = luaL_checkcanvas(L,1);
291 (void) lc; /* Just to enforce good practice, canvas should be already set. */
292 const glColour *c = luaL_optcolour(L,2,&cBlack);
293 glClearColor( c->r, c->g, c->b, c->a );
294 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
295 glClearColor( 0.0, 0.0, 0.0, 1.0 );
296 return 0;
297}
298
302void canvas_reset (void)
303{
304 if (!previous_fbo_set)
305 return;
306 gl_screen.current_fbo = previous_fbo;
307 previous_fbo_set = 0;
308 if (was_scissored)
309 glEnable(GL_SCISSOR_TEST);
310 glViewport( 0, 0, gl_screen.rw, gl_screen.rh );
311 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
312}
Header file with generic functions and naev-specifics.
glTexture ** lua_pushtex(lua_State *L, glTexture *texture)
Pushes a texture on the stack.
Definition nlua_tex.c:130
glInfo gl_screen
Definition opengl.c:51
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition opengl_tex.c:917
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition opengl_tex.c:862
static const double c[]
Definition rng.c:264
Wrapper to canvass.
Definition nlua_canvas.h:19
glTexture * tex
Definition nlua_canvas.h:21
int rh
Definition opengl.h:51
int rw
Definition opengl.h:50
GLuint current_fbo
Definition opengl.h:70
double w
Definition opengl_tex.h:40
uint8_t flags
Definition opengl_tex.h:57
GLuint texture
Definition opengl_tex.h:52
double h
Definition opengl_tex.h:41