Implement simple line drawing
This commit is contained in:
4
build.sh
4
build.sh
@@ -3,9 +3,9 @@
|
|||||||
cc="gcc"
|
cc="gcc"
|
||||||
warn="-std=c23 -pedantic -Wall -Wextra"
|
warn="-std=c23 -pedantic -Wall -Wextra"
|
||||||
opt="-O2 -march=native"
|
opt="-O2 -march=native"
|
||||||
libs="-I/usr/include/libdrm -ldrm"
|
libs="-I/usr/include/libdrm -ldrm -lm"
|
||||||
defs="-D_POSIX_C_SOURCE=200809L"
|
defs="-D_POSIX_C_SOURCE=200809L"
|
||||||
|
|
||||||
$cc $flags $libs $defs \
|
$cc $flags $libs $defs \
|
||||||
-o asteroids \
|
-o asteroids \
|
||||||
fb.c input.c main.c renderer.c
|
fb.c input.c main.c maths.c renderer.c
|
||||||
|
|||||||
11
main.c
11
main.c
@@ -5,9 +5,17 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||||
|
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
static bool quit = false;
|
static bool quit = false;
|
||||||
|
|
||||||
|
static const vec2_t ship[] = {
|
||||||
|
{ 0.0, 0.1 },
|
||||||
|
{ 0.05, -0.1 },
|
||||||
|
{ 0.0, -0.05 },
|
||||||
|
{ -0.05, -0.1 },
|
||||||
|
};
|
||||||
|
|
||||||
static void key_press_callback(int key)
|
static void key_press_callback(int key)
|
||||||
{
|
{
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@@ -45,7 +53,8 @@ int main()
|
|||||||
|
|
||||||
if (FD_ISSET(drm_fd, &set)) {
|
if (FD_ISSET(drm_fd, &set)) {
|
||||||
renderer_handle();
|
renderer_handle();
|
||||||
renderer_draw();
|
renderer_clear();
|
||||||
|
renderer_draw(ship, NELEMS(ship));
|
||||||
renderer_swap();
|
renderer_swap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
maths.c
Normal file
15
maths.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "maths.h"
|
||||||
|
|
||||||
|
vec3_t vec2_extend(vec2_t v)
|
||||||
|
{
|
||||||
|
return (vec3_t) { v.x, v.y, 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3_t mat3_mul_vec3(mat3_t m, vec3_t v)
|
||||||
|
{
|
||||||
|
return (vec3_t) {
|
||||||
|
.x = m.x.x * v.x + m.y.x * v.y + m.z.x * v.z,
|
||||||
|
.y = m.x.y * v.x + m.y.y * v.y + m.z.y * v.z,
|
||||||
|
.z = m.x.z * v.x + m.y.z * v.y + m.z.z * v.z,
|
||||||
|
};
|
||||||
|
}
|
||||||
24
maths.h
Normal file
24
maths.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef MATHS_H
|
||||||
|
#define MATHS_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} vec2_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} vec3_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3_t x;
|
||||||
|
vec3_t y;
|
||||||
|
vec3_t z;
|
||||||
|
} mat3_t;
|
||||||
|
|
||||||
|
vec3_t vec2_extend(vec2_t v);
|
||||||
|
vec3_t mat3_mul_vec3(mat3_t m, vec3_t v);
|
||||||
|
|
||||||
|
#endif
|
||||||
55
renderer.c
55
renderer.c
@@ -4,10 +4,14 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
|
||||||
|
#define MAX_VERTS_PER_DRAW 8U
|
||||||
|
|
||||||
static int drm_fd;
|
static int drm_fd;
|
||||||
static drmModeConnector *conn;
|
static drmModeConnector *conn;
|
||||||
static drmModeCrtc *crtc;
|
static drmModeCrtc *crtc;
|
||||||
@@ -17,18 +21,35 @@ static fb_info_t fbs[2];
|
|||||||
static int front, back;
|
static int front, back;
|
||||||
|
|
||||||
static uint32_t width, height;
|
static uint32_t width, height;
|
||||||
|
static mat3_t view;
|
||||||
|
|
||||||
|
static vec3_t vert_buf[MAX_VERTS_PER_DRAW];
|
||||||
|
|
||||||
static void page_flip_handler(int, unsigned, unsigned, unsigned, void *)
|
static void page_flip_handler(int, unsigned, unsigned, unsigned, void *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void set_pixel(uint32_t x, uint32_t y)
|
||||||
set_pixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b)
|
|
||||||
{
|
{
|
||||||
/* x %= width; */
|
x %= width;
|
||||||
/* y %= height; */
|
y %= height;
|
||||||
const uint32_t offset = y * (fbs[back].pitch / 4) + x;
|
const uint32_t offset = y * (fbs[back].pitch / 4) + x;
|
||||||
assert(offset < fbs[back].size);
|
fbs[back].buf[offset] = 0xff'ff'ff;
|
||||||
fbs[back].buf[offset] = (r << 16) | (g << 8) | b;
|
}
|
||||||
|
|
||||||
|
static void draw_line(vec3_t v1, vec3_t v2)
|
||||||
|
{
|
||||||
|
const float delta_x = v2.x - v1.x;
|
||||||
|
const float delta_y = v2.y - v1.y;
|
||||||
|
const float step = fmaxf(fabsf(delta_x), fabsf(delta_y));
|
||||||
|
if (step != 0.0) {
|
||||||
|
const float step_x = delta_x / step;
|
||||||
|
const float step_y = delta_y / step;
|
||||||
|
for (unsigned i = 0; i <= step; ++i)
|
||||||
|
set_pixel(roundf(v1.x + i * step_x), roundf(v1.y + i * step_y));
|
||||||
|
} else {
|
||||||
|
set_pixel(roundf(v1.x), roundf(v1.y));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_params_t renderer_init()
|
renderer_params_t renderer_init()
|
||||||
@@ -59,9 +80,17 @@ renderer_params_t renderer_init()
|
|||||||
width = mode.hdisplay;
|
width = mode.hdisplay;
|
||||||
height = mode.vdisplay;
|
height = mode.vdisplay;
|
||||||
|
|
||||||
|
const float aspect = (float)width / (float)height;
|
||||||
|
const float scale = (float)height / 2.0f;
|
||||||
|
view = (mat3_t) {
|
||||||
|
{ scale, 0, 0 },
|
||||||
|
{ 0, -scale, 0 },
|
||||||
|
{ aspect * scale, scale, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
return (renderer_params_t) {
|
return (renderer_params_t) {
|
||||||
.drm_fd = drm_fd,
|
.drm_fd = drm_fd,
|
||||||
.aspect = (float)mode.hdisplay / (float)mode.vdisplay,
|
.aspect = aspect,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,10 +132,12 @@ void renderer_swap()
|
|||||||
back = (back + 1) & 1;
|
back = (back + 1) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_draw()
|
void renderer_draw(const vec2_t *vs, unsigned count)
|
||||||
{
|
{
|
||||||
for (unsigned y = 0; y < height; ++y) {
|
assert(count < MAX_VERTS_PER_DRAW);
|
||||||
for (unsigned x = 0; x < width; ++x)
|
for (unsigned i = 0; i < count; ++i)
|
||||||
set_pixel(x, y, (x * 255) / width, (y * 255) / height, 128);
|
vert_buf[i] = mat3_mul_vec3(view, vec2_extend(vs[i]));
|
||||||
}
|
for (unsigned i = 1; i < count; ++i)
|
||||||
|
draw_line(vert_buf[i - 1], vert_buf[i]);
|
||||||
|
draw_line(vert_buf[count - 1], vert_buf[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef RENDERER_H
|
#ifndef RENDERER_H
|
||||||
#define RENDERER_H
|
#define RENDERER_H
|
||||||
|
|
||||||
|
#include "maths.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -15,5 +17,6 @@ void renderer_handle();
|
|||||||
void renderer_clear();
|
void renderer_clear();
|
||||||
void renderer_swap();
|
void renderer_swap();
|
||||||
|
|
||||||
void renderer_draw();
|
void renderer_draw(const vec2_t *vs, unsigned count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user