2024-09-10 23:53:56 +00:00
# include "unigi.ext/main.h"
void unigi_ext_texture_draw (
unigi_ext_type_texture tex ,
unigi_ext_type_texture buffer ,
unigi_ext_type_rect texbounds ,
unigi_ext_type_rect bufbounds
) {
unigi_ext_type_2d_coord texwidth ;
unigi_ext_type_2d_coord texheight ;
unigi_ext_type_2d_coord outwidth ;
unigi_ext_type_2d_coord outheight ;
unigi_ext_type_2d_coord x ;
unigi_ext_type_2d_coord y ;
unigi_type_resolution_1d_coord texi ;
unigi_type_resolution_1d_coord bufi ;
unigi_ext_type_2d_coord stepx ;
unigi_ext_type_2d_coord stepy ;
unigi_ext_type_2d_coord texx ;
unigi_ext_type_2d_coord texy ;
unigi_ext_rect_dimensions ( texbounds , & texwidth , & texheight ) ;
unigi_ext_rect_dimensions ( bufbounds , & outwidth , & outheight ) ;
// We precalculate the step through the texture to avoid division and
// multiplication per pixel. We also expand the range so we can use
// integers. By using 256, we are essentially adding 8 bits of "decimal
// point". If you need more bits (or less), just change this to some other
// power of 2.
stepx = ( 1 < < unigi_ext_texture_fixedpointdepth ) * ( float ) texwidth / outwidth ;
stepy = ( 1 < < unigi_ext_texture_fixedpointdepth ) * ( float ) texheight / outheight ;
texx = ( 1 < < unigi_ext_texture_fixedpointdepth ) * texbounds . x1 ;
texy = ( 1 < < unigi_ext_texture_fixedpointdepth ) * texbounds . y1 ;
//log("%f,%f step %f,%f", texx, texy, stepx, stepy);
// Buffer is R G B for each pixel, then across then down. If you want X, Y,
// it's: 3 * (x + y * width)
for ( y = bufbounds . y1 ; y < bufbounds . y2 ; y + + ) {
texx = texbounds . x1 ;
for ( x = bufbounds . x1 ; x < bufbounds . x2 ; x + + ) {
// And then with the shift, it is log2(256), or whatever you shifted
// by up there. So 512 would be 9, because 2^9 = 512
texi = ( texx > > unigi_ext_texture_fixedpointdepth ) + tex . width * ( texy > > unigi_ext_texture_fixedpointdepth ) ; // 'texy >> FIXEDPOINTDEPTH' could be calculated per y-iteration
bufi = x + y * buffer . width ; // 'y * buffer.width' could be calculated per y-iteration
buffer . pixels [ bufi ] = tex . pixels [ texi ] ;
texx + = stepx ;
bufi + = 1 ;
}
texy + = stepy ;
}
}
2024-09-13 21:25:10 +00:00
unigi_ext_type_texture * unigi_ext_texture_create ( unigi_ext_type_2d_coord width , unigi_ext_type_2d_coord height ) {
unigi_ext_type_texture * texture = malloc ( sizeof ( unigi_ext_type_texture ) ) ;
if ( texture = = NULL ) { return NULL ; }
texture - > width = width ;
texture - > height = height ;
texture - > pixels = malloc ( sizeof ( unigi_type_color ) * width * height ) ;
if ( texture - > pixels = = NULL ) {
free ( texture ) ;
return NULL ;
}
return texture ;
}
void unigi_ext_texture_destroy ( unigi_ext_type_texture * texture ) {
free ( texture - > pixels ) ;
free ( texture ) ;
}
# include <unistd.h>
# include <fcntl.h>
unigi_ext_type_texture * unigi_ext_texture_open ( char * path ) {
int fd = open ( path , O_RDONLY ) ;
if ( fd = = - 1 ) { goto fail ; }
unigi_ext_type_2d_coord width ;
unigi_ext_type_2d_coord height ;
if ( read ( fd , & width , sizeof ( uint16_t ) ) ! = sizeof ( uint16_t ) ) { goto fail_file ; }
if ( read ( fd , & height , sizeof ( uint16_t ) ) ! = sizeof ( uint16_t ) ) { goto fail_file ; }
unigi_ext_type_texture * texture = unigi_ext_texture_create ( width , height ) ;
if ( texture = = NULL ) { goto fail_file ; }
if ( read ( fd , texture - > pixels , sizeof ( uint16_t ) * width * height ) ! = sizeof ( uint16_t ) * width * height ) {
goto fail_texture ;
}
close ( fd ) ;
return texture ;
fail_texture : ;
unigi_ext_texture_destroy ( texture ) ;
fail_file : ;
close ( fd ) ;
fail : ;
return NULL ;
}
2024-09-10 23:53:56 +00:00
void unigi_ext_rect_dimensions (
unigi_ext_type_rect bounds ,
unigi_ext_type_2d_coord * width ,
unigi_ext_type_2d_coord * height
) {
* width = abs ( bounds . x2 - bounds . x1 ) ;
* height = abs ( bounds . y2 - bounds . y1 ) ;
}