naev 0.11.5
background.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include "naev.h"
13#include "background.h"
14
15#include "array.h"
16#include "camera.h"
17#include "conf.h"
18#include "log.h"
19#include "gui.h"
20#include "ndata.h"
21#include "nebula.h"
22#include "nlua.h"
23#include "nlua_audio.h"
24#include "nlua_bkg.h"
25#include "nlua_colour.h"
26#include "nlua_tex.h"
27#include "nlua_camera.h"
28#include "nlua_gfx.h"
29#include "nluadef.h"
30#include "nstring.h"
31#include "nxml.h"
32#include "opengl.h"
33#include "pause.h"
34#include "player.h"
35#include "rng.h"
36
40typedef struct background_image_s {
41 unsigned int id;
43 double x;
44 double y;
45 double move;
46 double scale;
47 double angle;
48 glColour col;
53static unsigned int bkg_idgen = 0;
58static nlua_env bkg_cur_env = LUA_NOREF;
59static nlua_env bkg_def_env = LUA_NOREF;
60static int bkg_L_renderbg = LUA_NOREF;
61static int bkg_L_rendermg = LUA_NOREF;
62static int bkg_L_renderfg = LUA_NOREF;
63static int bkg_L_renderov = LUA_NOREF;
65/*
66 * Background dust.
67 */
68#define STAR_BUF 250
69static gl_vbo *dust_vertexVBO = NULL;
70static unsigned int ndust = 0;
71static GLfloat dust_x = 0.;
72static GLfloat dust_y = 0.;
74/*
75 * Prototypes.
76 */
77static void background_renderImages( background_image_t *bkg_arr );
78static nlua_env background_create( const char *path );
79static void background_clearCurrent (void);
81/* Sorting. */
82static int bkg_compare( const void *p1, const void *p2 );
83static void bkg_sort( background_image_t *arr );
84
91{
92 GLfloat w, h, hw, hh;
93 double size;
94 GLfloat *dust_vertex;
95
96 /* Calculate size. */
97 size = SCREEN_W*SCREEN_H+STAR_BUF*STAR_BUF;
98 size /= pow2(conf.zoom_far);
99
100 /* Calculate dust buffer. */
101 w = (SCREEN_W + 2.*STAR_BUF);
102 w += (w / conf.zoom_far - 1.);
103 h = (SCREEN_H + 2.*STAR_BUF);
104 h += (h / conf.zoom_far - 1.);
105 hw = w / 2.;
106 hh = h / 2.;
107
108 /* Calculate dust. */
109 size *= n;
110 ndust = (unsigned int)(size/(800.*600.));
111
112 /* Create data. */
113 dust_vertex = malloc( ndust * sizeof(GLfloat) * 3 );
114
115 for (unsigned int i=0; i < ndust; i++) {
116 /* Set the position. */
117 dust_vertex[3*i+0] = RNGF()*w - hw;
118 dust_vertex[3*i+1] = RNGF()*h - hh;
119 /* Set the colour. */
120 dust_vertex[3*i+2] = RNGF()*0.6 + 0.2;
121 }
122
123 /* Recreate VBO. */
126 ndust * sizeof(GLfloat) * 3, dust_vertex );
127
128 free(dust_vertex);
129}
130
134void background_moveDust( double x, double y )
135{
136 dust_x += (GLfloat) x;
137 dust_y += (GLfloat) y;
138}
139
145void background_renderDust( const double dt )
146{
147 (void) dt;
148 GLfloat h, w, m;
149 double z, angle;
150 mat4 projection;
151 int points = 1;
152
153 /* Do some scaling for now. */
154 z = cam_getZoom();
155 m = 1.;
156 angle = 0.;
157 projection = gl_view_matrix;
158 mat4_translate( &projection, SCREEN_W/2., SCREEN_H/2., 0 );
159 mat4_scale( &projection, z, z, 1 );
160
161 /* Decide on shade mode. */
162 if ((player.p != NULL) && !player_isFlag(PLAYER_DESTROYED) &&
163 !player_isFlag(PLAYER_CREATING)) {
164 double dx, dy, vmod;
165
166 /* Get camera movement. */
167 cam_getVel( &dx, &dy );
168 vmod = hypot( dx, dy );
169
170 if (pilot_isFlag(player.p,PILOT_HYPERSPACE)) { /* hyperspace fancy effects */
171 /* lines get longer the closer we are to finishing the jump */
172 m = MAX( 0, HYPERSPACE_DUST_BLUR-player.p->ptimer );
173 if (m > 0.) {
174 m *= HYPERSPACE_DUST_LENGTH / HYPERSPACE_DUST_BLUR;
175 angle = atan2( dy, dx );
176 points = 0;
177 }
178 }
179 else if (dt_mod * vmod > 500. ) {
180 angle = atan2( dy, dx );
181 m = (dt_mod * vmod) / 25. - 20.;
182 points = 0;
183 }
184 }
185
186 /* Calculate some dimensions. */
187 w = (SCREEN_W + 2.*STAR_BUF);
188 w += (w / conf.zoom_far - 1.);
189 h = (SCREEN_H + 2.*STAR_BUF);
190 h += (h / conf.zoom_far - 1.);
191
192 /* Common shader stuff. */
193 glUseProgram(shaders.dust.program);
194 gl_uniformMat4(shaders.dust.projection, &projection);
195 glUniform2f(shaders.dust.offset_xy, dust_x, dust_y);
196 if (points)
197 glUniform3f(shaders.dust.dims, 2./gl_screen.scale, 0., 0.);
198 else
199 glUniform3f(shaders.dust.dims, MAX(1.,2.-m/20.)/gl_screen.scale, angle, m);
200 glUniform3f(shaders.dust.screen, w, h, 1. / gl_screen.scale);
201 glUniform1i(shaders.dust.use_lines, !points);
202
203 /* Vertices. */
204 glEnableVertexAttribArray( shaders.dust.vertex );
205 glEnableVertexAttribArray( shaders.dust.brightness );
206
207 /* Set up the vertices. */
208 gl_vboActivateAttribOffset( dust_vertexVBO, shaders.dust.vertex, 0,
209 2, GL_FLOAT, 3 * sizeof(GLfloat) );
210 gl_vboActivateAttribOffset( dust_vertexVBO, shaders.dust.brightness, 2 * sizeof(GLfloat),
211 1, GL_FLOAT, 3 * sizeof(GLfloat) );
212 glDrawArrays( GL_POINTS, 0, ndust );
213
214 /* Disable vertex array. */
215 glDisableVertexAttribArray( shaders.dust.vertex );
216 glDisableVertexAttribArray( shaders.dust.brightness );
217
218 glUseProgram(0);
219
220 /* Check for errors. */
221 gl_checkErr();
222}
223
229void background_render( double dt )
230{
231 if (bkg_L_renderbg != LUA_NOREF) {
232 lua_rawgeti( naevL, LUA_REGISTRYINDEX, bkg_L_renderbg );
233 lua_pushnumber( naevL, dt ); /* Note that this is real_dt. */
234 if (nlua_pcall( bkg_cur_env, 1, 0 )) {
235 WARN( _("Background script 'renderbg' error:\n%s"), lua_tostring(naevL,-1));
236 lua_pop( naevL, 1 );
237 }
238 }
239
241
242 if (bkg_L_rendermg != LUA_NOREF) {
243 lua_rawgeti( naevL, LUA_REGISTRYINDEX, bkg_L_rendermg );
244 lua_pushnumber( naevL, dt ); /* Note that this is real_dt. */
245 if (nlua_pcall( bkg_cur_env, 1, 0 )) {
246 WARN( _("Background script 'rendermg' error:\n%s"), lua_tostring(naevL,-1));
247 lua_pop( naevL, 1 );
248 }
249 }
250
253
254 if (bkg_L_renderfg != LUA_NOREF) {
255 lua_rawgeti( naevL, LUA_REGISTRYINDEX, bkg_L_renderfg );
256 lua_pushnumber( naevL, dt ); /* Note that this is real_dt. */
257 if (nlua_pcall( bkg_cur_env, 1, 0 )) {
258 WARN( _("Background script 'renderfg' error:\n%s"), lua_tostring(naevL,-1));
259 lua_pop( naevL, 1 );
260 }
261 }
262}
263
268{
269 if (bkg_L_renderov != LUA_NOREF) {
270 lua_rawgeti( naevL, LUA_REGISTRYINDEX, bkg_L_renderov );
271 lua_pushnumber( naevL, dt ); /* Note that this is real_dt. */
272 if (nlua_pcall( bkg_cur_env, 1, 0 )) {
273 WARN( _("Background script 'renderov' error:\n%s"), lua_tostring(naevL,-1));
274 lua_pop( naevL, 1 );
275 }
276 }
277}
278
282static int bkg_compare( const void *p1, const void *p2 )
283{
284 background_image_t *bkg1, *bkg2;
285
286 bkg1 = (background_image_t*) p1;
287 bkg2 = (background_image_t*) p2;
288
289 if (bkg1->move < bkg2->move)
290 return -1;
291 else if (bkg1->move > bkg2->move)
292 return +1;
293 return 0;
294}
295
299static void bkg_sort( background_image_t *arr )
300{
301 qsort( arr, array_size(arr), sizeof(background_image_t), bkg_compare );
302}
303
307unsigned int background_addImage( const glTexture *image, double x, double y,
308 double move, double scale, double angle, const glColour *col, int foreground )
309{
310 background_image_t *bkg, **arr;
311
312 if (foreground)
313 arr = &bkg_image_arr_ft;
314 else
315 arr = &bkg_image_arr_bk;
316
317 /* See if must create. */
318 if (*arr == NULL)
320
321 /* Create image. */
322 bkg = &array_grow( arr );
323 bkg->id = ++bkg_idgen;
324 bkg->image = gl_dupTexture(image);
325 bkg->x = x;
326 bkg->y = y;
327 bkg->move = move;
328 bkg->scale = scale;
329 bkg->angle = angle;
330 bkg->col = (col!=NULL) ? *col : cWhite;
331
332 /* Sort if necessary. */
333 bkg_sort( *arr );
334
335 return bkg_idgen;
336}
337
342{
343 /* Skip rendering altogether if disabled. */
344 if (conf.bg_brightness <= 0.)
345 return;
346
347 /* Render images in order. */
348 for (int i=0; i<array_size(bkg_arr); i++) {
349 double cx,cy, x,y, gx,gy, z, m;
350 glColour col;
351 background_image_t *bkg = &bkg_arr[i];
352
353 cam_getPos( &cx, &cy );
354 gui_getOffset( &gx, &gy );
355 m = bkg->move;
356 z = bkg->scale;
357 x = (bkg->x - cx) * m - z*bkg->image->sw/2. + gx + SCREEN_W/2.;
358 y = (bkg->y - cy) * m - z*bkg->image->sh/2. + gy + SCREEN_H/2.;
359
360 col.r = bkg->col.r * conf.bg_brightness;
361 col.g = bkg->col.g * conf.bg_brightness;
362 col.b = bkg->col.b * conf.bg_brightness;
363 col.a = bkg->col.a;
364
365 gl_renderTexture( bkg->image, x, y, z*bkg->image->sw, z*bkg->image->sh, 0., 0., bkg->image->srw, bkg->image->srh, &col, bkg->angle );
366 }
367}
368
372static nlua_env background_create( const char *name )
373{
374 size_t bufsize;
375 char path[PATH_MAX];
376 char *buf;
377 nlua_env env;
378
379 /* Create file name. */
380 snprintf( path, sizeof(path), BACKGROUND_PATH"%s.lua", name );
381
382 /* Create the Lua env. */
383 env = nlua_newEnv();
385 nlua_loadTex(env);
386 nlua_loadCol(env);
388 nlua_loadCamera(env);
389 nlua_loadGFX(env);
390
391 /* Open file. */
392 buf = ndata_read( path, &bufsize );
393 if (buf == NULL) {
394 WARN( _("Background script '%s' not found."), path);
395 nlua_freeEnv(env);
396 return LUA_NOREF;
397 }
398
399 /* Load file. */
400 if (nlua_dobufenv(env, buf, bufsize, path) != 0) {
401 WARN( _("Error loading background file: %s\n"
402 "%s\n"
403 "Most likely Lua file has improper syntax, please check"),
404 path, lua_tostring(naevL,-1));
405 free(buf);
406 nlua_freeEnv(env);
407 return LUA_NOREF;
408 }
409 free(buf);
410
411 return env;
412}
413
418{
419 /* Load Lua. */
420 bkg_def_env = background_create( "default" );
421 return 0;
422}
423
427int background_load( const char *name )
428{
429 int ret;
430 nlua_env env;
431
432 /* Free if exists. */
434
435 /* Load default. */
436 if (name == NULL)
438 /* Load new script. */
439 else
441
442 /* Comfort. */
443 env = bkg_cur_env;
444 if (env == LUA_NOREF)
445 return -1;
446
447 /* Run Lua. */
448 nlua_getenv(naevL, env,"background");
449 ret = nlua_pcall(env, 0, 0);
450 if (ret != 0) { /* error has occurred */
451 const char *err = (lua_isstring(naevL,-1)) ? lua_tostring(naevL,-1) : NULL;
452 WARN( _("Background -> 'background' : %s"),
453 (err) ? err : _("unknown error"));
454 lua_pop(naevL, 1);
455 }
456
457 /* See if there are render functions. */
458 bkg_L_renderbg = nlua_refenv( env, "renderbg" );
459 bkg_L_rendermg = nlua_refenv( env, "rendermg" );
460 bkg_L_renderfg = nlua_refenv( env, "renderfg" );
461 bkg_L_renderov = nlua_refenv( env, "renderov" );
462
463 return ret;
464}
465
469static void background_clearCurrent (void)
470{
471 if (bkg_cur_env != bkg_def_env) {
472 nlua_freeEnv( bkg_cur_env );
473 }
474 bkg_cur_env = LUA_NOREF;
475
476 luaL_unref( naevL, LUA_REGISTRYINDEX, bkg_L_renderbg );
477 luaL_unref( naevL, LUA_REGISTRYINDEX, bkg_L_rendermg );
478 luaL_unref( naevL, LUA_REGISTRYINDEX, bkg_L_renderfg );
479 luaL_unref( naevL, LUA_REGISTRYINDEX, bkg_L_renderov );
480 bkg_L_renderbg = LUA_NOREF;
481 bkg_L_rendermg = LUA_NOREF;
482 bkg_L_renderfg = LUA_NOREF;
483 bkg_L_renderov = LUA_NOREF;
484}
485
490{
491 /* Destroy current background script. */
493
494 /* Clear the backgrounds. */
497}
498
505{
506 for (int i=0; i<array_size(*arr); i++) {
507 background_image_t *bkg = &((*arr)[i]);
508 gl_freeTexture( bkg->image );
509 }
510
511 /* Erase it all. */
512 array_erase( arr, array_begin(*arr), array_end(*arr) );
513}
514
519{
520 /* Free the Lua. */
522 nlua_freeEnv( bkg_def_env );
523 bkg_def_env = LUA_NOREF;
524
525 /* Free the images. */
527 bkg_image_arr_ft = NULL;
529 bkg_image_arr_bk = NULL;
530
531 /* Free the Lua. */
532 nlua_freeEnv( bkg_cur_env );
533 bkg_cur_env = LUA_NOREF;
534
536 dust_vertexVBO = NULL;
537
538 ndust = 0;
539}
540
545{
547 for (int i=0; i<array_size(bkg_image_arr_ft); i++)
549 return imgs;
550}
551
557{
558 /* Assume many bg-layer images => none is representative => we should return NULL. Example: Taiomi system's debris field. */
559 if (array_size( bkg_image_arr_bk ) == 1)
560 return gl_dupTexture(bkg_image_arr_bk[0].image);
561 else
562 return NULL;
563}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:158
#define array_end(array)
Returns a pointer to the end of the reserved memory space.
Definition array.h:202
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
Definition array.h:102
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition array.h:140
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition array.h:119
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition array.h:129
#define array_begin(array)
Returns a pointer to the beginning of the reserved memory space.
Definition array.h:194
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
static background_image_t * bkg_image_arr_bk
Definition background.c:50
glTexture ** background_getStarTextures(void)
Returns an array (array.h) of star background images in the system background.
Definition background.c:544
void background_clear(void)
Cleans up the background stuff.
Definition background.c:489
int background_init(void)
Initializes the background system.
Definition background.c:417
static unsigned int bkg_idgen
Definition background.c:53
static int bkg_L_renderov
Definition background.c:63
static background_image_t * bkg_image_arr_ft
Definition background.c:51
#define STAR_BUF
Definition background.c:68
void background_initDust(int n)
Initializes background dust.
Definition background.c:90
static int bkg_L_renderbg
Definition background.c:60
void background_renderOverlay(double dt)
Renders the background overlay.
Definition background.c:267
static int bkg_L_rendermg
Definition background.c:61
static nlua_env bkg_def_env
Definition background.c:59
unsigned int background_addImage(const glTexture *image, double x, double y, double move, double scale, double angle, const glColour *col, int foreground)
Adds a new background image.
Definition background.c:307
void background_moveDust(double x, double y)
Displaces the dust, useful with camera.
Definition background.c:134
static int bkg_L_renderfg
Definition background.c:62
void background_free(void)
Cleans up and frees memory after the backgrounds.
Definition background.c:518
static void background_clearCurrent(void)
Destroys the current running background script.
Definition background.c:469
static GLfloat dust_x
Definition background.c:71
static int bkg_compare(const void *p1, const void *p2)
Compares two different backgrounds and sorts them.
Definition background.c:282
static void background_renderImages(background_image_t *bkg_arr)
Renders the background images.
Definition background.c:341
glTexture * background_getAmbientTexture(void)
Returns an overall background image (nebula, for instance), or NULL if none exists.
Definition background.c:556
void background_renderDust(const double dt)
Renders the dustry background.
Definition background.c:145
static void background_clearImgArr(background_image_t **arr)
Clears a background image array.
Definition background.c:504
static void bkg_sort(background_image_t *arr)
Sorts the backgrounds by movement.
Definition background.c:299
static gl_vbo * dust_vertexVBO
Definition background.c:69
static nlua_env background_create(const char *path)
Creates a background Lua state from a script.
Definition background.c:372
void background_render(double dt)
Render the background.
Definition background.c:229
static nlua_env bkg_cur_env
Backgrounds.
Definition background.c:58
static unsigned int ndust
Definition background.c:70
static GLfloat dust_y
Definition background.c:72
int background_load(const char *name)
Loads a background script by name.
Definition background.c:427
void cam_getVel(double *vx, double *vy)
Gets the camera velocity.
Definition camera.c:136
void cam_getPos(double *x, double *y)
Gets the camera position.
Definition camera.c:118
double cam_getZoom(void)
Gets the camera zoom.
Definition camera.c:97
void gui_getOffset(double *x, double *y)
Gets the GUI offset.
Definition gui.c:2062
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
Definition mat4.c:99
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
Definition mat4.c:82
Header file with generic functions and naev-specifics.
#define pow2(x)
Definition naev.h:46
#define MAX(x, y)
Definition naev.h:39
#define PATH_MAX
Definition naev.h:50
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
Definition ndata.c:154
int nlua_refenv(nlua_env env, const char *name)
Gets the reference of a global in a lua environment.
Definition nlua.c:903
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition nlua.c:798
int nlua_loadBackground(nlua_env env)
Loads the graphics library.
Definition nlua_bkg.c:38
int nlua_loadCamera(nlua_env env)
Loads the camera library.
Definition nlua_camera.c:49
int nlua_loadCol(nlua_env env)
Loads the colour library.
Definition nlua_colour.c:54
int nlua_loadGFX(nlua_env env)
Loads the graphics library.
Definition nlua_gfx.c:98
int nlua_loadTex(nlua_env env)
Loads the texture library.
Definition nlua_tex.c:62
glInfo gl_screen
Definition opengl.c:51
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.
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
void gl_vboDestroy(gl_vbo *vbo)
Destroys a VBO.
Definition opengl_vbo.c:246
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:226
gl_vbo * gl_vboCreateStatic(GLsizei size, const void *data)
Creates a stream vbo.
Definition opengl_vbo.c:179
double dt_mod
Definition pause.c:23
Player_t player
Definition player.c:74
double ptimer
Definition pilot.h:368
double zoom_far
Definition conf.h:134
double bg_brightness
Definition conf.h:98
Pilot * p
Definition player.h:101
Represents a background image like say a Nebula.
Definition background.c:40
glTexture * image
Definition background.c:42
unsigned int id
Definition background.c:41
double scale
Definition opengl.h:52
Abstraction for rendering sprite sheets.
Definition opengl_tex.h:36
double sw
Definition opengl_tex.h:46
double sh
Definition opengl_tex.h:47
double srh
Definition opengl_tex.h:49
double srw
Definition opengl_tex.h:48
Definition mat4.h:10