naev 0.12.6
nlua_gfx.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
11
12#include "naev.h"
14
15#include "nlua_gfx.h"
16
17#include "array.h"
18#include "font.h"
19#include "gltf.h"
20#include "nlua_canvas.h"
21#include "nlua_colour.h"
22#include "nlua_font.h"
23#include "nlua_shader.h"
24#include "nlua_tex.h"
25#include "nlua_transform.h"
26#include "nlua_vec2.h"
27#include "nluadef.h"
28#include "opengl.h"
29#include "render.h"
30
31/* GFX methods. */
32static int gfxL_dim( lua_State *L );
33static int gfxL_screencoords( lua_State *L );
34static int gfxL_renderTex( lua_State *L );
35static int gfxL_renderTexRaw( lua_State *L );
36static int gfxL_renderTexScale( lua_State *L );
37static int gfxL_renderTexH( lua_State *L );
38static int gfxL_renderRect( lua_State *L );
39static int gfxL_renderRectH( lua_State *L );
40static int gfxL_renderCircle( lua_State *L );
41static int gfxL_renderCircleH( lua_State *L );
42static int gfxL_renderLinesH( lua_State *L );
43static int gfxL_clearDepth( lua_State *L );
44static int gfxL_fontSize( lua_State *L );
45/* TODO get rid of printDim and print in favour of printfDim and printf */
46static int gfxL_printfDim( lua_State *L );
47static int gfxL_printfEnd( lua_State *L );
48static int gfxL_printfWrap( lua_State *L );
49static int gfxL_printRestoreClear( lua_State *L );
50static int gfxL_printRestoreLast( lua_State *L );
51static int gfxL_printf( lua_State *L );
52static int gfxL_printH( lua_State *L );
53static int gfxL_printDim( lua_State *L );
54static int gfxL_print( lua_State *L );
55static int gfxL_printText( lua_State *L );
56static int gfxL_setBlendMode( lua_State *L );
57static int gfxL_setBlendState( lua_State *L );
58static int gfxL_setScissor( lua_State *L );
59static int gfxL_lightAmbient( lua_State *L );
60static int gfxL_lightAmbientGet( lua_State *L );
61static int gfxL_lightIntensity( lua_State *L );
62static int gfxL_lightIntensityGet( lua_State *L );
63static int gfxL_screenshot( lua_State *L );
64static int gfxL_glVersion( lua_State *L );
65
66static const luaL_Reg gfxL_methods[] = {
67 /* Information. */
68 { "dim", gfxL_dim },
69 { "screencoords", gfxL_screencoords },
70 /* Render stuff. */
71 { "renderTex", gfxL_renderTex },
72 { "renderTexRaw", gfxL_renderTexRaw },
73 { "renderTexScale", gfxL_renderTexScale },
74 { "renderTexH", gfxL_renderTexH },
75 { "renderRect", gfxL_renderRect },
76 { "renderRectH", gfxL_renderRectH },
77 { "renderCircle", gfxL_renderCircle },
78 { "renderCircleH", gfxL_renderCircleH },
79 { "renderLinesH", gfxL_renderLinesH },
80 /* Printing. */
81 { "clearDepth", gfxL_clearDepth },
82 { "fontSize", gfxL_fontSize },
83 { "printfDim", gfxL_printfDim },
84 { "printfEnd", gfxL_printfEnd },
85 { "printfWrap", gfxL_printfWrap },
86 { "printRestoreClear", gfxL_printRestoreClear },
87 { "printRestoreLast", gfxL_printRestoreLast },
88 { "printf", gfxL_printf },
89 { "printH", gfxL_printH },
90 { "printDim", gfxL_printDim },
91 { "print", gfxL_print },
92 { "printText", gfxL_printText },
93 /* 3D rendering. */
94 { "lightAmbient", gfxL_lightAmbient },
95 { "lightAmbientGet", gfxL_lightAmbientGet },
96 { "lightIntensity", gfxL_lightIntensity },
97 { "lightIntensityGet", gfxL_lightIntensityGet },
98 /* Misc. */
99 { "setBlendMode", gfxL_setBlendMode },
100 { "setBlendState", gfxL_setBlendState },
101 { "setScissor", gfxL_setScissor },
102 { "screenshot", gfxL_screenshot },
103 { "glVersion", gfxL_glVersion },
104 { 0, 0 } };
105
112int nlua_loadGFX( nlua_env env )
113{
114 /* Register the values */
115 nlua_register( env, "gfx", gfxL_methods, 0 );
116
117 /* We also load the texture, colour, font, and transform modules as
118 * dependencies. */
119 nlua_loadCol( env );
120 nlua_loadTex( env );
121 nlua_loadFont( env );
122 nlua_loadTransform( env );
123 nlua_loadShader( env );
124 nlua_loadCanvas( env );
125
126 return 0;
127}
128
141
154static int gfxL_dim( lua_State *L )
155{
156 if ( lua_isboolean( L, 1 ) ) {
157 lua_pushnumber( L, SCREEN_W );
158 lua_pushnumber( L, SCREEN_H );
159 } else {
160 lua_pushnumber( L, gl_screen.nw );
161 lua_pushnumber( L, gl_screen.nh );
162 }
163 lua_pushnumber( L, gl_screen.scale );
164 return 3;
165}
166
175static int gfxL_screencoords( lua_State *L )
176{
177 vec2 screen;
178 double x, y;
179 const vec2 *game = luaL_checkvector( L, 1 );
180 int invert = lua_toboolean( L, 2 );
181 gl_gameToScreenCoords( &x, &y, game->x, game->y );
182 if ( invert )
183 y = SCREEN_H - y;
184 vec2_cset( &screen, x, y );
185 lua_pushvector( L, screen );
186 return 1;
187}
188
210static int gfxL_renderTex( lua_State *L )
211{
212 const glTexture *tex;
213 const glColour *col;
214 double x, y;
215 int sx, sy;
216
217 /* Parameters. */
218 tex = luaL_checktex( L, 1 );
219 x = luaL_checknumber( L, 2 );
220 y = luaL_checknumber( L, 3 );
221 if ( lua_isnumber( L, 4 ) ) {
222 sx = luaL_checkinteger( L, 4 ) - 1;
223 sy = luaL_checkinteger( L, 5 ) - 1;
224 col = luaL_optcolour( L, 6, &cWhite );
225 } else {
226 sx = 0;
227 sy = 0;
228 col = luaL_optcolour( L, 4, &cWhite );
229 }
230
231 /* Some safety checking. */
232#if DEBUGGING
233 if ( sx < 0 || sx >= tex->sx )
234 return NLUA_ERROR( L,
235 _( "Texture '%s' trying to render out of bounds (X "
236 "position) sprite: %d > %d." ),
237 tex->name, sx + 1, tex->sx );
238 if ( sy < 0 || sy >= tex->sy )
239 return NLUA_ERROR( L,
240 _( "Texture '%s' trying to render out of bounds (Y "
241 "position) sprite: %d > %d." ),
242 tex->name, sy + 1, tex->sy );
243#endif /* DEBUGGING */
244
245 /* Render. */
246 gl_renderStaticSprite( tex, x, y, sx, sy, col );
247
248 return 0;
249}
250
265static int gfxL_renderTexScale( lua_State *L )
266{
267 const glTexture *tex;
268 const glColour *col;
269 double x, y, bw, bh;
270 int sx, sy;
271
272 /* Parameters. */
273 col = NULL;
274 tex = luaL_checktex( L, 1 );
275 x = luaL_checknumber( L, 2 );
276 y = luaL_checknumber( L, 3 );
277 bw = luaL_checknumber( L, 4 );
278 bh = luaL_checknumber( L, 5 );
279 if ( lua_isnumber( L, 6 ) ) {
280 sx = luaL_checkinteger( L, 6 ) - 1;
281 sy = luaL_checkinteger( L, 7 ) - 1;
282 if ( lua_iscolour( L, 8 ) )
283 col = luaL_checkcolour( L, 8 );
284 } else {
285 sx = 0;
286 sy = 0;
287 if ( lua_iscolour( L, 6 ) )
288 col = luaL_checkcolour( L, 4 );
289 }
290
291 /* Some safety checking. */
292#if DEBUGGING
293 if ( sx >= tex->sx )
294 return NLUA_ERROR( L,
295 _( "Texture '%s' trying to render out of bounds (X "
296 "position) sprite: %d > %d." ),
297 tex->name, sx + 1, tex->sx );
298 if ( sx >= tex->sx )
299 return NLUA_ERROR( L,
300 _( "Texture '%s' trying to render out of bounds (Y "
301 "position) sprite: %d > %d." ),
302 tex->name, sy + 1, tex->sy );
303#endif /* DEBUGGING */
304
305 /* Render. */
306 gl_renderScaleSprite( tex, x, y, sx, sy, bw, bh, col );
307
308 return 0;
309}
310
338static int gfxL_renderTexRaw( lua_State *L )
339{
340 const glTexture *t;
341 const glColour *col;
342 double px, py, pw, ph, tx, ty, tw, th;
343 double angle;
344 int sx, sy;
345
346 /* Parameters. */
347 t = luaL_checktex( L, 1 );
348 px = luaL_checknumber( L, 2 );
349 py = luaL_checknumber( L, 3 );
350 pw = luaL_checknumber( L, 4 );
351 ph = luaL_checknumber( L, 5 );
352 sx = luaL_optinteger( L, 6, 1 ) - 1;
353 sy = luaL_optinteger( L, 7, 1 ) - 1;
354 tx = luaL_optnumber( L, 8, 0. );
355 ty = luaL_optnumber( L, 9, 0. );
356 tw = luaL_optnumber( L, 10, 1. );
357 th = luaL_optnumber( L, 11, 1. );
358 col = luaL_optcolour( L, 12, &cWhite );
359 angle = luaL_optnumber( L, 13, 0. );
360
361 /* Some safety checking. */
362#if DEBUGGING
363 if ( sx >= t->sx )
364 return NLUA_ERROR( L,
365 _( "Texture '%s' trying to render out of bounds (X "
366 "position) sprite: %d > %d." ),
367 t->name, sx + 1, t->sx );
368 if ( sx >= t->sx )
369 return NLUA_ERROR( L,
370 _( "Texture '%s' trying to render out of bounds (Y "
371 "position) sprite: %d > %d." ),
372 t->name, sy + 1, t->sy );
373#endif /* DEBUGGING */
374
375 /* Translate as needed. */
376 tx = ( tx * t->sw + t->sw * (double)( sx ) ) / t->w;
377 tw = tw * t->srw;
378 if ( tw < 0 )
379 tx -= tw;
380 ty = ( ty * t->sh + t->sh * ( t->sy - (double)sy - 1 ) ) / t->h;
381 th = th * t->srh;
382 if ( th < 0 )
383 ty -= th;
384
385 gl_renderTexture( t, px, py, pw, ph, tx, ty, tw, th, col, angle );
386 return 0;
387}
388
398static int gfxL_renderTexH( lua_State *L )
399{
400 const glTexture *t;
401 const glColour *col;
402 LuaShader_t *shader;
403 mat4 *H, *TH, ID;
404
405 ID = mat4_identity();
406
407 /* Parameters. */
408 t = luaL_checktex( L, 1 );
409 shader = luaL_checkshader( L, 2 );
410 H = luaL_checktransform( L, 3 );
411 col = luaL_optcolour( L, 4, &cWhite );
412 TH = luaL_opttransform( L, 5, &ID );
413
414 glUseProgram( shader->program );
415
416 /* Set the vertex. */
417 glEnableVertexAttribArray( shader->VertexPosition );
418 gl_vboActivateAttribOffset( gl_squareVBO, shader->VertexPosition, 0, 2,
419 GL_FLOAT, 0 );
420
421 /* Set up texture vertices if necessary. */
422 if ( shader->VertexTexCoord >= 0 ) {
423 gl_uniformMat4( shader->ViewSpaceFromLocal, TH );
424 glEnableVertexAttribArray( shader->VertexTexCoord );
425 gl_vboActivateAttribOffset( gl_squareVBO, shader->VertexTexCoord, 0, 2,
426 GL_FLOAT, 0 );
427 }
428
429 /* Set the texture(s). */
430 glBindTexture( GL_TEXTURE_2D, t->texture );
431 glUniform1i( shader->MainTex, 0 );
432 for ( int i = 0; i < array_size( shader->tex ); i++ ) {
433 LuaTexture_t *lt = &shader->tex[i];
434 glActiveTexture( lt->active );
435 glBindTexture( GL_TEXTURE_2D, lt->texid );
436 glUniform1i( lt->uniform, lt->value );
437 }
438 glActiveTexture( GL_TEXTURE0 );
439
440 /* Set shader uniforms. */
441 gl_uniformColour( shader->ConstantColour, col );
442 gl_uniformMat4( shader->ClipSpaceFromLocal, H );
443
444 /* Draw. */
445 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
446
447 /* Clear state. */
448 glDisableVertexAttribArray( shader->VertexPosition );
449 if ( shader->VertexTexCoord >= 0 )
450 glDisableVertexAttribArray( shader->VertexTexCoord );
451
452 /* anything failed? */
453 if ( gl_checkErr() )
454 NLUA_ERROR( L, _( "OpenGL Error!" ) );
455
456 glUseProgram( 0 );
457
458 return 0;
459}
460
477static int gfxL_renderRect( lua_State *L )
478{
479 const glColour *col;
480 double x, y, w, h;
481 int empty;
482
483 /* Parse parameters. */
484 x = luaL_checknumber( L, 1 );
485 y = luaL_checknumber( L, 2 );
486 w = luaL_checknumber( L, 3 );
487 h = luaL_checknumber( L, 4 );
488 col = luaL_checkcolour( L, 5 );
489 empty = lua_toboolean( L, 6 );
490
491 /* Render. */
492 if ( empty )
493 gl_renderRectEmpty( x, y, w, h, col );
494 else
495 gl_renderRect( x, y, w, h, col );
496
497 return 0;
498}
499
508static int gfxL_renderRectH( lua_State *L )
509{
510 /* Parse parameters. */
511 const mat4 *H = luaL_checktransform( L, 1 );
512 const glColour *col = luaL_optcolour( L, 2, &cWhite );
513 int empty = lua_toboolean( L, 3 );
514
515 /* Render. */
516 gl_renderRectH( H, col, !empty );
517
518 return 0;
519}
520
531static int gfxL_renderCircle( lua_State *L )
532{
533 const glColour *col;
534 double x, y, r;
535 int empty;
536
537 /* Parse parameters. */
538 x = luaL_checknumber( L, 1 );
539 y = luaL_checknumber( L, 2 );
540 r = luaL_checknumber( L, 3 );
541 col = luaL_checkcolour( L, 4 );
542 empty = lua_toboolean( L, 5 );
543
544 /* Render. */
545 gl_renderCircle( x, y, r, col, !empty );
546 return 0;
547}
548
557static int gfxL_renderCircleH( lua_State *L )
558{
559 /* Parse parameters. */
560 const mat4 *H = luaL_checktransform( L, 1 );
561 const glColour *col = luaL_optcolour( L, 2, &cWhite );
562 int empty = lua_toboolean( L, 3 );
563
564 /* Render. */
565 gl_renderCircleH( H, col, !empty );
566 return 0;
567}
568
569static gl_vbo *vbo_lines = NULL;
581static int gfxL_renderLinesH( lua_State *L )
582{
583 GLfloat buf[256 * 2];
584 int i = 3;
585 GLuint n = 0;
586 const mat4 *H = luaL_checktransform( L, 1 );
587 const glColour *c = luaL_optcolour( L, 2, &cWhite );
588
589 if ( vbo_lines == NULL )
590 vbo_lines = gl_vboCreateDynamic( 256 * sizeof( GLfloat ) * 2, NULL );
591
592 while ( !lua_isnoneornil( L, i ) ) {
593 if ( n >= 256 ) {
594 NLUA_WARN( L, _( "Trying to draw too many lines in one call!" ) );
595 n = 256;
596 break;
597 }
598
599 if ( lua_isnumber( L, i ) ) {
600 double x = luaL_checknumber( L, i );
601 double y = luaL_checknumber( L, i + 1 );
602 buf[2 * n + 0] = x;
603 buf[2 * n + 1] = y;
604 n++;
605 i += 2;
606 } else {
607 const vec2 *v = luaL_checkvector( L, i );
608 buf[2 * n + 0] = v->x;
609 buf[2 * n + 1] = v->y;
610 n++;
611 i += 1;
612 }
613 }
614
615 glUseProgram( shaders.lines.program );
616
617 gl_vboData( vbo_lines, sizeof( GLfloat ) * 2 * n, buf );
618 glEnableVertexAttribArray( shaders.lines.vertex );
619 gl_vboActivateAttribOffset( vbo_lines, shaders.lines.vertex, 0, 2, GL_FLOAT,
620 2 * sizeof( GLfloat ) );
621
622 gl_uniformColour( shaders.lines.colour, c );
623 gl_uniformMat4( shaders.lines.projection, H );
624
625 glDrawArrays( GL_LINE_STRIP, 0, n );
626 glUseProgram( 0 );
627
628 /* Check for errors. */
629 if ( gl_checkErr() )
630 NLUA_ERROR( L, _( "OpenGL Error!" ) );
631
632 return 0;
633}
634
638static int gfxL_clearDepth( lua_State *L )
639{
640 (void)L;
641 glClear( GL_DEPTH_BUFFER_BIT );
642 if ( gl_checkErr() )
643 NLUA_ERROR( L, _( "OpenGL Error!" ) );
644 return 0;
645}
646
654static int gfxL_fontSize( lua_State *L )
655{
656 int small = lua_toboolean( L, 1 );
657 lua_pushnumber( L, small ? gl_smallFont.h : gl_defFont.h );
658 return 1;
659}
660
675static int gfxL_printDim( lua_State *L )
676{
677 const char *str;
678 int width;
679 const glFont *font;
680
681 /* Parse parameters. */
682 font = lua_toboolean( L, 1 ) ? &gl_smallFont : &gl_defFont;
683 str = luaL_checkstring( L, 2 );
684 width = luaL_optinteger( L, 3, 0 );
685
686 /* Print length. */
687 if ( width == 0 )
688 lua_pushnumber( L, gl_printWidthRaw( font, str ) );
689 else
690 lua_pushnumber( L, gl_printHeightRaw( font, width, str ) );
691 return 1;
692}
693
704static int gfxL_printfDim( lua_State *L )
705{
706 const char *str;
707 int width;
708 const glFont *font;
709
710 /* Parse parameters. */
711 font = luaL_checkfont( L, 1 );
712 str = luaL_checkstring( L, 2 );
713 width = luaL_optinteger( L, 3, 0 );
714
715 /* Print length. */
716 if ( width == 0 )
717 lua_pushnumber( L, gl_printWidthRaw( font, str ) );
718 else
719 lua_pushnumber( L, gl_printHeightRaw( font, width, str ) );
720 return 1;
721}
722
734static int gfxL_printfEnd( lua_State *L )
735{
736 const char *str;
737 int width;
738 const glFont *font;
739 int x, y;
740
741 /* Parse parameters. */
742 font = luaL_checkfont( L, 1 );
743 str = luaL_checkstring( L, 2 );
744 width = luaL_checkinteger( L, 3 );
745
746 /* Print length. */
747 gl_printEndRaw( &x, &y, font, width, str );
748 lua_pushinteger( L, x );
749 lua_pushinteger( L, y );
750 return 2;
751}
752
763static int gfxL_printfWrap( lua_State *L )
764{
765 const char *s;
766 int width, maxw;
767 const glFont *font;
769 int linenum;
770
771 /* Parse parameters. */
772 font = luaL_checkfont( L, 1 );
773 s = luaL_checkstring( L, 2 );
774 width = luaL_checkinteger( L, 3 );
775 if ( width < 0 )
776 return NLUA_ERROR( L, _( "width has to be a positive value." ) );
777
778 /* Process output into table. */
779 lua_newtable( L );
780 gl_printLineIteratorInit( &iter, font, s, width );
781 linenum = 1;
782 maxw = 0;
783 while ( gl_printLineIteratorNext( &iter ) ) {
784 maxw = MAX( maxw, iter.l_width );
785
786 /* Create entry of form { string, width } in the table. */
787 lua_newtable( L ); /* t, t */
788 lua_pushlstring( L, &s[iter.l_begin],
789 iter.l_end - iter.l_begin ); /* t, t, s */
790 lua_rawseti( L, -2, 1 ); /* t, t */
791 lua_pushinteger( L, iter.l_width ); /* t, t, n */
792 lua_rawseti( L, -2, 2 ); /* t, t */
793 lua_rawseti( L, -2, linenum++ ); /* t */
794 }
795
796 /* Push max width. */
797 lua_pushinteger( L, maxw );
798
799 return 2;
800}
801
806static int gfxL_printRestoreClear( lua_State *L )
807{
808 (void)L;
810 return 0;
811}
812
817static int gfxL_printRestoreLast( lua_State *L )
818{
819 (void)L;
821 return 0;
822}
823
839static int gfxL_printf( lua_State *L )
840{
841 const glFont *font;
842 const char *str;
843 double x, y;
844 const glColour *col;
845 int max, mid;
846
847 /* Parse parameters. */
848 font = luaL_checkfont( L, 1 );
849 str = luaL_checkstring( L, 2 );
850 x = luaL_checknumber( L, 3 );
851 y = luaL_checknumber( L, 4 );
852 col = luaL_checkcolour( L, 5 );
853 max = luaL_optinteger( L, 6, 0 );
854 mid = lua_toboolean( L, 7 );
855
856 /* Render. */
857 if ( mid )
858 gl_printMidRaw( font, max, x, y, col, 0., str );
859 else if ( max > 0 )
860 gl_printMaxRaw( font, max, x, y, col, 0., str );
861 else
862 gl_printRaw( font, x, y, col, 0., str );
863 return 0;
864}
865
876static int gfxL_printH( lua_State *L )
877{
878 const mat4 *H;
879 const glFont *font;
880 const char *str;
881 const glColour *col;
882 double outline;
883
884 /* Parse parameters. */
885 H = luaL_checktransform( L, 1 );
886 font = luaL_checkfont( L, 2 );
887 str = luaL_checkstring( L, 3 );
888 col = luaL_optcolour( L, 4, &cWhite );
889 outline = luaL_optnumber( L, 5, 0. );
890
891 /* Render. */
892 gl_printRawH( font, H, col, outline, str );
893 return 0;
894}
895
915static int gfxL_print( lua_State *L )
916{
917 const glFont *font;
918 const char *str;
919 double x, y;
920 const glColour *col;
921 int max, mid;
922
923 /* Parse parameters. */
924 font = lua_toboolean( L, 1 ) ? &gl_smallFont : &gl_defFont;
925 str = luaL_checkstring( L, 2 );
926 x = luaL_checknumber( L, 3 );
927 y = luaL_checknumber( L, 4 );
928 col = luaL_checkcolour( L, 5 );
929 max = luaL_optinteger( L, 6, 0 );
930 mid = lua_toboolean( L, 7 );
931
932 /* Render. */
933 if ( mid )
934 gl_printMidRaw( font, max, x, y, col, -1., str );
935 else if ( max > 0 )
936 gl_printMaxRaw( font, max, x, y, col, -1., str );
937 else
938 gl_printRaw( font, x, y, col, -1., str );
939 return 0;
940}
941
958static int gfxL_printText( lua_State *L )
959{
960 const glFont *font;
961 const char *str;
962 int w, h, lh;
963 double x, y;
964 const glColour *col;
965
966 /* Parse parameters. */
967 font = lua_toboolean( L, 1 ) ? &gl_smallFont : &gl_defFont;
968 str = luaL_checkstring( L, 2 );
969 x = luaL_checknumber( L, 3 );
970 y = luaL_checknumber( L, 4 );
971 w = luaL_checkinteger( L, 5 );
972 h = luaL_checkinteger( L, 6 );
973 col = luaL_checkcolour( L, 7 );
974 lh = luaL_optinteger( L, 8, 0 );
975
976 /* Render. */
977 gl_printTextRaw( font, w, h, x, y, lh, col, -1., str );
978
979 return 0;
980}
981
995static int gfxL_setBlendMode( lua_State *L )
996{
997 const char *mode, *alphamode;
998 GLenum func, srcRGB, srcA, dstRGB, dstA;
999
1000 /* Parse parameters. */
1001 mode = luaL_checkstring( L, 1 );
1002 alphamode = luaL_optstring( L, 2, "alphamultiply" );
1003
1004 /* Translate to OpenGL enums. */
1005 func = GL_FUNC_ADD;
1006 srcRGB = GL_ONE;
1007 srcA = GL_ONE;
1008 dstRGB = GL_ZERO;
1009 dstA = GL_ZERO;
1010
1011 if ( !strcmp( alphamode, "alphamultiply" ) )
1012 srcRGB = srcA = GL_SRC_ALPHA;
1013 else if ( !strcmp( alphamode, "premultiplied" ) ) {
1014 if ( !strcmp( mode, "lighten" ) || !strcmp( mode, "darken" ) ||
1015 !strcmp( mode, "multiply" ) )
1016 NLUA_INVALID_PARAMETER( L, 2 );
1017 } else
1018 NLUA_INVALID_PARAMETER( L, 2 );
1019
1020 if ( !strcmp( mode, "alpha" ) )
1021 dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA;
1022 else if ( !strcmp( mode, "multiply" ) )
1023 srcRGB = srcA = GL_DST_COLOR;
1024 else if ( !strcmp( mode, "subtract" ) )
1025 func = GL_FUNC_REVERSE_SUBTRACT;
1026 else if ( !strcmp( mode, "add" ) ) {
1027 func = GL_FUNC_REVERSE_SUBTRACT;
1028 srcA = GL_ZERO;
1029 dstRGB = dstA = GL_ONE;
1030 } else if ( !strcmp( mode, "lighten" ) )
1031 func = GL_MAX;
1032 else if ( !strcmp( mode, "darken" ) )
1033 func = GL_MIN;
1034 else if ( !strcmp( mode, "screen" ) )
1035 dstRGB = dstA = GL_ONE_MINUS_SRC_COLOR;
1036 else if ( strcmp( mode, "replace" ) )
1037 NLUA_INVALID_PARAMETER( L, 1 );
1038
1039 glBlendEquation( func );
1040 glBlendFuncSeparate( srcRGB, dstRGB, srcA, dstA );
1041 if ( gl_checkErr() )
1042 NLUA_ERROR( L, _( "OpenGL Error!" ) );
1043
1044 render_needsReset();
1045 return 0;
1046}
1047
1056static int gfxL_setBlendState( lua_State *L )
1057{
1058 GLenum funcRGB, srcRGB, dstRGB;
1059
1060 funcRGB = gl_stringToBlendFunc( luaL_checkstring( L, 1 ) );
1061 if ( lua_gettop( L ) <= 3 ) {
1062 srcRGB = gl_stringToBlendFactor( luaL_checkstring( L, 2 ) );
1063 dstRGB = gl_stringToBlendFactor( luaL_checkstring( L, 3 ) );
1064
1065 glBlendEquation( funcRGB );
1066 glBlendFunc( srcRGB, dstRGB );
1067 } else {
1068 GLenum funcA, srcA, dstA;
1069 funcA = gl_stringToBlendFunc( luaL_checkstring( L, 2 ) );
1070 srcRGB = gl_stringToBlendFactor( luaL_checkstring( L, 3 ) );
1071 srcA = gl_stringToBlendFactor( luaL_checkstring( L, 4 ) );
1072 dstRGB = gl_stringToBlendFactor( luaL_checkstring( L, 5 ) );
1073 dstA = gl_stringToBlendFactor( luaL_checkstring( L, 6 ) );
1074
1075 glBlendEquationSeparate( funcRGB, funcA );
1076 glBlendFuncSeparate( srcRGB, dstRGB, srcA, dstA );
1077 }
1078
1079 if ( gl_checkErr() )
1080 NLUA_ERROR( L, _( "OpenGL Error!" ) );
1081
1082 render_needsReset();
1083 return 0;
1084}
1085
1097static int gfxL_setScissor( lua_State *L )
1098{
1099 if ( lua_gettop( L ) > 0 ) {
1100 GLint x = luaL_optinteger( L, 1, 0 );
1101 GLint y = luaL_optinteger( L, 2, 0 );
1102 GLsizei w = luaL_optinteger( L, 3, 0 );
1103 GLsizei h = luaL_optinteger( L, 4, 0 );
1104 gl_clipRect( x, y, w, h );
1105 render_needsReset();
1106 } else
1107 gl_unclipRect();
1108
1109 if ( gl_checkErr() )
1110 NLUA_ERROR( L, _( "OpenGL Error!" ) );
1111
1112 return 0;
1113}
1114
1123static int gfxL_screenshot( lua_State *L )
1124{
1125 LuaCanvas_t *lc;
1126 int mustfree;
1127
1128 /* Set up canvas or try to reuse. */
1129 if ( lua_iscanvas( L, 1 ) ) {
1130 lc = luaL_checkcanvas( L, 1 );
1131 mustfree = 0;
1132 } else {
1133 lc = calloc( 1, sizeof( LuaCanvas_t ) );
1134 canvas_new( lc, gl_screen.rw, gl_screen.rh );
1135 mustfree = 1;
1136 }
1137
1138 /* Copy over. */
1139 glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
1140 glBindFramebuffer( GL_DRAW_FRAMEBUFFER, lc->fbo );
1141 /* We flip it over because that seems to be what love2d API wants. */
1142 glBlitFramebuffer( 0, 0, gl_screen.rw, gl_screen.rh, 0, lc->tex->h,
1143 lc->tex->w, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST );
1144 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
1145
1146 /* Return new or old canvas. */
1147 lua_pushcanvas( L, *lc );
1148 if ( mustfree )
1149 free( lc );
1150
1151 if ( gl_checkErr() )
1152 NLUA_ERROR( L, _( "OpenGL Error!" ) );
1153 return 1;
1154}
1155
1169static int gfxL_lightAmbient( lua_State *L )
1170{
1171 double r, g, b;
1172 if ( lua_iscolour( L, 1 ) ) {
1173 const glColour *c = lua_tocolour( L, 1 );
1174 double n = c->a * sqrt( pow2( c->r ) + pow2( c->g ) + pow2( c->b ) );
1175 /* Premultiply alpha. */
1176 r = c->r * n;
1177 g = c->g * n;
1178 b = c->b * n;
1179 } else {
1180 r = luaL_checknumber( L, 1 );
1181 g = luaL_optnumber( L, 2, r );
1182 b = luaL_optnumber( L, 3, r );
1183 if ( !lua_isnoneornil( L, 4 ) ) {
1184 double n = luaL_checknumber( L, 4 ) /
1185 sqrt( pow2( r ) + pow2( g ) + pow2( b ) );
1186 r *= n;
1187 g *= n;
1188 b *= n;
1189 }
1190 }
1191 gltf_lightAmbient( r, g, b );
1192 return 0;
1193}
1194
1203static int gfxL_lightAmbientGet( lua_State *L )
1204{
1205 double r, g, b;
1206 gltf_lightAmbientGet( &r, &g, &b );
1207 lua_pushnumber( L, r );
1208 lua_pushnumber( L, g );
1209 lua_pushnumber( L, b );
1210 return 3;
1211}
1212
1220static int gfxL_lightIntensity( lua_State *L )
1221{
1222 gltf_lightIntensity( luaL_checknumber( L, 1 ) );
1223 return 0;
1224}
1225
1232static int gfxL_lightIntensityGet( lua_State *L )
1233{
1234 lua_pushnumber( L, gltf_lightIntensityGet() );
1235 return 1;
1236}
1237
1246static int gfxL_glVersion( lua_State *L )
1247{
1248 lua_pushinteger( L, gl_screen.major );
1249 lua_pushinteger( L, gl_screen.minor );
1250 lua_pushinteger( L, gl_screen.glsl );
1251 return 3;
1252}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
Definition font.c:1050
void gl_printRestoreClear(void)
Clears the restoration.
Definition font.c:398
int gl_printLineIteratorNext(glPrintLineIterator *iter)
Updates iter with the next line's information.
Definition font.c:550
glFont gl_smallFont
Definition font.c:159
void gl_printRaw(const glFont *ft_font, double x, double y, const glColour *c, double outlineR, const char *text)
Prints text on screen.
Definition font.c:646
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
Definition font.c:984
glFont gl_defFont
Definition font.c:158
int gl_printMidRaw(const glFont *ft_font, int width, double x, double y, const glColour *c, double outlineR, const char *text)
Displays text centered in position and width.
Definition font.c:821
int gl_printTextRaw(const glFont *ft_font, const int width, const int height, double bx, double by, int line_height, const glColour *c, double outlineR, const char *text)
Prints a block of text that fits in the dimensions given.
Definition font.c:895
void gl_printRawH(const glFont *ft_font, const mat4 *H, const glColour *c, const double outlineR, const char *text)
Prints text on screen using a transformation matrix.
Definition font.c:680
void gl_printLineIteratorInit(glPrintLineIterator *iter, const glFont *ft_font, const char *text, int width)
Initialize an iterator object for breaking text into lines.
Definition font.c:528
int gl_printMaxRaw(const glFont *ft_font, const int max, double x, double y, const glColour *c, double outlineR, const char *text)
Behaves like gl_printRaw but stops displaying text after a certain distance.
Definition font.c:753
void gl_printRestoreLast(void)
Restores last colour.
Definition font.c:406
int gl_printEndRaw(int *xo, int *yo, const glFont *ft_font, int width, const char *text)
Gets the position at which text would end writing.
Definition font.c:1107
mat4 mat4_identity(void)
Creates an identity matrix.
Definition mat4.c:335
Header file with generic functions and naev-specifics.
#define pow2(x)
Definition naev.h:53
#define MAX(x, y)
Definition naev.h:37
int lua_iscolour(lua_State *L, int ind)
Checks to see if ind is a colour.
int nlua_loadCol(nlua_env env)
Loads the colour library.
Definition nlua_colour.c:57
glColour * lua_tocolour(lua_State *L, int ind)
Lua bindings to interact with colours.
Definition nlua_colour.c:87
glColour * luaL_checkcolour(lua_State *L, int ind)
Gets colour at index or raises error if there is no colour at index.
Definition nlua_colour.c:98
int nlua_loadFont(nlua_env env)
Loads the font library.
Definition nlua_font.c:43
glFont * luaL_checkfont(lua_State *L, int ind)
Gets font at index or raises error if there is no font at index.
Definition nlua_font.c:72
static int gfxL_renderTexScale(lua_State *L)
DEPRECATED: Renders a texture, scaled. Ultimately, love.graphics should handle this.
Definition nlua_gfx.c:265
static int gfxL_renderRectH(lua_State *L)
Renders a rectangle given a transformation matrix.
Definition nlua_gfx.c:508
static int gfxL_screencoords(lua_State *L)
Gets the screen coordinates from game coordinates.
Definition nlua_gfx.c:175
static int gfxL_lightAmbient(lua_State *L)
Sets the ambient lighting.
Definition nlua_gfx.c:1169
static int gfxL_dim(lua_State *L)
Lua bindings to interact with rendering and the Naev graphical environment.
Definition nlua_gfx.c:154
static int gfxL_renderRect(lua_State *L)
Renders a rectangle.
Definition nlua_gfx.c:477
static const luaL_Reg gfxL_methods[]
Definition nlua_gfx.c:66
static int gfxL_printText(lua_State *L)
Prints a block of text on the screen.
Definition nlua_gfx.c:958
static int gfxL_printf(lua_State *L)
Prints text on the screen using a font.
Definition nlua_gfx.c:839
static int gfxL_screenshot(lua_State *L)
Takes the current rendered game screen and returns it as a canvas.
Definition nlua_gfx.c:1123
static int gfxL_renderTexH(lua_State *L)
Renders a texture using a transformation matrix.
Definition nlua_gfx.c:398
static int gfxL_lightAmbientGet(lua_State *L)
Gets the ambient lighting values.
Definition nlua_gfx.c:1203
static int gfxL_renderTex(lua_State *L)
Renders a texture.
Definition nlua_gfx.c:210
static int gfxL_printfWrap(lua_State *L)
Gets the wrap for text.
Definition nlua_gfx.c:763
static int gfxL_printfDim(lua_State *L)
Gets the size of the text to print.
Definition nlua_gfx.c:704
static int gfxL_clearDepth(lua_State *L)
Clears the depth buffer.
Definition nlua_gfx.c:638
static int gfxL_setBlendMode(lua_State *L)
Sets the OpenGL blending mode. See https://love2d.org/wiki/love.graphics.setBlendMode as of version 0...
Definition nlua_gfx.c:995
static int gfxL_renderLinesH(lua_State *L)
Renders a polyline or set of line segments.
Definition nlua_gfx.c:581
static int gfxL_setBlendState(lua_State *L)
Sets the OpenGL blending state. See https://love2d.org/wiki/love.graphics.setBlendState as of version...
Definition nlua_gfx.c:1056
static int gfxL_lightIntensityGet(lua_State *L)
Gets the light intensity.
Definition nlua_gfx.c:1232
static int gfxL_renderCircle(lua_State *L)
Renders a circle.
Definition nlua_gfx.c:531
static int gfxL_glVersion(lua_State *L)
Gets the OpenGL version.
Definition nlua_gfx.c:1246
static int gfxL_printRestoreLast(lua_State *L)
Restores the last saved internal colour state.
Definition nlua_gfx.c:817
static int gfxL_printH(lua_State *L)
Prints text on the screen using a font with a transformation matirx.
Definition nlua_gfx.c:876
int nlua_loadGFX(nlua_env env)
Loads the graphics library.
Definition nlua_gfx.c:112
static int gfxL_renderCircleH(lua_State *L)
Renders a circle given a transformation matrix.
Definition nlua_gfx.c:557
static int gfxL_lightIntensity(lua_State *L)
Sets the intensity of the main lights excluding ambient lighting. Multiplies the default radiosity va...
Definition nlua_gfx.c:1220
static int gfxL_fontSize(lua_State *L)
Gets the size of the font.
Definition nlua_gfx.c:654
static int gfxL_printfEnd(lua_State *L)
Gets the position at which text would end printing. Can be the middle of a line.
Definition nlua_gfx.c:734
static int gfxL_renderTexRaw(lua_State *L)
Renders a texture using the core render function.
Definition nlua_gfx.c:338
static int gfxL_printDim(lua_State *L)
Gets the size of the text to print.
Definition nlua_gfx.c:675
static int gfxL_printRestoreClear(lua_State *L)
Clears the saved internal colour state.
Definition nlua_gfx.c:806
static int gfxL_print(lua_State *L)
Prints text on the screen.
Definition nlua_gfx.c:915
static int gfxL_setScissor(lua_State *L)
Sets the scissor clipping.
Definition nlua_gfx.c:1097
int nlua_loadShader(nlua_env env)
Loads the shader library.
Definition nlua_shader.c:54
LuaShader_t * luaL_checkshader(lua_State *L, int ind)
Gets shader at index or raises error if there is no shader at index.
Definition nlua_shader.c:83
glTexture * luaL_checktex(lua_State *L, int ind)
Gets texture at index or raises error if there is no texture at index.
Definition nlua_tex.c:97
int nlua_loadTex(nlua_env env)
Loads the texture library.
Definition nlua_tex.c:59
mat4 * luaL_checktransform(lua_State *L, int ind)
Gets transform at index or raises error if there is no transform at index.
int nlua_loadTransform(nlua_env env)
Loads the transform library.
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition nlua_vec2.c:130
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition nlua_vec2.c:145
GLenum gl_stringToBlendFactor(const char *s)
Gets a blend factor from a string.
Definition opengl.c:847
GLenum gl_stringToBlendFunc(const char *s)
Gets a blend function from a string.
Definition opengl.c:825
glInfo gl_screen
Definition opengl.c:47
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
void gl_renderCircleH(const mat4 *H, const glColour *c, int filled)
Draws a circle.
void gl_renderTexture(const glTexture *texture, double x, double y, double w, double h, double tx, double ty, double tw, double th, const glColour *c, double angle)
Texture blitting backend.
void gl_unclipRect(void)
Clears the 2d clipping planes.
void gl_renderScaleSprite(const glTexture *sprite, double bx, double by, int sx, int sy, double bw, double bh, const glColour *c)
Blits a scaled sprite, position is in absolute screen coordinates.
void gl_renderStaticSprite(const glTexture *sprite, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite, position is in absolute screen coordinates.
void gl_renderRectEmpty(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_renderRectH(const mat4 *H, const glColour *c, int filled)
Renders a rectangle.
void gl_clipRect(int x, int y, int w, int h)
Sets up 2d clipping planes around a rectangle.
void gl_renderCircle(double cx, double cy, double r, const glColour *c, int filled)
Draws a circle.
gl_vbo * gl_vboCreateDynamic(GLsizei size, const void *data)
Creates a dynamic vbo.
Definition opengl_vbo.c:160
void gl_vboActivateAttribOffset(gl_vbo *vbo, GLuint index, GLuint offset, GLint size, GLenum type, GLsizei stride)
Activates a VBO's offset.
Definition opengl_vbo.c:224
void gl_vboData(gl_vbo *vbo, GLsizei size, const void *data)
Reloads new data or grows the size of the vbo.
Definition opengl_vbo.c:96
static const double c[]
Definition rng.c:256
Wrapper to canvass.
Definition nlua_canvas.h:15
glTexture * tex
Definition nlua_canvas.h:17
Represents a font in memory.
Definition font.h:17
The state of a line iteration. This matches the process of rendering text into an on-screen box: An e...
Definition font.h:44
Abstraction for rendering sprite sheets.
Definition opengl_tex.h:43
double sw
Definition opengl_tex.h:53
double sh
Definition opengl_tex.h:54
double w
Definition opengl_tex.h:47
double sx
Definition opengl_tex.h:51
double srh
Definition opengl_tex.h:56
char * name
Definition opengl_tex.h:44
GLuint texture
Definition opengl_tex.h:59
double sy
Definition opengl_tex.h:52
double h
Definition opengl_tex.h:48
double srw
Definition opengl_tex.h:55
Definition mat4.h:12
Represents a 2d vector.
Definition vec2.h:45
double y
Definition vec2.h:47
double x
Definition vec2.h:46