naev 0.10.4
opengl_tex.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <stdio.h>
11#include <stdlib.h>
12#include "physfsrwops.h"
13#include "SDL_image.h"
14
15#include "naev.h"
18#include "array.h"
19#include "conf.h"
20#include "gui.h"
21#include "log.h"
22#include "md5.h"
23#include "nfile.h"
24#include "nstring.h"
25#include "opengl.h"
26
27/*
28 * graphic list
29 */
33typedef struct glTexList_ {
34 struct glTexList_ *next;
36 int used;
37 /* TODO We currently treat images with different number of sprites as
38 * different images, i.e., they get reloaded and use more memory. However,
39 * it should be possible to do something fancier and share the texture to
40 * avoid this increase of memory (without sharing other parameters). */
41 int sx;
42 int sy;
43} glTexList;
44static glTexList* texture_list = NULL;
46/*
47 * prototypes
48 */
49/* misc */
50static int SDL_IsTrans( SDL_Surface* s, int x, int y );
51static uint8_t* SDL_MapTrans( SDL_Surface* s, int w, int h );
52static size_t gl_transSize( const int w, const int h );
53/* glTexture */
54static GLuint gl_texParameters( unsigned int flags );
55static GLuint gl_loadSurface( SDL_Surface* surface, unsigned int flags, int freesur );
56static glTexture* gl_loadNewImage( const char* path, unsigned int flags );
57static glTexture* gl_loadNewImageRWops( const char *path, SDL_RWops *rw, unsigned int flags );
58/* List. */
59static glTexture* gl_texExists( const char* path, int sx, int sy );
60static int gl_texAdd( glTexture *tex, int sx, int sy );
61
70static int SDL_IsTrans( SDL_Surface* s, int x, int y )
71{
72 int bpp;
73 Uint8 *p;
74 Uint32 pixelcolour;
75
76 bpp = s->format->BytesPerPixel;
77 /* here p is the address to the pixel we want to retrieve */
78 p = (Uint8 *)s->pixels + y*s->pitch + x*bpp;
79
80 pixelcolour = 0;
81 switch(bpp) {
82 case 1:
83 pixelcolour = *p;
84 break;
85
86 case 2:
87 memcpy(&pixelcolour, p, sizeof(Uint16));
88 break;
89
90 case 3:
91#if SDL_BYTEORDER == SDL_BIG_ENDIAN
92 pixelcolour = p[0] << 16 | p[1] << 8 | p[2];
93#else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
94 pixelcolour = p[0] | p[1] << 8 | p[2] << 16;
95#endif /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
96 break;
97
98 case 4:
99 memcpy(&pixelcolour, p, sizeof(Uint32));
100 break;
101 }
102
103 /* test whether pixels colour == colour of transparent pixels for that surface */
104 return ((pixelcolour & s->format->Amask) < (Uint32)(0.1*(double)s->format->Amask));
105}
106
118static uint8_t* SDL_MapTrans( SDL_Surface* s, int w, int h )
119{
120 size_t size;
121 uint8_t *t;
122
123 /* Get limit.s */
124 if (w < 0)
125 w = s->w;
126 if (h < 0)
127 h = s->h;
128
129 /* alloc memory for just enough bits to hold all the data we need */
130 size = gl_transSize(w, h);
131 t = malloc(size);
132 if (t==NULL) {
133 WARN(_("Out of Memory"));
134 return NULL;
135 }
136 memset(t, 0, size); /* important, must be set to zero */
137
138 /* Check each pixel individually. */
139 for (int i=0; i<h; i++)
140 for (int j=0; j<w; j++) /* sets each bit to be 1 if not transparent or 0 if is */
141 t[(i*w+j)/8] |= (SDL_IsTrans(s,j,i)) ? 0 : (1<<((i*w+j)%8));
142
143 return t;
144}
145
146/*
147 * @brief Gets the size needed for a transparency map.
148 *
149 * @param w Width of the image.
150 * @param h Height of the image.
151 * @return The size in bytes.
152 */
153static size_t gl_transSize( const int w, const int h )
154{
155 /* One bit per pixel, plus remainder. */
156 return w*h/8 + ((w*h%8)?1:0);
157}
158
162static GLuint gl_texParameters( unsigned int flags )
163{
164 GLuint texture;
165
166 /* opengl texture binding */
167 glGenTextures( 1, &texture ); /* Creates the texture */
168 glBindTexture( GL_TEXTURE_2D, texture ); /* Loads the texture */
169
170 /* Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR
171 * also seems to create a bit of artifacts around the edges */
172 if ((gl_screen.scale != 1.) || (flags & OPENGL_TEX_MIPMAPS)) {
173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
174 if (flags & OPENGL_TEX_MIPMAPS)
175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
176 else
177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
178 }
179 else {
180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
182 }
183
184 /* Always wrap just in case. */
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
187
188 /* Check errors. */
189 gl_checkErr();
190
191 return texture;
192}
193
203int gl_fboCreate( GLuint *fbo, GLuint *tex, GLsizei width, GLsizei height )
204{
205 GLenum status;
206
207 /* Create the render buffer. */
208 glGenTextures(1, tex);
209 glBindTexture(GL_TEXTURE_2D, *tex);
210 glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
211 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
215 glBindTexture(GL_TEXTURE_2D, 0);
216
217 /* Create the frame buffer. */
218 glGenFramebuffers( 1, fbo );
219 glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
220
221 /* Attach the colour buffer. */
222 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *tex, 0);
223
224 /* Check status. */
225 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
226 if (status != GL_FRAMEBUFFER_COMPLETE)
227 WARN(_("Error setting up framebuffer!"));
228
229 /* Restore state. */
230 glBindFramebuffer(GL_FRAMEBUFFER, gl_screen.current_fbo);
231
232 gl_checkErr();
233
234 return (status==GL_FRAMEBUFFER_COMPLETE);
235}
236
237glTexture* gl_loadImageData( float *data, int w, int h, int sx, int sy, const char* name )
238{
239 /* Set up the texture defaults */
240 glTexture *texture = calloc( 1, sizeof(glTexture) );
241
242 texture->w = (double) w;
243 texture->h = (double) h;
244 texture->sx = (double) sx;
245 texture->sy = (double) sy;
246
247 /* Set up texture. */
248 texture->texture = gl_texParameters( 0 );
249
250 /* Copy over. */
251 glTexImage2D( GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, w, h, 0, GL_RGBA, GL_FLOAT, data );
252 glBindTexture( GL_TEXTURE_2D, 0 );
253
254 /* Check errors. */
255 gl_checkErr();
256
257 /* Set up values. */
258 texture->sw = texture->w / texture->sx;
259 texture->sh = texture->h / texture->sy;
260 texture->srw = texture->sw / texture->w;
261 texture->srh = texture->sh / texture->h;
262
263 /* Add to list. */
264 if (name != NULL) {
265 texture->name = strdup(name);
266 gl_texAdd( texture, sx, sy );
267 }
268
269 return texture;
270}
271
280static GLuint gl_loadSurface( SDL_Surface* surface, unsigned int flags, int freesur )
281{
282 GLuint texture;
283 GLfloat param;
284
285 /* Get texture. */
286 texture = gl_texParameters( flags );
287
288 /* now load the texture data up */
289 SDL_LockSurface( surface );
290 glPixelStorei( GL_UNPACK_ALIGNMENT, MIN( surface->pitch&-surface->pitch, 8 ) );
291 glTexImage2D( GL_TEXTURE_2D, 0, GL_SRGB_ALPHA,
292 surface->w, surface->h, 0, surface->format->Amask ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, surface->pixels );
293 SDL_UnlockSurface( surface );
294
295 /* Create mipmaps. */
296 if (flags & OPENGL_TEX_MIPMAPS) {
297 /* Do fancy stuff. */
298 if (GLAD_GL_ARB_texture_filter_anisotropic) {
299 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &param);
300 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, param);
301 }
302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
303 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 9);
304
305 /* Now generate the mipmaps. */
306 glGenerateMipmap(GL_TEXTURE_2D);
307 }
308
309 /* cleanup */
310 if (freesur)
311 SDL_FreeSurface( surface );
312 gl_checkErr();
313
314 return texture;
315}
316
331glTexture* gl_loadImagePadTrans( const char *name, SDL_Surface* surface, SDL_RWops *rw,
332 unsigned int flags, int w, int h, int sx, int sy, int freesur )
333{
334 glTexture *texture = NULL;
335 size_t filesize, cachesize;
336 uint8_t *trans;
337 char *cachefile;
338 char digest[33];
339
340 if ((name != NULL) && !(flags & OPENGL_TEX_SKIPCACHE)) {
341 texture = gl_texExists( name, sx, sy );
342 if ((texture != NULL) && (texture->trans != NULL)) {
343 if (freesur)
344 SDL_FreeSurface( surface );
345 return texture;
346 }
347 }
348
349 if (flags & OPENGL_TEX_MAPTRANS)
350 flags ^= OPENGL_TEX_MAPTRANS;
351
352 /* Appropriate size for the transparency map, see SDL_MapTrans */
353 cachesize = gl_transSize(w, h);
354
355 cachefile = NULL;
356 trans = NULL;
357
358 if (rw != NULL) {
359 size_t pngsize;
360 md5_state_t md5;
361 char *data;
362 md5_byte_t *md5val = malloc(16);
363 md5_init(&md5);
364
365 pngsize = SDL_RWseek( rw, 0, SEEK_END );
366 SDL_RWseek( rw, 0, SEEK_SET );
367
368 data = malloc(pngsize);
369 if (data == NULL)
370 WARN(_("Out of Memory"));
371 else {
372 SDL_RWread( rw, data, pngsize, 1 );
373 md5_append( &md5, (md5_byte_t*)data, pngsize );
374 free(data);
375 }
376 md5_finish( &md5, md5val );
377
378 for (int i=0; i<16; i++)
379 snprintf( &digest[i * 2], 3, "%02x", md5val[i] );
380 free(md5val);
381
382 asprintf( &cachefile, "%scollisions/%s",
383 nfile_cachePath(), digest );
384
385 /* Attempt to find a cached transparency map. */
386 if (nfile_fileExists(cachefile)) {
387 trans = (uint8_t*)nfile_readFile( &filesize, cachefile );
388
389 /* Consider cached data invalid if the length doesn't match. */
390 if (trans != NULL && cachesize != (unsigned int)filesize) {
391 free(trans);
392 trans = NULL;
393 }
394 /* Cached data matches, no need to overwrite. */
395 else {
396 free(cachefile);
397 cachefile = NULL;
398 }
399 }
400 }
401 else {
402 /* We could hash raw pixel data here, but that's slower than just
403 * generating the map from scratch.
404 */
405 WARN(_("Texture '%s' has no RWops"), name);
406 }
407
408 if (trans == NULL) {
409 SDL_LockSurface(surface);
410 trans = SDL_MapTrans( surface, w, h );
411 SDL_UnlockSurface(surface);
412
413 if (cachefile != NULL) {
414 /* Cache newly-generated transparency map. */
415 char dirpath[PATH_MAX];
416 snprintf( dirpath, sizeof(dirpath), "%s/%s", nfile_cachePath(), "collisions/" );
417 nfile_dirMakeExist( dirpath );
418 nfile_writeFile( (char*)trans, cachesize, cachefile );
419 free(cachefile);
420 }
421 }
422
423 if (texture == NULL)
424 texture = gl_loadImagePad( name, surface, flags, w, h, sx, sy, freesur );
425 else if (freesur)
426 SDL_FreeSurface( surface );
427 texture->trans = trans;
428 return texture;
429}
430
444glTexture* gl_loadImagePad( const char *name, SDL_Surface* surface,
445 unsigned int flags, int w, int h, int sx, int sy, int freesur )
446{
447 glTexture *texture;
448
449 /* Make sure doesn't already exist. */
450 if ((name != NULL) && !(flags & OPENGL_TEX_SKIPCACHE)) {
451 texture = gl_texExists( name, sx, sy );
452 if (texture != NULL)
453 return texture;
454 }
455
456 if (flags & OPENGL_TEX_MAPTRANS)
457 return gl_loadImagePadTrans( name, surface, NULL, flags, w, h,
458 sx, sy, freesur );
459
460 /* set up the texture defaults */
461 texture = calloc( 1, sizeof(glTexture) );
462
463 texture->w = (double) w;
464 texture->h = (double) h;
465 texture->sx = (double) sx;
466 texture->sy = (double) sy;
467
468 texture->texture = gl_loadSurface( surface, flags, freesur );
469
470 texture->sw = texture->w / texture->sx;
471 texture->sh = texture->h / texture->sy;
472 texture->srw = texture->sw / texture->w;
473 texture->srh = texture->sh / texture->h;
474 texture->flags = flags;
475
476 if (name != NULL) {
477 texture->name = strdup(name);
478 gl_texAdd( texture, sx, sy );
479 }
480 else
481 texture->name = NULL;
482
483 return texture;
484}
485
493glTexture* gl_loadImage( SDL_Surface* surface, unsigned int flags )
494{
495 return gl_loadImagePad( NULL, surface, flags, surface->w, surface->h, 1, 1, 1 );
496}
497
508static glTexture* gl_texExists( const char* path, int sx, int sy )
509{
510 /* Null does never exist. */
511 if (path==NULL)
512 return NULL;
513
514 /* check to see if it already exists */
515 if (texture_list == NULL)
516 return NULL;
517
518 for (glTexList *cur=texture_list; cur!=NULL; cur=cur->next) {
519 /* Must match filename. */
520 if (strcmp(path,cur->tex->name)!=0)
521 continue;
522 /* Must match size. */
523 if ((cur->sx!=sx) || (cur->sy!=sy))
524 continue;
525
526 /* Use new texture. */
527 cur->used++;
528 return cur->tex;
529 }
530
531 return NULL;
532}
533
537static int gl_texAdd( glTexture *tex, int sx, int sy )
538{
539 glTexList *new, *last = texture_list;
540
541 /* Create the new node */
542 new = malloc( sizeof(glTexList) );
543 new->next = NULL;
544 new->used = 1;
545 new->tex = tex;
546 new->sx = sx;
547 new->sy = sy;
548
549 if (texture_list == NULL) /* special condition - creating new list */
550 texture_list = new;
551 else {
552 while (last->next != NULL)
553 last = last->next;
554
555 last->next = new;
556 }
557
558 return 0;
559}
560
570glTexture* gl_newImage( const char* path, const unsigned int flags )
571{
572 /* Check if it already exists. */
573 if (!(flags & OPENGL_TEX_SKIPCACHE)) {
574 glTexture *t = gl_texExists( path, 1, 1 );
575 if (t != NULL)
576 return t;
577 }
578
579 /* Load the image */
580 return gl_loadNewImage( path, flags );
581}
582
595glTexture* gl_newImageRWops( const char* path, SDL_RWops *rw, const unsigned int flags )
596{
597 /* Check if it already exists. */
598 if (!(flags & OPENGL_TEX_SKIPCACHE)) {
599 glTexture *t = gl_texExists( path, 1, 1 );
600 if (t != NULL)
601 return t;
602 }
603
604 /* Load the image */
605 return gl_loadNewImageRWops( path, rw, flags );
606}
607
615static glTexture* gl_loadNewImage( const char* path, const unsigned int flags )
616{
617 glTexture *texture;
618 SDL_RWops *rw;
619
620 if (path==NULL) {
621 WARN(_("Trying to load image from NULL path."));
622 return NULL;
623 }
624
625 /* Load from packfile */
626 rw = PHYSFSRWOPS_openRead( path );
627 if (rw == NULL) {
628 WARN(_("Failed to load surface '%s' from ndata."), path);
629 return NULL;
630 }
631
632 texture = gl_loadNewImageRWops( path, rw, flags );
633
634 SDL_RWclose( rw );
635 return texture;
636}
637
646static glTexture* gl_loadNewImageRWops( const char *path, SDL_RWops *rw, unsigned int flags )
647{
648 glTexture *texture;
649 SDL_Surface *surface;
650
651 /* Placeholder for warnings. */
652 if (path==NULL)
653 path = _("unknown");
654
655 surface = IMG_Load_RW( rw, 0 );
656 flags |= OPENGL_TEX_VFLIP;
657 if (surface == NULL) {
658 WARN(_("Unable to load image '%s'."), path );
659 return NULL;
660 }
661
662 if (surface == NULL) {
663 WARN(_("'%s' could not be opened"), path );
664 return NULL;
665 }
666
667 if (flags & OPENGL_TEX_MAPTRANS)
668 texture = gl_loadImagePadTrans( path, surface, rw, flags, surface->w, surface->h, 1, 1, 1 );
669 else
670 texture = gl_loadImagePad( path, surface, flags, surface->w, surface->h, 1, 1, 1 );
671
672 return texture;
673}
674
684glTexture* gl_newSprite( const char* path, const int sx, const int sy,
685 const unsigned int flags )
686{
687 glTexture* texture;
688
689 /* Check if it already exists. */
690 if (!(flags & OPENGL_TEX_SKIPCACHE)) {
691 texture = gl_texExists( path, sx, sy );
692 if (texture != NULL)
693 return texture;
694 }
695
696 /* Create new image. */
697 texture = gl_newImage( path, flags | OPENGL_TEX_SKIPCACHE );
698 if (texture == NULL)
699 return NULL;
700
701 /* will possibly overwrite an existing texture properties
702 * so we have to load same texture always the same sprites */
703 texture->sx = (double) sx;
704 texture->sy = (double) sy;
705 texture->sw = texture->w / texture->sx;
706 texture->sh = texture->h / texture->sy;
707 texture->srw = texture->sw / texture->w;
708 texture->srh = texture->sh / texture->h;
709 return texture;
710}
711
722glTexture* gl_newSpriteRWops( const char* path, SDL_RWops *rw,
723 const int sx, const int sy, const unsigned int flags )
724{
725 glTexture* texture;
726
727 /* Check if it already exists. */
728 if (!(flags & OPENGL_TEX_SKIPCACHE)) {
729 texture = gl_texExists( path, sx, sy );
730 if (texture != NULL)
731 return texture;
732 }
733
734 /* Create new image. */
735 texture = gl_newImageRWops( path, rw, flags | OPENGL_TEX_SKIPCACHE );
736 if (texture == NULL)
737 return NULL;
738
739 /* will possibly overwrite an existing texture properties
740 * so we have to load same texture always the same sprites */
741 texture->sx = (double) sx;
742 texture->sy = (double) sy;
743 texture->sw = texture->w / texture->sx;
744 texture->sh = texture->h / texture->sy;
745 texture->srw = texture->sw / texture->w;
746 texture->srh = texture->sh / texture->h;
747 return texture;
748}
749
755void gl_freeTexture( glTexture *texture )
756{
757 glTexList *last;
758
759 if (texture == NULL)
760 return;
761
762 /* see if we can find it in stack */
763 last = NULL;
764 for (glTexList *cur=texture_list; cur!=NULL; cur=cur->next) {
765 if (cur->tex == texture) { /* found it */
766 cur->used--;
767 if (cur->used <= 0) { /* not used anymore */
768 /* free the texture */
769 glDeleteTextures( 1, &texture->texture );
770 free(texture->trans);
771 free(texture->name);
772 free(texture);
773
774 /* free the list node */
775 if (last == NULL) { /* case there's no texture before it */
776 if (cur->next != NULL)
777 texture_list = cur->next;
778 else /* case it's the last texture */
779 texture_list = NULL;
780 }
781 else
782 last->next = cur->next;
783 free(cur);
784 }
785 return; /* we already found it so we can exit */
786 }
787 last = cur;
788 }
789
790 /* Not found */
791 if (texture->name != NULL) /* Surfaces will have NULL names */
792 WARN(_("Attempting to free texture '%s' not found in stack!"), texture->name);
793
794 /* Free anyways */
795 glDeleteTextures( 1, &texture->texture );
796 free(texture->trans);
797 free(texture->name);
798 free(texture);
799
800 gl_checkErr();
801}
802
810{
811 /* No segfaults kthxbye. */
812 if (texture == NULL)
813 return NULL;
814
815 /* check to see if it already exists */
816 if (texture_list != NULL) {
817 for (glTexList *cur=texture_list; cur!=NULL; cur=cur->next) {
818 if (texture == cur->tex) {
819 cur->used++;
820 return cur->tex;
821 }
822 }
823 }
824
825 /* Invalid texture. */
826 WARN(_("Unable to duplicate texture '%s'."), texture->name);
827 return NULL;
828}
829
838int gl_isTrans( const glTexture* t, const int x, const int y )
839{
840 /* Get the position in the sheet. */
841 int i = y*(int)(t->w) + x ;
842 /* Now we have to pull out the individual bit. */
843 return !(t->trans[ i/8 ] & (1 << (i%8)));
844}
845
857void gl_getSpriteFromDir( int* x, int* y, const glTexture* t, const double dir )
858{
859 int s, sx, sy;
860 double shard, rdir;
861
862#ifdef DEBUGGING
863 if ((dir > 2.*M_PI) || (dir < 0.)) {
864 WARN(_("Angle not between 0 and 2.*M_PI [%f]."), dir);
865 *x = *y = 0;
866 return;
867 }
868#endif /* DEBUGGING */
869
870 /* what each image represents in angle */
871 shard = 2.*M_PI / (t->sy*t->sx);
872
873 /* real dir is slightly moved downwards */
874 rdir = dir + shard/2.;
875
876 /* now calculate the sprite we need */
877 s = (int)(rdir / shard);
878 sx = t->sx;
879 sy = t->sy;
880
881 /* makes sure the sprite is "in range" */
882 if (s > (sy*sx-1))
883 s = s % (sy*sx);
884
885 (*x) = s % sx;
886 (*y) = s / sx;
887}
888
893{
894 glTexture **t;
895
896 if (array_size(tex) == 0) {
897 *n = 0;
898 return NULL;
899 }
900
901 t = malloc( array_size(tex) * sizeof(glTexture*) );
902 for (int i=0; i<array_size(tex); i++)
903 t[i] = gl_dupTexture( tex[i] );
904 *n = array_size(tex);
905 return t;
906}
907
914{
915 return 0;
916}
917
922{
923 /* Make sure there's no texture leak */
924 if (texture_list != NULL) {
925 DEBUG(_("Texture leak detected!"));
926 for (glTexList *tex=texture_list; tex!=NULL; tex=tex->next)
927 DEBUG( n_( " '%s' opened %d time", " '%s' opened %d times", tex->used ), tex->tex->name, tex->used );
928 }
929}
930
935{
936 if (tex==NULL) {
937 tex = malloc( sizeof(glTexture*) );
938 tex[0] = t;
939 *n = 1;
940 return tex;
941 }
942
943 *n += 1;
944 tex = realloc( tex, (*n)*sizeof(glTexture*) );
945 tex[*n-1] = t;
946 return tex;
947}
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:168
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition: naev.h:40
#define PATH_MAX
Definition: naev.h:50
int nfile_writeFile(const char *data, size_t len, const char *path)
Tries to write a file.
Definition: nfile.c:538
char * nfile_readFile(size_t *filesize, const char *path)
Tries to read a file.
Definition: nfile.c:427
int nfile_dirMakeExist(const char *path)
Creates a directory if it doesn't exist.
Definition: nfile.c:267
const char * nfile_cachePath(void)
Gets Naev's cache path (for cached data such as generated textures)
Definition: nfile.c:159
int nfile_fileExists(const char *path)
Checks to see if a file exists.
Definition: nfile.c:316
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
glTexture * gl_newSprite(const char *path, const int sx, const int sy, const unsigned int flags)
Loads the texture immediately, but also sets it as a sprite.
Definition: opengl_tex.c:684
void gl_exitTextures(void)
Cleans up the opengl texture subsystem.
Definition: opengl_tex.c:921
glTexture * gl_newImageRWops(const char *path, SDL_RWops *rw, const unsigned int flags)
Loads an image as a texture.
Definition: opengl_tex.c:595
int gl_fboCreate(GLuint *fbo, GLuint *tex, GLsizei width, GLsizei height)
Creates a framebuffer and its associated texture.
Definition: opengl_tex.c:203
static glTexture * gl_texExists(const char *path, int sx, int sy)
Check to see if a texture matching a path already exists.
Definition: opengl_tex.c:508
glTexture * gl_loadImage(SDL_Surface *surface, unsigned int flags)
Loads the SDL_Surface to a glTexture.
Definition: opengl_tex.c:493
glTexture * gl_newSpriteRWops(const char *path, SDL_RWops *rw, const int sx, const int sy, const unsigned int flags)
Loads the texture immediately, but also sets it as a sprite.
Definition: opengl_tex.c:722
glTexture ** gl_copyTexArray(glTexture **tex, int *n)
Copy a texture array.
Definition: opengl_tex.c:892
int gl_isTrans(const glTexture *t, const int x, const int y)
Checks to see if a pixel is transparent in a texture.
Definition: opengl_tex.c:838
static glTexture * gl_loadNewImage(const char *path, unsigned int flags)
Only loads the image, does not add to stack unlike gl_newImage.
Definition: opengl_tex.c:615
static int SDL_IsTrans(SDL_Surface *s, int x, int y)
Checks to see if a position of the surface is transparent.
Definition: opengl_tex.c:70
glTexture ** gl_addTexArray(glTexture **tex, int *n, glTexture *t)
Adds an element to a texture array.
Definition: opengl_tex.c:934
static int gl_texAdd(glTexture *tex, int sx, int sy)
Adds a texture to the list under the name of path.
Definition: opengl_tex.c:537
glTexture * gl_loadImagePad(const char *name, SDL_Surface *surface, unsigned int flags, int w, int h, int sx, int sy, int freesur)
Loads the already padded SDL_Surface to a glTexture.
Definition: opengl_tex.c:444
glTexture * gl_loadImagePadTrans(const char *name, SDL_Surface *surface, SDL_RWops *rw, unsigned int flags, int w, int h, int sx, int sy, int freesur)
Wrapper for gl_loadImagePad that includes transparency mapping.
Definition: opengl_tex.c:331
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
Definition: opengl_tex.c:570
static uint8_t * SDL_MapTrans(SDL_Surface *s, int w, int h)
Maps the surface transparency.
Definition: opengl_tex.c:118
void gl_getSpriteFromDir(int *x, int *y, const glTexture *t, const double dir)
Sets x and y to be the appropriate sprite for glTexture using dir.
Definition: opengl_tex.c:857
static glTexture * gl_loadNewImageRWops(const char *path, SDL_RWops *rw, unsigned int flags)
Only loads the image, does not add to stack unlike gl_newImage.
Definition: opengl_tex.c:646
static GLuint gl_texParameters(unsigned int flags)
Sets default texture parameters.
Definition: opengl_tex.c:162
static glTexList * texture_list
Definition: opengl_tex.c:44
static GLuint gl_loadSurface(SDL_Surface *surface, unsigned int flags, int freesur)
Loads a surface into an opengl texture.
Definition: opengl_tex.c:280
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition: opengl_tex.c:755
int gl_initTextures(void)
Initializes the opengl texture subsystem.
Definition: opengl_tex.c:913
double scale
Definition: opengl.h:48
GLuint current_fbo
Definition: opengl.h:66
Represents a node in the texture list.
Definition: opengl_tex.c:33
struct glTexList_ * next
Definition: opengl_tex.c:34
glTexture * tex
Definition: opengl_tex.c:35
int used
Definition: opengl_tex.c:36
Abstraction for rendering sprite sheets.
Definition: opengl_tex.h:34
uint8_t * trans
Definition: opengl_tex.h:51
double w
Definition: opengl_tex.h:38
double sx
Definition: opengl_tex.h:42
double sy
Definition: opengl_tex.h:43
Define the state of the MD5 Algorithm.
Definition: md5.h:73