A tiny software raymarcher that attempts to render "n-dimension" manofold insertions as an image appearing to be a non-euclidean 3-dimensional space. Written for the uqcs hackathon 2020. This repo is a mirror of: https://github.com/ailrst/blackpink
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

177 lines
4.8 KiB

#include "main.h"
#include "queue.h"
#include "camera.h"
#include "distfuncs.h"
#include "types.h"
#include "vect.h"
#include <SDL2/SDL_blendmode.h>
#include <SDL2/SDL_gamecontroller.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_thread.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_video.h>
#include <stdlib.h>
int keyboardstate[322] = {}; // 322 is the number of SDLK_DOWN events
int exitnow = 0;
SDL_Renderer * ren;
Uint32 pixels[B_INTERNAL_HEIGHT][B_INTERNAL_WIDTH];
struct object white_sphere;
struct SDL_Window* make_window(void) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("error initializing SDL: %s\n", SDL_GetError());
}
return SDL_CreateWindow("sdl_tester",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
B_WINDOW_WIDTH, B_WINDOW_HEIGHT,
SDL_WINDOW_RESIZABLE);
}
void handle_inputs(void)
{
if (keyboardstate[SDL_SCANCODE_UP])
printf("up");
if (keyboardstate[SDL_SCANCODE_DOWN])
printf("down");
if (keyboardstate[SDL_SCANCODE_LEFT])
printf("left");
if (keyboardstate[SDL_SCANCODE_RIGHT])
printf("right");
if (keyboardstate[SDL_SCANCODE_ESCAPE]) {
exitnow = 1;
}
return;
};
int input_loop(void *ptr) {
int close = 0;
while (!close) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
exitnow = 1;
// *(int *)0 = 1; // segfault
break;
case SDL_KEYDOWN:
keyboardstate[event.key.keysym.scancode] = 1;
break;
case SDL_KEYUP:
keyboardstate[event.key.keysym.scancode] = 0;
break;
}
}
handle_inputs();
SDL_Delay(100);
}
return 0;
}
static int raymarch_threadfn(void *data) {
int id = *(int *)data;
/* draw stuff */
/* march the rays */
for (int i = 0; i < B_INTERNAL_WIDTH; i++) {
for (int j = 0; j < B_INTERNAL_HEIGHT; j++) {
/* checkerboard rendering */
if ((i + j * B_INTERNAL_WIDTH) % B_NUM_RAYMARCH_THREADS != id) {
continue;
}
//sdlb_draw_col_pixel(p.col, j, i);
pixels[j][i] = process_pixel(i, j);
}
}
free(data);
return 0;
}
int main(int argc, char **argv) {
SDL_Window * win = make_window();
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_RenderSetLogicalSize(ren, B_INTERNAL_HEIGHT, B_INTERNAL_HEIGHT);
// use this to turn on antristroptic filtering
// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
SDL_Thread *input_thread = SDL_CreateThread(input_loop, "input", (void *)NULL);
double elapsed;
Uint64 start, end;
white_sphere = new_sphere(100);
/* texture for drawing into */
SDL_Rect view = {.w = B_INTERNAL_WIDTH, .h = B_INTERNAL_HEIGHT, .x = 0, .y = 0};
SDL_Texture *texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STATIC, B_INTERNAL_WIDTH, B_INTERNAL_HEIGHT);
SDL_Thread ** threads = calloc(B_NUM_RAYMARCH_THREADS, sizeof(SDL_Thread *));
while (!exitnow) {
/* clear the view */
start = SDL_GetPerformanceCounter();
SDL_RenderClear(ren);
for (int i = 0; i < B_NUM_RAYMARCH_THREADS; i++) {
int *tid = malloc(sizeof(int));
*tid = i;
threads[i] = SDL_CreateThread(raymarch_threadfn, "raymarch", tid);
// tid is freed in raymarch_threadfn
}
for (int i = 0; i < B_NUM_RAYMARCH_THREADS; i++) {
int status;
SDL_WaitThread(threads[i], &status);
}
SDL_UpdateTexture(texture, &view, pixels, B_INTERNAL_WIDTH * sizeof(Uint32));
SDL_RenderCopy(ren, texture, NULL, NULL);
SDL_RenderPresent(ren);
end = SDL_GetPerformanceCounter();
double el = (1000 * (end - start) / SDL_GetPerformanceFrequency());
if (el > 0) {
elapsed = 1000 / el;
}
printf("\rframerate: %f", elapsed);
fflush(stdout);
}
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
}
/********************************************************************************
*
* DRAWING UTILITIES
*
*/
void sdlb_set_colour(struct colour col) {
struct colour c = get_rgb(col);
SDL_SetRenderDrawColor(ren, c.r, c.g, c.b, c.a);
}
void sdlb_draw_col_pixel(struct colour col, int x, int y) {
sdlb_set_colour(col);
SDL_RenderDrawPoint(ren, x, y);
}