texstretch/main.c

118 lines
3.6 KiB
C
Raw Normal View History

2024-07-22 23:19:27 +00:00
#include <stdio.h>
#include <stdlib.h>
2024-07-22 23:40:13 +00:00
#include <stdint.h>
#include <string.h>
2024-07-23 00:24:54 +00:00
#include <math.h>
2024-07-23 00:38:24 +00:00
#include <time.h>
2024-07-23 00:24:54 +00:00
// You need to generate this with textoc.h
#include "texture.h"
2024-07-22 23:40:13 +00:00
typedef uint8_t u8;
2024-07-23 00:44:09 +00:00
typedef int32_t i32;
2024-07-22 23:40:13 +00:00
#define CDEPTH 255
#define log(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
#define panic(fmt, ...) { fprintf(stderr, "PANIC: " fmt "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
2024-07-23 00:24:54 +00:00
// A simple designation of a rectangle
struct rect {
int x1, y1; // Inclusive
int x2, y2; // Exclusive
};
// Compute the dimensions of a rect
void rect_dims(struct rect bounds, int * width, int * height) {
*width = abs(bounds.x2 - bounds.x1);
*height = abs(bounds.y2 - bounds.y1);
}
// A simple designation of a texture
struct texture {
int width, height;
u8 * data;
};
2024-07-22 23:40:13 +00:00
// fb is framebuffer. Thsi dumps a color version (rgb) of a framebuffer
// to stdout, which you can pipe to a file or some shit idk
2024-07-23 00:24:54 +00:00
void dump_ppm(struct texture fb) {
log("Dumping framebuffer %dx%d", fb.width, fb.height);
printf("P3\n%d %d\n%d\n# Image start\n", fb.width, fb.height, CDEPTH);
for(int i = 0; i < fb.width * fb.height * 3; i+=3)
printf("%d %d %d\n", fb.data[i], fb.data[i+1], fb.data[i+2]);
2024-07-22 23:40:13 +00:00
printf("\n");
}
2024-07-22 23:19:27 +00:00
2024-07-23 00:24:54 +00:00
// ------------------------------------------------------
// * THIS IS THE FUNCTION YOU WANT <3 *
// ------------------------------------------------------
void drawTexInto(struct texture tex, struct texture buffer, struct rect texbounds, struct rect bufbounds) {
int texwidth, texheight, outwidth, outheight;
rect_dims(texbounds, &texwidth, &texheight);
rect_dims(bufbounds, &outwidth, &outheight);
// We precalculate the step through the texture to avoid division and
2024-07-23 01:11:03 +00:00
// 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.
2024-07-23 00:44:09 +00:00
i32 stepx = 256 * (float)texwidth / outwidth;
i32 stepy = 256 * (float)texheight / outheight;
i32 texx = 256 * texbounds.x1;
i32 texy = 256 * texbounds.y1;
2024-07-23 00:38:24 +00:00
//log("%f,%f step %f,%f", texx, texy, stepx, stepy);
2024-07-23 00:24:54 +00:00
// Buffer is R G B for each pixel, then across then down. If you want X, Y,
// it's: 3 * (x + y * width)
for(int y = bufbounds.y1; y < bufbounds.y2; y++) {
texx = texbounds.x1;
for(int x = bufbounds.x1; x < bufbounds.x2; x++) {
2024-07-23 01:11:03 +00:00
// 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
2024-07-23 00:44:09 +00:00
i32 texi = 3 * ((texx >> 8) + tex.width * (texy >> 8));
2024-07-23 01:01:14 +00:00
i32 bufi = 3 * (x + y * buffer.width);
memcpy(buffer.data + bufi, tex.data + texi, 3);
2024-07-23 00:24:54 +00:00
texx += stepx;
bufi += 3;
2024-07-23 00:24:54 +00:00
}
texy += stepy;
}
}
2024-07-22 23:19:27 +00:00
int main() {
2024-07-22 23:40:13 +00:00
log("Program start");
const int width = 512;
const int height = 512;
2024-07-23 00:24:54 +00:00
const int fbsize = width * height * 3;
2024-07-22 23:40:13 +00:00
2024-07-23 00:24:54 +00:00
struct texture fb = {
width, height,
calloc(fbsize, 1)
};
if(!fb.data) panic("Can't allocate framebuffer");
// Initialize the texture. It's already defined elsewhere
struct texture tex = {
mytex_width, mytex_height, mytex
};
2024-07-22 23:40:13 +00:00
2024-07-23 00:24:54 +00:00
// We actually stretch a texture here
2024-07-23 01:11:03 +00:00
struct rect texrect = { 0, 0, 8, 12 };
struct rect bufrect = { 10, 10, 509, 499 };
2024-07-23 00:38:24 +00:00
clock_t start = clock();
for(int i = 0; i < 50; i++) { //overdraw factor
2024-07-23 00:38:24 +00:00
drawTexInto(tex, fb, texrect, bufrect);
}
clock_t end = clock();
double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
log("1000 iterations took: %fs", cpu_time_used);
2024-07-22 23:40:13 +00:00
2024-07-23 00:24:54 +00:00
// Dump the image to the ppm
dump_ppm(fb);
2024-07-22 23:40:13 +00:00
log("Program end");
2024-07-22 23:19:27 +00:00
}