naev 0.12.5
nlua_canvas.c
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
12
13#include "nlua_canvas.h"
14
15#include "nlua_colour.h"
16#include "nlua_tex.h"
17#include "nluadef.h"
18#include "render.h"
19
20static int nlua_canvas_counter = 0;
21static GLuint previous_fbo = 0;
22static int previous_fbo_set = 0;
23static int was_scissored = 0;
24
25/* Canvas metatable methods. */
26static int canvasL_gc( lua_State *L );
27static int canvasL_eq( lua_State *L );
28static int canvasL_new( lua_State *L );
29static int canvasL_set( lua_State *L );
30static int canvasL_dims( lua_State *L );
31static int canvasL_getTex( lua_State *L );
32static int canvasL_clear( lua_State *L );
33
34static const luaL_Reg canvasL_methods[] = {
35 { "__gc", canvasL_gc }, { "__eq", canvasL_eq },
36 { "new", canvasL_new }, { "set", canvasL_set },
37 { "dims", canvasL_dims }, { "getTex", canvasL_getTex },
38 { "clear", canvasL_clear }, { 0, 0 } };
39
46int nlua_loadCanvas( nlua_env env )
47{
48 nlua_register( env, CANVAS_METATABLE, canvasL_methods, 1 );
49 return 0;
50}
51
66LuaCanvas_t *lua_tocanvas( lua_State *L, int ind )
67{
68 return (LuaCanvas_t *)lua_touserdata( L, ind );
69}
77LuaCanvas_t *luaL_checkcanvas( lua_State *L, int ind )
78{
79 if ( lua_iscanvas( L, ind ) )
80 return lua_tocanvas( L, ind );
81 luaL_typerror( L, ind, CANVAS_METATABLE );
82 return NULL;
83}
91LuaCanvas_t *lua_pushcanvas( lua_State *L, LuaCanvas_t canvas )
92{
93 LuaCanvas_t *c = (LuaCanvas_t *)lua_newuserdata( L, sizeof( LuaCanvas_t ) );
94 *c = canvas;
95 luaL_getmetatable( L, CANVAS_METATABLE );
96 lua_setmetatable( L, -2 );
97 return c;
98}
106int lua_iscanvas( lua_State *L, int ind )
107{
108 int ret;
109
110 if ( lua_getmetatable( L, ind ) == 0 )
111 return 0;
112 lua_getfield( L, LUA_REGISTRYINDEX, CANVAS_METATABLE );
113
114 ret = 0;
115 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
116 ret = 1;
117
118 lua_pop( L, 2 ); /* remove both metatables */
119 return ret;
120}
121
128static int canvasL_gc( lua_State *L )
129{
130 const LuaCanvas_t *lc = luaL_checkcanvas( L, 1 );
131 glDeleteFramebuffers( 1, &lc->fbo );
132 gl_freeTexture( lc->tex );
133 if ( lc->depth != 0 )
134 glDeleteTextures( 1, &lc->depth );
135 if ( gl_checkErr() )
136 NLUA_ERROR( L, _( "OpenGL Error!" ) );
137 return 0;
138}
139
148static int canvasL_eq( lua_State *L )
149{
150 LuaCanvas_t *c1 = luaL_checkcanvas( L, 1 );
151 LuaCanvas_t *c2 = luaL_checkcanvas( L, 2 );
152 lua_pushboolean( L, ( memcmp( c1, c2, sizeof( LuaCanvas_t ) ) == 0 ) );
153 return 1;
154}
155
163int canvas_new( LuaCanvas_t *lc, int w, int h )
164{
165 char *name;
166
167 memset( lc, 0, sizeof( LuaCanvas_t ) );
168
169 /* Create the texture. */
170 SDL_asprintf( &name, "nlua_canvas_%03d", ++nlua_canvas_counter );
171 lc->tex = gl_loadImageData( NULL, w, h, 1, 1, name );
172 lc->tex->flags |=
173 OPENGL_TEX_VFLIP; /* Long story, but love stuff inverts Y axis for
174 canvases so we have to redo that here for spob
175 targetting stuff to work properly. */
176 free( name );
177
178 /* Create the frame buffer. */
179 gl_fboCreate( &lc->fbo, &lc->tex->texture, w, h );
180
181 return 0;
182}
183
194static int canvasL_new( lua_State *L )
195{
196 LuaCanvas_t lc;
197
198 int w = luaL_checkint( L, 1 );
199 int h = luaL_checkint( L, 2 );
200 int depth = lua_toboolean( L, 3 );
201
202 if ( canvas_new( &lc, w, h ) )
203 return NLUA_ERROR( L, _( "Error setting up framebuffer!" ) );
204 if ( depth )
205 gl_fboAddDepth( lc.fbo, &lc.depth, w, h );
206 lua_pushcanvas( L, lc );
207 return 1;
208}
209
218static int canvasL_set( lua_State *L )
219{
220 if ( !lua_isnoneornil( L, 1 ) ) {
221 const LuaCanvas_t *lc = luaL_checkcanvas( L, 1 );
222 if ( !previous_fbo_set ) {
223 previous_fbo = gl_screen.current_fbo;
224 previous_fbo_set = 1;
225 was_scissored = glIsEnabled( GL_SCISSOR_TEST );
226 }
227 gl_screen.current_fbo = lc->fbo;
228 glDisable( GL_SCISSOR_TEST );
229 glViewport( 0, 0, lc->tex->w, lc->tex->h );
230 glBindFramebuffer( GL_FRAMEBUFFER, gl_screen.current_fbo );
231 render_needsReset();
232 } else
233 canvas_reset();
234
235 return 0;
236}
237
245static int canvasL_dims( lua_State *L )
246{
247 const LuaCanvas_t *lc = luaL_checkcanvas( L, 1 );
248 lua_pushnumber( L, lc->tex->w );
249 lua_pushnumber( L, lc->tex->h );
250 return 2;
251}
252
260static int canvasL_getTex( lua_State *L )
261{
262 const LuaCanvas_t *lc = luaL_checkcanvas( L, 1 );
263 lua_pushtex( L, gl_dupTexture( lc->tex ) );
264 return 1;
265}
266
274static int canvasL_clear( lua_State *L )
275{
276 const LuaCanvas_t *lc = luaL_checkcanvas( L, 1 );
277 (void)lc; /* Just to enforce good practice, canvas should be already set. */
278 const glColour *c = luaL_optcolour( L, 2, &cBlack );
279 glClearColor( c->r, c->g, c->b, c->a );
280 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
281 glClearColor( 0.0, 0.0, 0.0, 0.0 );
282 return 0;
283}
284
288void canvas_reset( void )
289{
290 if ( !previous_fbo_set )
291 return;
292 gl_screen.current_fbo = previous_fbo;
293 previous_fbo_set = 0;
294 if ( was_scissored )
295 glEnable( GL_SCISSOR_TEST );
296 glViewport( 0, 0, gl_screen.rw, gl_screen.rh );
297 glBindFramebuffer( GL_FRAMEBUFFER, gl_screen.current_fbo );
298}
glTexture ** lua_pushtex(lua_State *L, glTexture *texture)
Pushes a texture on the stack.
Definition nlua_tex.c:129
glInfo gl_screen
Definition opengl.c:47
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition opengl_tex.c:891
int gl_fboCreate(GLuint *fbo, GLuint *tex, GLsizei width, GLsizei height)
Creates a framebuffer and its associated texture.
Definition opengl_tex.c:268
int gl_fboAddDepth(GLuint fbo, GLuint *tex, GLsizei width, GLsizei height)
Adds a depth attachment to an FBO.
Definition opengl_tex.c:313
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition opengl_tex.c:835
static const double c[]
Definition rng.c:256
Wrapper to canvass.
Definition nlua_canvas.h:15
glTexture * tex
Definition nlua_canvas.h:17
GLuint depth
Definition nlua_canvas.h:18
double w
Definition opengl_tex.h:47
uint8_t flags
Definition opengl_tex.h:64
GLuint texture
Definition opengl_tex.h:59
double h
Definition opengl_tex.h:48