Skip to content

Instantly share code, notes, and snippets.

@TerrorBite
Created February 26, 2016 00:02
Show Gist options
  • Save TerrorBite/423de4e81e6c4a785661 to your computer and use it in GitHub Desktop.
Save TerrorBite/423de4e81e6c4a785661 to your computer and use it in GitHub Desktop.
Framebuffer rendering thing
#!/bin/sh
gcc -std=gnu99 -o fbtoy main.c framebuffer.c draw.c -lm -g
#include "draw.h"
framebuffer* draw_fb;
ARGB_color active_color;
const int CLIP_INSIDE = 0;
const int CLIP_LEFT = 1;
const int CLIP_RIGHT = 2;
const int CLIP_BOTTOM = 4;
const int CLIP_TOP = 8;
void draw_setfb(framebuffer* fb) {
draw_fb = fb;
}
framebuffer* draw_getfb(framebuffer* fb) {
return draw_fb;
}
void draw_setcolor(ARGB_color color) {
active_color = color;
}
typedef void (*_linedraw_func)(double, double, double, double);
int _clip_get_outcode(double x, double y) {
int code = CLIP_INSIDE;
int xmax = draw_fb->vinfo.xres-1, ymax = draw_fb->vinfo.yres-1;
if(x<0) code |= CLIP_LEFT;
else if(x>xmax) code |= CLIP_RIGHT;
if(y<0) code |= CLIP_BOTTOM;
else if(y>ymax) code |= CLIP_TOP;
return code;
}
void _clip(_linedraw_func func, double x0, double y0, double x1, double y1) {
const int xmin = 0, ymin = 0;
int xmax = draw_fb->vinfo.xres-1, ymax = draw_fb->vinfo.yres-1;
int outcode0 = _clip_get_outcode(x0, y0);
int outcode1 = _clip_get_outcode(x1, y1);
int accept = 0;
while(1) {
if(!(outcode0 | outcode1)) {
/* Line is entirely within the viewport */
accept = 1;
break;
} else if(outcode0 & outcode1) {
/* A line drawn between these points will not cross the viewport at all */
break;
} else {
/* A line drawn between these points will cross the edge of the viewport */
/* So we need to clip it */
double x, y;
/* at least one outcode is outside the viewport, grab the first one */
int outside = outcode0 ? outcode0 : outcode1;
int dx = (x1 - x0), dy = (y1 - y0);
/* Find the intersection point */
if(outside & CLIP_TOP) { // point is above the viewport
x = x0 + dx * (ymax - y0) / dy;
y = ymax;
} else if(outside & CLIP_BOTTOM) { // point is below the viewport
x = x0 + dx * (ymin - y0) / dy;
y = ymin;
} else if(outside & CLIP_RIGHT) { // point is to the right
y = y0 + dy * (xmax - x0) / dx;
x = xmax;
} else if(outside & CLIP_LEFT) { // to the left
y = y0 + dy * (xmin - x0) / dx;
x = xmin;
}
/* Move outside point to intersection point */
if(outside == outcode0) {
x0 = x; y0 = y;
outcode0 = _clip_get_outcode(x0, y0);
} else {
x1 = x; y1 = y;
outcode1 = _clip_get_outcode(x1, y1);
}
}
}
if(accept) (*func)(x0, y0, x1, y1);
}
void _draw_line(double x0, double y0, double x1, double y1) {
/* Implements Bresenham's line algorithm in software */
int8_t xsign = (x1>x0)?1:-1, ysign = (y1>y0)?1:-1;
x0 = round(x0); x1=round(x1);
y0 = round(y0); y1=round(y1);
double dx = (x1-x0)*xsign, dy = (y1-y0)*ysign, error = 0.0, delta;
int i, x=x0, y=y0;
/* To improve accuracy, we swap x and y depending on slope */
if(dx > dy) {
for(i=0; i<=dx; i++, x+=xsign) {
draw_point(x, y);
error += dy;
while(error >= dx) {
y += ysign;
error -= dx;
}
}
} else {
for(i=0; i<=dy; i++, y+=ysign) {
draw_point(x, y);
error += dx;
while(error >= dy) {
x += xsign;
error -= dy;
}
}
}
}
/*void draw_line_int(int x0, int y0, int x1, int y1) {
_clip(&_draw_line, (double)x0, (double)y0, (double)x1, (double)y1);
}*/
void draw_line(double x0, double y0, double x1, double y1) {
_clip(&_draw_line, x0, y0, x1, y1);
}
inline double round(const double r) { return floor(r)+0.5; }
#define draw_point_asqrt(x,y,alpha) draw_point_alpha(x,y,sqrt(alpha))
void _draw_line_aa(double x0, double y0, double x1, double y1) {
/* Implements Xiaolin Wu's line algorithm in software */
/*uint8_t xsign = (x1>x0)?1:-1, ysign = (y1>y0)?1:-1;*/
int steep = fabs(y1-y0) > fabs(x1-x0);
double temp;
if(steep) {
temp=x0; x0=y0; y0=temp; /* swap(x0, y0) */
temp=x1; x1=y1; y1=temp; /* swap(x1, y1) */
}
if(x0 > x1) {
temp=x0; x0=x1; x1=temp; /* swap(x0, x1) */
temp=y0; y0=y1; y1=temp; /* swap(y0, y1) */
}
double dx = x1 - x0, dy = y1 - y0;
double gradient = dy / dx;
double xend, yend, xgap, ygap;
/* Calculate first endpoint */
xend = round(x0);
yend = y0 + gradient * (xend - x0);
xgap = 1.0-modf(x0+0.5, &temp); /* throw away integer part */
ygap = modf(yend, &temp);
int intx1 = (int)xend, inty1 = (int)temp; /* will be used in the main loop */
/* Draw first endpoint */
if(steep) {
draw_point_asqrt(inty1, intx1, (1.0-ygap)*xgap);
draw_point_asqrt(inty1+1, intx1, ygap*xgap);
} else {
draw_point_asqrt(intx1, inty1, (1.0-ygap)*xgap);
draw_point_asqrt(intx1, inty1+1, ygap*xgap);
}
double y_inter = yend + gradient; /* First y-intersect for main loop */
/* Calculate second endpoint */
xend = round(x1);
yend = y1 + gradient * (xend - x1);
xgap = modf(x1+0.5, &temp); /* throw away integer part */
ygap = modf(yend, &temp);
int intx2 = (int)xend, inty2 = (int)temp;
/* Draw second endpoint */
if(steep) {
draw_point_asqrt(inty2, intx2, (1.0-ygap)*xgap);
draw_point_asqrt(inty2+1, intx2, ygap*xgap);
} else {
draw_point_asqrt(intx2, inty2, (1.0-ygap)*xgap);
draw_point_asqrt(intx2, inty2+1, ygap*xgap);
}
/* main loop */
double f_yint;
int x, i_yint;
for(x = intx1+1; x<intx2; x++) {
f_yint = modf(y_inter, &temp); i_yint = (int)temp;
if(steep) {
draw_point_asqrt(i_yint, x, 1.0-f_yint);
draw_point_asqrt(i_yint+1, x, f_yint);
} else {
draw_point_asqrt(x, i_yint, 1.0-f_yint);
draw_point_asqrt(x, i_yint+1, f_yint);
}
y_inter += gradient;
}
}
void draw_line_aa(double x0, double y0, double x1, double y1) {
_clip(&_draw_line_aa, x0, y0, x1, y1);
}
void draw_point(int x, int y) {
if(_clip_get_outcode(x,y)) return;
fb_setpixel(draw_fb, x, y, active_color);
}
void draw_point_alpha(int x, int y, double alpha) {
/* Compositing */
ARGB color;
color.argb = active_color; color.a = alpha*255;
fb_blend_over(draw_fb, x, y, color.argb);
}
void draw_clear(void) {
fb_clear(draw_fb);
}
#ifndef _DRAW_H
#define _DRAW_H
#include <math.h>
#include "framebuffer.h"
#define ARGB_WHITE 0xFFFFFFFFu
#define ARGB_BLACK 0xFF000000u
#define ARGB_RED 0xFFFF0000u
#define ARGB_GREEN 0xFF00FF00u
#define ARGB_BLUE 0xFF0000FFu
#define ARGB_YELLOW 0xFFFFFF00u
#define ARGB_MAGENTA 0xFFFF00FFu
#define ARGB_CYAN 0xFF00FFFFu
#define ARGB_GREY 0xFF666666u
#define ARGB_LIGHTGREY 0xFFAAAAAAu
void draw_setfb(framebuffer* fb);
framebuffer* draw_getfb();
void draw_setcolor(ARGB_color color);
/*void draw_line_int(int x1, int y1, int x2, int y2);*/
void draw_line(double x0, double y0, double x1, double y1);
void draw_line_aa(double x0, double y0, double x1, double y1);
void draw_point(int x, int y);
void draw_point_alpha(int x, int y, double alpha);
void draw_clear(void);
#endif
#include "framebuffer.h"
framebuffer* fb_open(int index, int flags) {
char filename[16];
framebuffer* fb;
fb = malloc(sizeof(framebuffer));
sprintf(filename, "/dev/fb%d", index);
/* Try to open the file */
fb->fd = open(filename, O_RDWR);
if(fb->fd < 0) {
printf("Failed to open /dev/fb0 - aborting\n");
return NULL;
}
/* Get information about framebuffer */
if(ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vinfo) < 0) {
printf("ioctl failed!\n");
return NULL;
}
fb->vinfo.bits_per_pixel = FBTEST_BPP;
fb->vinfo.yres_virtual = 2*fb->vinfo.yres_virtual;
printf("Doubling buffer to %d lines (if possible)... ", fb->vinfo.yres_virtual);
if(ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vinfo) < 0) {
printf("ioctl failed!\n");
return NULL;
};
fb->width = fb->vinfo.xres;
fb->height = fb->vinfo.yres;
printf("%d lines\n", fb->vinfo.yres_virtual);
ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->finfo);
/* Calculate framebuffer length in bytes */
fb->size = fb->vinfo.yres_virtual * fb->finfo.line_length;
printf("Framebuffer length is 0x%zx (%zd) bytes\nPerforming mmap... ", fb->size, fb->size);
/* Map the framebuffer into memory*/
fb->buffer = (uint32_t*)mmap(NULL, fb->size, PROT_READ|PROT_WRITE, MAP_SHARED, fb->fd, 0);
printf("mapped to %p\n", fb->buffer);
return fb;
}
int fb_close(framebuffer* fb) {
if(fb != NULL && fb->buffer != NULL) {
munmap(fb->buffer, fb->size);
fb->buffer = NULL;
close(fb->fd);
free(fb);
}
}
void fb_fill(framebuffer* fb, ARGB_color color) {
const int limit = fb->size>>2;
int i=0;
for(i=0; i < limit; i++) fb->buffer[i]=color;
}
int _getindex(framebuffer* fb, int x, int y) {
/* This assumes that the buffer is 32bpp */
int index=(x+fb->vinfo.xoffset) + (y+fb->vinfo.yoffset) * fb->vinfo.xres_virtual;
#ifdef DEBUG_TRAP_OOB
if(index<0 || index >= fb->size>>2) {
printf("Aborting: Out of bounds write detected (x=%d, y=%d)\n", x, y);
fb_close(fb);
exit(-1);
}
#endif
return index;
}
void fb_setpixel(framebuffer* fb, int x, int y, ARGB_color value) {
fb->buffer[_getindex(fb,x,y)] = value;
}
void fb_blend_over(framebuffer* fb, int x, int y, ARGB_color value) {
int index = _getindex(fb, x, y);
ARGB bg, fg, color;
bg.argb = fb->buffer[index];
fg.argb = value;
float alpha = (float)fg.a / 255;
color.r = fg.r*alpha + bg.r*(1-alpha);
color.g = fg.g*alpha + bg.g*(1-alpha);
color.b = fg.b*alpha + bg.b*(1-alpha);
color.a = 255;
fb->buffer[index] = color.argb;
}
ARGB_color fb_getpixel(framebuffer* fb, int x, int y) {
return fb->buffer[_getindex(fb,x,y)];
}
void fb_clear(framebuffer* fb) {
memset(fb->buffer, 0, fb->size);
}
ARGB_color fb_rgb(framebuffer* fb, uint8_t r, uint8_t g, uint8_t b) {
return (r<<fb->vinfo.red.offset) |
(g<<fb->vinfo.green.offset) |
(b<<fb->vinfo.blue.offset);
}
ARGB_color fb_rgba(framebuffer* fb, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return fb_rgb(fb, r, g, b) | (a<<fb->vinfo.transp.offset);
}
#ifndef _FRAMEBUFFER_H
#define _FRAMEBUFFER_H
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define FBTEST_FLAGS_NONE 0
#define FBTEST_BPP 32;
#define DEBUG_TRAP_OOB
typedef struct {
int fd;
uint16_t width, height;
uint32_t* buffer;
size_t size;
uint32_t flags;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
} framebuffer;
typedef uint32_t ARGB_color;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
typedef union {
ARGB_color argb;
struct {
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
};
} ARGB;
#else
typedef union {
ARGB_color argb;
struct {
uint8_t a;
uint8_t r;
uint8_t g;
uint8_t b;
};
} ARGB;
#endif
framebuffer* fb_open(int index, int flags);
int fb_close(framebuffer* fb);
void fb_fill(framebuffer* fb, uint32_t color);
void fb_setpixel(framebuffer* fb, int x, int y, uint32_t value);
void fb_blend_over(framebuffer* fb, int x, int y, uint32_t value);
ARGB_color fb_getpixel(framebuffer* fb, int x, int y);
void fb_clear(framebuffer* fb);
ARGB_color fb_rgb(framebuffer* fb, uint8_t r, uint8_t g, uint8_t b);
ARGB_color fb_rgba(framebuffer* fb, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
#endif
#include "main.h"
int main(int argc, char* argv[], char* env[]) {
int i, j;
printf("Welcome to framebuffer test\n");
framebuffer* fb = fb_open(0, FBTEST_FLAGS_NONE);
/* Do a test */
printf("Bits Per Pixel: %d\n"
"Value | Off | Len | Shift\n"
" Red | %3d | %3d | %3d\n"
"Green | %3d | %3d | %3d\n"
" Blue | %3d | %3d | %3d\n"
"Alpha | %3d | %3d | %3d\n",
fb->vinfo.bits_per_pixel,
fb->vinfo.red.offset, fb->vinfo.red.length, fb->vinfo.red.msb_right,
fb->vinfo.green.offset, fb->vinfo.green.length, fb->vinfo.green.msb_right,
fb->vinfo.blue.offset, fb->vinfo.blue.length, fb->vinfo.blue.msb_right,
fb->vinfo.transp.offset, fb->vinfo.transp.length, fb->vinfo.transp.msb_right);
printf("Assuming 32bpp ARGB format\n");
draw_setfb(fb);
/* Define a set of lines to draw * /
double lines[23][4] = {
{-5.0, -5.0, -5.0, 5.0},
{-4.0, -5.0, -4.0, 5.0},
{-3.0, -5.0, -3.0, 5.0},
{-2.0, -5.0, -2.0, 5.0},
{-1.0, -5.0, -1.0, 5.0},
{0.0, -5.0, 0.0, 5.0},
{1.0, -5.0, 1.0, 5.0},
{2.0, -5.0, 2.0, 5.0},
{3.0, -5.0, 3.0, 5.0},
{4.0, -5.0, 4.0, 5.0},
{5.0, -5.0, 5.0, 5.0},
{-5.0, -5.0, 5.0, -5.0},
{-5.0, -4.0, 5.0, -4.0},
{-5.0, -3.0, 5.0, -3.0},
{-5.0, -2.0, 5.0, -2.0},
{-5.0, -1.0, 5.0, -1.0},
{-5.0, 0.0, 5.0, 0.0},
{-5.0, 1.0, 5.0, 1.0},
{-5.0, 2.0, 5.0, 2.0},
{-5.0, 3.0, 5.0, 3.0},
{-5.0, 4.0, 5.0, 4.0},
{-5.0, 5.0, 5.0, 5.0},
{NAN, NAN, NAN, NAN}
};
double camera_posx = 0.0, camera_posy = 0.0, camera_rotation = 0.0;
for(double* line=(double*)lines;;line+=4) {
if(isnan(line[0])) break;
/ *printf("%f, %f, %f, %f\n", line[0], line[1], line[2], line[3]);* /
3d_draw(line, camera_posx, camera_posy, 2.0, camera_rotation);
}
printf("End of list\n");
*/
camera3d cam = {
.xpos = 0.0,
.ypos = 2.0,
.zpos = -10.0,
.yaw = 0.0,
.pitch = 0.0,
.fov = 1.0,
.distort = 0.0
}; /* camera position/rotation */
test_render(cam);
/* Get a nice keyboard. Later we might use raw mode */
static struct termios old_t, new_t;
tcgetattr(STDIN_FILENO, &old_t);
new_t = old_t;
new_t.c_lflag &= ~(ICANON|ECHO); /* disable ICANON and ECHO */
/* cfmakeraw(new_t); */
tcsetattr(STDIN_FILENO, TCSANOW, &new_t);
setvbuf(stdin, NULL, _IONBF, 0);
while(1) {
char input = getchar();
switch(input) {
case '4':
cam.yaw -= 0.1/cam.fov;
break;
case '6':
cam.yaw += 0.1/cam.fov;
break;
case '2':
cam.pitch += 0.1/cam.fov;
if(cam.pitch > HALF_PI) cam.pitch = HALF_PI;
break;
case '8':
cam.pitch -= 0.1/cam.fov;
if(cam.pitch < -HALF_PI) cam.pitch = -HALF_PI;
break;
case '+':
cam.fov *= 1.25;
break;
case '-':
cam.fov *= 0.8;
break;
case '5':
cam.yaw = 0.0;
cam.pitch = 0.0;
cam.fov = 1.0;
cam.distort = 0.0;
break;
case 'w':
cam.zpos += 0.8;
break;
case 's':
cam.zpos -= 0.8;
break;
case 'a':
cam.xpos -= 0.8;
break;
case 'd':
cam.xpos += 0.8;
break;
case '*':
cam.distort += 0.1;
break;
case '/':
cam.distort -= 0.1;
break;
case 'q':
goto close;
}
test_render(cam);
}
close:
setvbuf(stdin, NULL, _IOFBF, 0);
tcsetattr(STDIN_FILENO, TCSANOW, &old_t);
fb_close(fb);
return 0;
}
void test_render(camera3d cam) {
draw_clear();
/* Draw horizon line */
draw_setcolor(ARGB_GREY);
double hpos = (0.5+tan(cam.pitch)*cam.fov)*480;
draw_line(0.0, hpos, 640.0, hpos);
/* Draw point grid */
draw_setcolor(ARGB_WHITE);
for(double wx=-20.0; wx<20.01; wx++) {
for(double wz=-20.0; wz<20.01; wz++) {
point_3d(wx, 0.0, wz, cam);
}
}
/* Draw a cube */
/* Define a set of lines to draw */
double lines[13][6] = {
{5.5, 0.0, 5.5, 6.5, 0.0, 5.5},
{5.5, 0.0, 5.5, 5.5, 0.0, 6.5},
{6.5, 0.0, 5.5, 6.5, 0.0, 6.5},
{5.5, 0.0, 6.5, 6.5, 0.0, 6.5},
{5.5, 1.0, 5.5, 6.5, 1.0, 5.5},
{5.5, 1.0, 5.5, 5.5, 1.0, 6.5},
{6.5, 1.0, 5.5, 6.5, 1.0, 6.5},
{5.5, 1.0, 6.5, 6.5, 1.0, 6.5},
{5.5, 0.0, 5.5, 5.5, 1.0, 5.5},
{5.5, 0.0, 6.5, 5.5, 1.0, 6.5},
{6.5, 0.0, 5.5, 6.5, 1.0, 5.5},
{6.5, 0.0, 6.5, 6.5, 1.0, 6.5},
{NAN, NAN, NAN, NAN, NAN, NAN}
};
for(double* line=(double*)lines;;line+=6) {
if(isnan(line[0])) break;
//printf("%f, %f, %f, %f, %f, %f\n", line[0], line[1], line[2], line[3], line[4], line[5]);
draw_3d(line, cam);
}
}
void point_3d(double wx, double wy, double wz, camera3d cam) {
/* Translation in 3D space*/
wx -= cam.xpos; wy -= cam.ypos; wz -= cam.zpos;
/* Rotation in 3D space (around Y axis): Camera yaw */
double rx = wx*cos(cam.yaw) - wz*sin(cam.yaw),
rz = wx*sin(cam.yaw) + wz*cos(cam.yaw);
/* Second rotation (around X axis): Camera pitch */
wz = rz;
double ry = wy*cos(cam.pitch) - wz*sin(cam.pitch);
rz = wy*sin(cam.pitch) + wz*cos(cam.pitch);
/* Discard any points that are now "behind" us i.e. the Z value is negative */
if(rz <= 0) {
//printf("Discarding point %f,%f,%f\n", rx,ry,rz);
return;
}
//printf("Drawing point %f,%f,%f\n", rx,ry,rz);
/* Map to screen coordinates */
double sy = -ry / rz * cam.fov;
double sx = rx / rz * cam.fov;
screen_draw_point(sx, sy);
}
void draw_3d(double points[], camera3d cam) {
/* Translation in 3D space*/
double wx0 = points[0] - cam.xpos, wx1 = points[3] - cam.xpos;
double wy0 = points[1] - cam.ypos, wy1 = points[4] - cam.ypos;
double wz0 = points[2] - cam.zpos, wz1 = points[5] - cam.zpos;
/* Rotation in 3D space (around Y axis): Camera yaw */
double rx0 = wx0*cos(cam.yaw) - wz0*sin(cam.yaw),
rz0 = wx0*sin(cam.yaw) + wz0*cos(cam.yaw);
double rx1 = wx1*cos(cam.yaw) - wz1*sin(cam.yaw),
rz1 = wx1*sin(cam.yaw) + wz1*cos(cam.yaw);
/* Second rotation (around X axis): Camera pitch */
wz0 = rz0; wz1 = rz1;
double ry0 = wy0*cos(cam.pitch) - wz0*sin(cam.pitch);
rz0 = wy0*sin(cam.pitch) + wz0*cos(cam.pitch);
double ry1 = wy1*cos(cam.pitch) - wz1*sin(cam.pitch);
rz1 = wy1*sin(cam.pitch) + wz1*cos(cam.pitch);
if(rz0 <= 0 || rz1 <= 0) {
// help I need a front clipping plane here
// Just bail out instead
return;
}
/* Translate 3d lines to 2d screen space */
double sy0 = -ry0/rz0 * cam.fov,
sx0 = rx0/rz0 * cam.fov,
sy1 = -ry1/rz1 * cam.fov,
sx1 = rx1/rz1 * cam.fov;
/* map center-origin screen coords to pixels */
double px0 = (0.5+sx0)*480,
px1 = (0.5+sx1)*480,
py0 = (0.5+sy0)*480,
py1 = (0.5+sy1)*480;
draw_line_aa(px0, py0, px1, py1);
}
void screen_draw_point(double sx, double sy) {
framebuffer* fb = draw_getfb();
/* map center-origin screen coords to pixels.
* Deliberately using yres for both of these */
draw_point( (0.5+sx)*fb->vinfo.yres, (0.5+sy)*fb->vinfo.yres );
//draw_line( (0.5+sx)*640, (0.5+sy)*480, 0, 0 );
}
void demo_rainbow(framebuffer* fb) {
for(int y=0; y<120; y++) {
for(int x=0; x<fb->width; x++) {
float alpha = y<20?1.f:1.f-((y-20)/100.f);
ARGB_color color = get_rainbow((float)x/(float)fb->width, alpha);
fb_blend_over(fb, x, y, color);
}
}
}
ARGB_color get_rainbow(float percent, float alpha) {
uint8_t red, green, blue;
float redf, greenf, bluef;
redf = 0.0; greenf = 0.0; bluef = 0.0;
double band = 0;
double hue = modf(percent*6.0, &band);
switch((int)band%6) {
case 0:
redf = 1.f; greenf = hue;
break;
case 1:
redf = 1.f-hue; greenf = 1.f;
break;
case 2:
greenf = 1.f; bluef = hue;
break;
case 3:
greenf = 1.f-hue; bluef = 1.f;
break;
case 4:
bluef = 1.f; redf = hue;
break;
case 5:
bluef = 1.f-hue; redf = 1.f;
break;
}
red = (uint8_t)(redf*255);
green = (uint8_t)(greenf*255);
blue = (uint8_t)(bluef*255);
return (uint8_t)(alpha*255)<<24 | red<<16 | green<<8 | blue;
}
#ifndef _MAIN_H
#define _MAIN_H
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include "framebuffer.h"
#include "draw.h"
/* Main.h */
#define HALF_PI 1.57079632679
typedef struct {
double xpos;
double ypos;
double zpos;
double yaw;
double pitch;
double fov;
double distort;
} camera3d;
void demo_rainbow(framebuffer* fb);
ARGB_color get_rainbow(float percent, float alpha);
void screen_draw_point(double sx, double sy);
void point_3d(double wx, double wy, double wz, camera3d cam);
void draw_3d(double[], camera3d cam);
void test_render(camera3d cam);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment