2023-05-14 10:21:03 +00:00
// Mostly for fun (but can very slightly increase performance for large textures). If set to 1, does not clear texture's affiliated and leaves garbage.
# define ENGINE_GENERIC_TEXTURE_NOCLEAR 1
struct ENGINE_TEXTURE { int width ; int height ; void * fe_texture ; } ;
struct ENGINE_GENERIC_TEXTURE { char * pixels ; } ;
2023-05-14 16:55:16 +00:00
struct ENGINE_TEXTURE * engine_texture_create ( int width , int height ) {
2023-05-14 10:21:03 +00:00
// frontend texture
char * pixels = engine_malloc ( NULL , sizeof ( char ) * width * height * 4 ) ;
# if (ENGINE_GENERIC_TEXTURE_NOCLEAR == 0)
memset ( pixels , 0 , sizeof ( char ) * width * height * 4 ) ;
# endif
struct ENGINE_GENERIC_TEXTURE * fe_texture = engine_malloc ( NULL , sizeof ( struct ENGINE_GENERIC_TEXTURE ) ) ;
fe_texture - > pixels = pixels ;
// engine texture
struct ENGINE_TEXTURE * texture = engine_malloc ( NULL , sizeof ( struct ENGINE_TEXTURE ) ) ;
texture - > width = width ;
texture - > height = height ;
texture - > fe_texture = ( void * ) fe_texture ;
return texture ;
}
struct ENGINE_GENERIC_TEXTURE_COLOR { char r ; char g ; char b ; char a ; } ;
struct ENGINE_GENERIC_TEXTURE_COLOR engine_generic_texture_color ;
2023-05-14 15:48:31 +00:00
void engine_texture_color_set ( char r , char g , char b , char a ) {
2023-05-14 10:21:03 +00:00
engine_generic_texture_color . r = r ;
engine_generic_texture_color . g = g ;
engine_generic_texture_color . b = b ;
engine_generic_texture_color . a = a ;
}
2023-05-14 15:48:31 +00:00
void engine_texture_draw_pixel ( struct ENGINE_TEXTURE * texture , int x , int y ) {
2023-05-14 10:21:03 +00:00
char * pixels = ( ( struct ENGINE_GENERIC_TEXTURE * ) ( texture - > fe_texture ) ) - > pixels ;
long pixelIndex = ( x + y * texture - > width ) * 4 ;
pixels [ pixelIndex + 0 ] = engine_generic_texture_color . r ;
pixels [ pixelIndex + 1 ] = engine_generic_texture_color . g ;
pixels [ pixelIndex + 2 ] = engine_generic_texture_color . b ;
pixels [ pixelIndex + 3 ] = engine_generic_texture_color . a ;
}
2023-05-14 15:48:31 +00:00
void engine_texture_destroy ( struct ENGINE_TEXTURE * texture ) {
2023-05-14 10:21:03 +00:00
struct ENGINE_GENERIC_TEXTURE * fe_texture = ( struct ENGINE_GENERIC_TEXTURE * ) ( texture - > fe_texture ) ;
engine_free ( fe_texture - > pixels ) ;
engine_free ( fe_texture ) ;
engine_free ( texture ) ;
}
2023-05-14 15:48:31 +00:00
void engine_texture_render_2d ( struct ENGINE_TEXTURE * texture , int sx , int sy ) {
2023-05-14 10:21:03 +00:00
char * pixels = ( ( struct ENGINE_GENERIC_TEXTURE * ) ( texture - > fe_texture ) ) - > pixels ;
int ex = sx + texture - > width ;
if ( ex > engine_width ) { ex = engine_width ; }
int ey = sy + texture - > height ;
if ( ey > engine_width ) { ey = engine_height ; }
int x = sx ;
if ( x < 0 ) { x = 0 ; }
int y = sy ;
if ( y < 0 ) { y = 0 ; }
long pixelIndex = 0 ;
while ( y < ey ) {
while ( x < ex ) {
pixelIndex = ( ( x - sx ) + ( y - sy ) * texture - > width ) * 4 ;
2023-05-14 15:48:31 +00:00
engine_surface_color_set ( pixels [ pixelIndex ] , pixels [ pixelIndex + 1 ] , pixels [ pixelIndex + 2 ] , pixels [ pixelIndex + 3 ] ) ;
engine_surface_draw_pixel ( x , y ) ;
2023-05-14 10:21:03 +00:00
+ + x ;
}
x = sx ;
+ + y ;
}
}
2023-05-14 15:48:31 +00:00
void engine_texture_from_file ( struct ENGINE_TEXTURE * texture , char * fpath ) {
2023-05-14 10:21:03 +00:00
FILE * f = fopen ( fpath , " r " ) ;
fgets ( ( ( struct ENGINE_GENERIC_TEXTURE * ) ( texture - > fe_texture ) ) - > pixels , texture - > width * texture - > height , f ) ;
fclose ( f ) ;
}