naev 0.10.4
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
22static int nlua_canvas_counter = 0;
23static GLuint previous_fbo = 0;
24static int previous_fbo_set = 0;
25static int was_scissored = 0;
26
27/* Canvas metatable methods. */
28static int canvasL_gc( lua_State *L );
29static int canvasL_eq( lua_State *L );
30static int canvasL_new( lua_State *L );
31static int canvasL_set( lua_State *L );
32static int canvasL_dims( lua_State *L );
33static int canvasL_getTex( lua_State *L );
34static int canvasL_clear( lua_State *L );
35static const luaL_Reg canvasL_methods[] = {
36 { "__gc", canvasL_gc },
37 { "__eq", canvasL_eq },
38 { "new", canvasL_new },
39 { "set", canvasL_set },
40 { "dims", canvasL_dims },
41 { "getTex", canvasL_getTex },
42 { "clear", canvasL_clear },
43 {0,0}
44};
52int nlua_loadCanvas( nlua_env env )
53{
54 nlua_register(env, CANVAS_METATABLE, canvasL_methods, 1);
55 return 0;
56}
57
72LuaCanvas_t* lua_tocanvas( lua_State *L, int ind )
73{
74 return (LuaCanvas_t*) lua_touserdata(L,ind);
75}
83LuaCanvas_t* luaL_checkcanvas( lua_State *L, int ind )
84{
85 if (lua_iscanvas(L,ind))
86 return lua_tocanvas(L,ind);
87 luaL_typerror(L, ind, CANVAS_METATABLE);
88 return NULL;
89}
97LuaCanvas_t* lua_pushcanvas( lua_State *L, LuaCanvas_t canvas )
98{
99 LuaCanvas_t *c = (LuaCanvas_t*) lua_newuserdata(L, sizeof(LuaCanvas_t));
100 *c = canvas;
101 luaL_getmetatable(L, CANVAS_METATABLE);
102 lua_setmetatable(L, -2);
103 return c;
104}
112int lua_iscanvas( lua_State *L, int ind )
113{
114 int ret;
115
116 if (lua_getmetatable(L,ind)==0)
117 return 0;
118 lua_getfield(L, LUA_REGISTRYINDEX, CANVAS_METATABLE);
119
120 ret = 0;
121 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
122 ret = 1;
123
124 lua_pop(L, 2); /* remove both metatables */
125 return ret;
126}
127
134static int canvasL_gc( lua_State *L )
135{
136 LuaCanvas_t *lc = luaL_checkcanvas(L,1);
137 glDeleteFramebuffers( 1, &lc->fbo );
138 gl_freeTexture( lc->tex );
139 gl_checkErr();
140 return 0;
141}
142
151static int canvasL_eq( lua_State *L )
152{
153 LuaCanvas_t *c1, *c2;
154 c1 = luaL_checkcanvas(L,1);
155 c2 = luaL_checkcanvas(L,2);
156 lua_pushboolean( L, (memcmp( c1, c2, sizeof(LuaCanvas_t) )==0) );
157 return 1;
158}
159
167int canvas_new( LuaCanvas_t *lc, int w, int h )
168{
169 GLenum status;
170 char *name;
171
172 memset( lc, 0, sizeof(LuaCanvas_t) );
173
174 /* Create the texture. */
175 asprintf( &name, "nlua_canvas_%03d", ++nlua_canvas_counter );
176 lc->tex = gl_loadImageData( NULL, w, h, 1, 1, name );
177 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. */
178 free( name );
179
180 /* Create the frame buffer. */
181 glGenFramebuffers( 1, &lc->fbo );
182 glBindFramebuffer(GL_FRAMEBUFFER, lc->fbo);
183
184 /* Attach the colour buffer. */
185 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lc->tex->texture, 0);
186
187 /* Check status. */
188 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
189 if (status != GL_FRAMEBUFFER_COMPLETE)
190 return -1;
191
192 /* Clear the canvas. */
193 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194
195 /* Restore state. */
196 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
197
198 gl_checkErr();
199 return 0;
200}
201
210static int canvasL_new( lua_State *L )
211{
212 LuaCanvas_t lc;
213
214 int w = luaL_checkint(L,1);
215 int h = luaL_checkint(L,2);
216
217 if (canvas_new( &lc, w, h ))
218 NLUA_ERROR( L, _("Error setting up framebuffer!"));
219 lua_pushcanvas( L, lc );
220 return 1;
221}
222
230static int canvasL_set( lua_State *L )
231{
232 LuaCanvas_t *lc;
233
234 if (lua_iscanvas(L,1)) {
235 lc = luaL_checkcanvas(L,1);
236 if (!previous_fbo_set) {
237 previous_fbo = gl_screen.current_fbo;
238 previous_fbo_set = 1;
239 was_scissored = glIsEnabled(GL_SCISSOR_TEST);
240 }
242 glDisable(GL_SCISSOR_TEST);
243 glViewport( 0, 0, lc->tex->w, lc->tex->h );
244 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
245 }
246 else if ((lua_gettop(L)<=0) || lua_isnil(L,1)) {
247 gl_screen.current_fbo = previous_fbo;
248 previous_fbo_set = 0;
249 if (was_scissored)
250 glEnable(GL_SCISSOR_TEST);
251 glViewport( 0, 0, gl_screen.rw, gl_screen.rh );
252 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
253 }
254 else
255 NLUA_ERROR(L,_("Unexpected parameter"));
256
257 return 0;
258}
259
267static int canvasL_dims( lua_State *L )
268{
269 LuaCanvas_t *lc = luaL_checkcanvas(L,1);
270 lua_pushnumber( L, lc->tex->w );
271 lua_pushnumber( L, lc->tex->h );
272 return 2;
273}
274
282static int canvasL_getTex( lua_State *L )
283{
284 LuaCanvas_t *lc = luaL_checkcanvas(L,1);
285 lua_pushtex( L, gl_dupTexture(lc->tex) );
286 return 1;
287}
288
296static int canvasL_clear( lua_State *L )
297{
298 LuaCanvas_t *lc = luaL_checkcanvas(L,1);
299 (void) lc; /* Just to enforce good practice, canvas should be already set. */
300 const glColour *c = luaL_optcolour(L,2,&cBlack);
301 glClearColor( c->r, c->g, c->b, c->a );
302 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
303 glClearColor( 0.0, 0.0, 0.0, 1.0 );
304 return 0;
305}
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
int asprintf(char **strp, const char *fmt,...)
Like sprintf(), but it allocates a large-enough string and returns the pointer in the first argument....
Definition: nstring.c:161
glInfo gl_screen
Definition: opengl.c:51
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition: opengl_tex.c:809
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition: opengl_tex.c:755
static const double c[]
Definition: rng.c:264
Wrapper to canvass.
Definition: nlua_canvas.h:19
GLuint fbo
Definition: nlua_canvas.h:20
glTexture * tex
Definition: nlua_canvas.h:21
int rh
Definition: opengl.h:47
int rw
Definition: opengl.h:46
GLuint current_fbo
Definition: opengl.h:66
double w
Definition: opengl_tex.h:38
uint8_t flags
Definition: opengl_tex.h:54
GLuint texture
Definition: opengl_tex.h:50
double h
Definition: opengl_tex.h:39