Speed up and fix unigi_ext_texture_draw
This commit is contained in:
parent
b1cc74007a
commit
d8789b7689
74
main.c
74
main.c
@ -1,48 +1,40 @@
|
||||
#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;
|
||||
void unigi_ext_texture_draw(unigi_ext_type_texture *sprite, unigi_ext_type_texture *fb, unigi_ext_type_rect texrect, unigi_ext_type_rect outrect) {
|
||||
// Precalc the step, as it's always the same even if we clip the rect
|
||||
unigi_ext_type_2d_coord tex_width, tex_height, out_width, out_height;
|
||||
unigi_ext_rect_dimensions(texrect,&tex_width,&tex_height);
|
||||
unigi_ext_rect_dimensions(outrect,&out_width,&out_height);
|
||||
int32_t stepx = (1 << unigi_ext_texture_fixedpointdepth) * (float)tex_width / out_width;
|
||||
int32_t stepy = (1 << unigi_ext_texture_fixedpointdepth) * (float)tex_height / out_height;
|
||||
int32_t texx_init = (1 << unigi_ext_texture_fixedpointdepth) * texrect.x1;
|
||||
int32_t texy = (1 << unigi_ext_texture_fixedpointdepth) * texrect.y1;
|
||||
// Clip the rect
|
||||
if (outrect.x1 < 0) {
|
||||
texx_init += stepx * -outrect.x1;
|
||||
outrect.x1 = 0;
|
||||
}
|
||||
if (outrect.y1 < 0) {
|
||||
texy += stepy * -outrect.y1;
|
||||
outrect.y1 = 0;
|
||||
}
|
||||
if (outrect.x2 >= fb->width) {
|
||||
outrect.x2 = fb->width - 1;
|
||||
}
|
||||
if (outrect.y2 >= fb->height) {
|
||||
outrect.y2 = fb->height - 1;
|
||||
}
|
||||
|
||||
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];
|
||||
for (int y = outrect.y1; y < outrect.y2; y++) {
|
||||
int32_t texx = texx_init;
|
||||
int yiter = y * fb->width;
|
||||
for (int x = outrect.x1; x < outrect.x2; x++) {
|
||||
uint16_t pix = sprite->pixels[((texy >> unigi_ext_texture_fixedpointdepth) * sprite->width) + (texx >> unigi_ext_texture_fixedpointdepth)];
|
||||
|
||||
if (pix & 0xF000) {
|
||||
fb->pixels[yiter + x] = pix;
|
||||
}
|
||||
texx += stepx;
|
||||
bufi += 1;
|
||||
}
|
||||
texy += stepy;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user