LibGame v0.4.0
The LG Game Engine - Copyright (C) 2024-2026 ETMSoftware
Loading...
Searching...
No Matches
lg_textures.c File Reference

Functions

static LG_Texturelg_texture_create (int, LG_Path)
 
static int lg_texture_add (LG_Texture *)
 
static void lg_texture_free (LG_Texture *node)
 
static int find_available_tex_unit ()
 
static void free_tex_unit (int tex_unit)
 
void lg_init_textures_module ()
 
void lg_tex_set_min_filter (int v)
 
void lg_tex_set_mag_filter (int v)
 
int lg_tex_get_min_filter ()
 
int lg_tex_get_mag_filter ()
 
LG_Texturelg_texture_new_from_data (lg_tc_format tc_format, int tex_type, LG_Path path, void *data, void **cubemap_data, size_t size, int w, int h, int n_mipmaps)
 
LG_Texturelg_texture_new_from_file (int tex_type, LG_Path path, LG_CubeMap_Paths *cubemap_paths)
 
SDL_Surface * lg_sdl_surf_from_file (LG_Path path, int scale_x, int scale_y)
 
void * lg_compressed_texdata_from_file (LG_Path path, lg_tc_format *tc_format, size_t *size, int *w, int *h, int *n_mipmaps)
 
zboolean lg_test_file_extension (const char *path, const char *ext)
 
int lg_get_png_dims (LG_Path path, int *w, int *h)
 
zboolean is_lg_tex (LG_Texture *node)
 
void lg_texture_remove (LG_Texture *node)
 
void lg_texture_remove_all ()
 
LG_Texturelg_texture_first (LG_Texture *node)
 
LG_Texturelg_texture_last (LG_Texture *node)
 
LG_Texturelg_texture_find_by_id (uint32_t id)
 
int lg_texture_count_nodes ()
 
int lg_texture_count_gl_tex ()
 
static void texture_info (const LG_Texture *tex)
 
void lg_texture_info (const LG_Texture *tex)
 
void lg_texture_info_all ()
 
void lg_texture_list_all ()
 
zboolean lg_read_pixels_from_screen (void *pixels, Rec2Di r)
 
zboolean lg_write_pixels_to_screen (void *pixels, const Rec2Di *dest)
 
void lg_texture_unbind (LG_Texture *tex)
 
void lg_tex_units_info ()
 
unsigned int lg_get_active_tex ()
 
void lg_active_tex_info ()
 
void lg_free_sdl_surf (SDL_Surface *surf)
 
int lg_surf_depth (SDL_Surface *surf)
 
void lg_info_out_read_framebuffer ()
 

Variables

static zboolean assigned_tex_unit [LG_MAX_TEX_UNITS]
 
static int max_tex_units
 

Detailed Description

=== Handle all texture related stuff ===

We're using a global doubly-linked list.

Vars storing the texture list and the assigned tex units:

These vars are for all libgame and app textures, and are updated by all funcs creating or removing textures.

They are 'private', there is no public API, apart from lg_texture_get_node0().

So, you can/should only use this func to create new textures:

 LG_Texture *lg_texture_new_from_file(int tex_type, LG_Path path, LG_CubeMap_Paths *cubemap_paths)

and you can/should only use this func when done with a texture:

 void lg_texture_remove(LG_Texture *node)

and just ignore the details.

(Use everything here only if you know what you're doing).

*** WARNING: Rendering of DXT1/3 textures with mipmaps is still f**ked up at the moment, so avoid them until it's fixed ***

Function Documentation

◆ lg_init_textures_module()

void lg_init_textures_module ( )

Must be called at init time in libgame.c

◆ lg_tex_set_min_filter()

void lg_tex_set_min_filter ( int  v)

Set global value of GL_TEXTURE_MIN_FILTER

Parameters
new_valueProbably GL_LINEAR or GL_NEAREST

◆ lg_tex_set_mag_filter()

void lg_tex_set_mag_filter ( int  v)

Set global value of GL_TEXTURE_MAG_FILTER

Parameters
new_valueProbably GL_LINEAR or GL_NEAREST

◆ lg_tex_get_min_filter()

int lg_tex_get_min_filter ( )

Get global value of GL_TEXTURE_MIN_FILTER

Returns
Probably GL_LINEAR or GL_NEAREST

◆ lg_tex_get_mag_filter()

int lg_tex_get_mag_filter ( )

Get global value of GL_TEXTURE_MAG_FILTER

Returns
Probably GL_LINEAR or GL_NEAREST

◆ lg_texture_new_from_data()

LG_Texture * lg_texture_new_from_data ( lg_tc_format  tc_format,
int  tex_type,
LG_Path  path,
void *  data,
void **  cubemap_data,
size_t  size,
int  w,
int  h,
int  n_mipmaps 
)

Create a new LG_Texture node from data (either a SDL_Surface or compressed tex data), and ADD IT to the global doubly-linked list

(Completely replace SDL_CreateTextureFromSurface())

Now also reading compressed textures - see lg_astc_loader.c/h and lg_dds_loader.c/h

About mipmaps:

  • They are ignored in uncompressed textures, as they are generated with glGenerateMipmap(GL_TEXTURE_2D)
  • Skyboxes dont need/want mipmaps, so they also are ignored, if included
  • *** WARNING: Rendering of DXT1/3 textures with mipmaps is still f**ked up at the moment, so avoid them until it's fixed ***
Parameters
tc_formatIf tc_format == LG_TC_UNCOMPRESSED, data is a SDL_Surface, otherwise data is compressed texture data
(LG_TC_DXT1, LG_TC_DXT3, LG_TC_ASTC, LG_TC_ETC1 so far ...)
tex_typeGL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
pathLG_Path to image file, only used at this point to store info
dataA pointer to compressed texture data or a SDL_Surface - ignored if tex_type == GL_TEXTURE_CUBE_MAP
cubemap_dataArray of 6 compressed tex data or 6 SDL_Surface's - ignored if tex_type == GL_TEXTURE_2D
sizeSize - ignored if texture is not compressed
wWidth
hHeight
n_mipmapsNumber of generated mipmaps - WARNING: Original image is considered mipmap level 0, so n_mipmaps must be at least 1
Returns
A pointer to a LG_Texture if OK, NULL on error

◆ lg_texture_new_from_file()

LG_Texture * lg_texture_new_from_file ( int  tex_type,
LG_Path  path,
LG_CubeMap_Paths cubemap_paths 
)

Create a new LG_Texture node from a file and ADD IT to the global doubly-linked list

=== You should use this func when creating new textures ===

*** WARNING #1: Rendering of DXT1/3 textures with mipmaps is still f**ked up at the moment, so avoid them until it's fixed ***

*** WARNING #2: stbi_info() doesn't work on Android - used (only) to get jpg file dims, so avoid them until (?) ***

(Seems stb_image is f**ked up on Android and pretty useless, should probably get rid of it)

Parameters
tex_typeGL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
pathLG_Path to image file - if tex_type == GL_TEXTURE_CUBE_MAP, only used to store path to first image
cubemap_pathsArray of 6 LG_Path to image file - ignored if tex_type == GL_TEXTURE_2D
Returns
A pointer to a LG_Texture if OK, NULL on error

◆ lg_sdl_surf_from_file()

SDL_Surface * lg_sdl_surf_from_file ( LG_Path  path,
int  scale_x,
int  scale_y 
)

For image and NON-compressed tex files

NO scaling is applied if scale_x == 0 or scale_y == 0

Otherwise, scale_x/y apply to env->top_win_logical_w/h, ie

  • w = env->top_win_logical_w * scale_x
  • h = env->top_win_logical_h * scale_y
Parameters
pathLG_Path to image file
scale_x
scale_y
Returns
A SDL_Surface if OK, NULL on error

◆ lg_compressed_texdata_from_file()

void * lg_compressed_texdata_from_file ( LG_Path  path,
lg_tc_format *  tc_format,
size_t *  size,
int *  w,
int *  h,
int *  n_mipmaps 
)

For compressed tex files

Supported file formats and texture compression formats:

  • S3TC -> DDS with DXT1 and DXT3 tex compression (Linux only)
  • ASCT
  • PKM with ETC1 tex compression
  • *** WARNING: Rendering of DXT1/3 textures with mipmaps is still f**ked up at the moment, so avoid them until it's fixed ***

Returned data must be freed afterwards

Parameters
pathLG_Path to compressed tex file
tc_formatPointer to lg_tc_format
sizePointer to size
wPointer to width
hPointer to height
n_mipmapsPointer n_mipmaps
Returns
Pointer to compressed data if OK, NULL on error

◆ lg_test_file_extension()

zboolean lg_test_file_extension ( const char *  path,
const char *  ext 
)

Test path against file extension (case-insensitive strings comparaison)

NOTE: doesn't search backward for '.' but uses extension string length instead, so extension should include '.', ie ".png", not "png"

Parameters
pathPath string (full or relative, doesn't matter here)
extFile extension to test against (ie ".png", ".jpg", etc)
Returns
TRUE if path FILE EXTENSION == EXT, FALSE otherwise

◆ lg_get_png_dims()

int lg_get_png_dims ( LG_Path  path,
int *  w,
int *  h 
)

Get PNG image dimensions

Parameters
pathLG_Path to image file
wWidth
hHeight
Returns
LG_OK if OK

◆ is_lg_tex()

zboolean is_lg_tex ( LG_Texture node)

Check if a LG_Texture node is valid, ie non NULL and with a valid signature

Parameters
nodeA LG_Texture node
Returns
TRUE if OK, FALSE otherwise

◆ lg_texture_remove()

void lg_texture_remove ( LG_Texture node)

Remove node from list AND free node and all associated resources (including the GL texture), if != <node0>

=== You should use this func when done with a texture ===

WARNING: Must be a valid texture and need a valid GL context, or will segfault

Anyways, lg_texture_remove_all() is always called by lg_quit() so you shouldn't worry too much about memory leaks

Parameters
nodeA LG_Texture node
Returns
TRUE if removed, FALSE on error

◆ lg_texture_remove_all()

void lg_texture_remove_all ( )

Remove all nodes (but <node0>) from list, freeing all resources (including GL textures)

WARNING:

  • This func should be called very carefully, unless you know exactly what you are doing
  • This func is always called by lg_quit()
  • Need a valid GL context
Returns
The num of removed nodes

◆ lg_texture_first()

LG_Texture * lg_texture_first ( LG_Texture node)

Return first node

Parameters
nodeA LG_Texture node
Returns
First node of the list

◆ lg_texture_last()

LG_Texture * lg_texture_last ( LG_Texture node)

Return last node

Parameters
nodeA LG_Texture node
Returns
Last node of the list

◆ lg_texture_find_by_id()

LG_Texture * lg_texture_find_by_id ( uint32_t  id)

Return first found occurence

Parameters
idA LG_Texture id
Returns
Found LG_Texture node or NULL if not found

◆ lg_texture_count_nodes()

int lg_texture_count_nodes ( )

Count all nodes - doesn't check if node->id is a valid GL texture

Include <node0>

Returns
Number of nodes of the list

◆ lg_texture_count_gl_tex()

int lg_texture_count_gl_tex ( )

Count all nodes - check if node->id is a valid GL texture

Doesn't include <node0>

Returns
Number of nodes of the list

◆ lg_texture_info()

void lg_texture_info ( const LG_Texture tex)

Print out texture info

Parameters
texA LG_Texture

◆ lg_texture_info_all()

void lg_texture_info_all ( )

Print out texture info for all nodes

◆ lg_texture_list_all()

void lg_texture_list_all ( )

Print out a list of all textures (id and rel_path_in_assets)

◆ lg_read_pixels_from_screen()

zboolean lg_read_pixels_from_screen ( void *  pixels,
Rec2Di  r 
)

Store a v-flipped image (don't ask me why it's v-flipped)

From some doc somewhere: "Only two format/type parameter pairs are accepted. GL_RGBA/GL_UNSIGNED_BYTE is always accepted, and the other acceptable pair can be discovered by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE."

Parameters
pixelsA pixel buffer
rA Rec2Di
Returns
TRUE if OK

◆ lg_write_pixels_to_screen()

zboolean lg_write_pixels_to_screen ( void *  pixels,
const Rec2Di dest 
)

'Un-flip' the image provided by lg_read_pixels_from_screen()

If NULL, dest is the entire rendering target

Parameters
pixelsA pixel buffer
destA Rec2Di
Returns
TRUE if OK

◆ lg_texture_unbind()

void lg_texture_unbind ( LG_Texture tex)

Unbind texture

◆ lg_tex_units_info()

void lg_tex_units_info ( )

Print out texture units info

◆ lg_get_active_tex()

unsigned int lg_get_active_tex ( )
Returns
The active texture unit

◆ lg_active_tex_info()

void lg_active_tex_info ( )

Print out active texture unit info

◆ lg_free_sdl_surf()

void lg_free_sdl_surf ( SDL_Surface *  surf)

Free SDL_Surface if not NULL

Parameters
surfAddr of SDL_Surface

◆ lg_surf_depth()

int lg_surf_depth ( SDL_Surface *  surf)

Surface depth of a SDL_Surface

Parameters
surfAddr of SDL_Surface
Returns
Surface depth

◆ lg_info_out_read_framebuffer()

void lg_info_out_read_framebuffer ( )

Print out current bound read framebuffer info