unigi.ext/main.c

105 lines
3.7 KiB
C
Raw Normal View History

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);
}