commit f0068617e7ee03ceaabde90e32e32aedd255101d
parent adee3025ffab5387f7b50d118998a26e56a747ff
Author: amin <dev@aminmesbah.com>
Date: Mon, 11 Dec 2017 07:04:30 +0000
Render lines in and between any octant
I did this in the most silly and straightforward way possible. It's
begging for some compression.
I had to disable the `-Wfloat-equal` compiler argument because it didn't
like me comparing floats to 0.0f, which is understandable. However this
rendering code will be replaced anyway once I start using Opengl, so
being careful with floats doesn't matter too much in this case.
However, I really do need to read about floats and how to do safe
comparisons...
FossilOrigin-Name: b9c894e58422423a61a41dcf05ccba1a3cd243ec499cf354a0ecf483904cba4a
Diffstat:
M | Makefile | | | 2 | +- |
M | src/game.c | | | 178 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
2 files changed, 165 insertions(+), 15 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
CC = gcc
-CFLAGS = -std=c99 -Wall -Wextra -Wfloat-equal -Wshadow -Wswitch-enum -Wno-unused-parameter
+CFLAGS = -std=c99 -Wall -Wextra -Wshadow -Wswitch-enum -Wno-unused-parameter
LDFLAGS = $(SDL_LDFLAGS) -ldl -lm
SDL_CFLAGS := $(shell sdl2-config --cflags)
diff --git a/src/game.c b/src/game.c
@@ -2,6 +2,7 @@
// TODO: remove this
#include <math.h>
+#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
@@ -133,36 +134,185 @@ void game_render_line(struct OffscreenBuffer *buffer, float x0, float y0, float
float delta_x = x1 - x0;
float delta_y = y1 - y0;
- if (0 == (int)delta_x)
+ if (0.0f == delta_x) // vertical
{
- for (int y = y0; y <= y1; ++y)
+ for (int y = fminf(y0, y1); y <= fmaxf(y0, y1); ++y)
{
game_set_pixel(buffer, x0, y, color);
}
}
- else if (0 == (int)delta_y)
+ else if (0.0f == delta_y) // horizontal
{
- for (int x = x0; x <= x1; ++x)
+ for (int x = fminf(x0, x1); x <= fmaxf(x0, x1); ++x)
{
game_set_pixel(buffer, x, y0, color);
}
}
else
{
- // Bresenham's line algorithm
- float delta_err = fabsf(delta_y / delta_x);
- float error = 0.0;
- int y = y0;
- for (int x = x0; x <= x1; ++x)
+ bool quadrant_01 = (delta_x > 0.0f && delta_y <= 0.0f);
+ bool quadrant_02 = (delta_x <= 0.0f && delta_y < 0.0f);
+ bool quadrant_03 = (delta_x < 0.0f && delta_y >= 0.0f);
+ bool quadrant_04 = (delta_x >= 0.0f && delta_y > 0.0f);
+ bool bigger_delta_x = fabsf(delta_x) >= fabsf(delta_y);
+ bool bigger_delta_y = !bigger_delta_x;
+
+ if(bigger_delta_x && quadrant_01)
+ {
+ // octant 1
+ // Bresenham's line algorithm
+ assert(0.0f != delta_x);
+ float delta_err = fabsf(delta_y / delta_x);
+ float error = 0.0f;
+ int y = y0;
+ for (int x = x0; x <= x1; ++x)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ y -= 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else if (bigger_delta_x && quadrant_02)
+ {
+ // octant 4
+ // Bresenham's line algorithm
+ assert(0.0f != delta_x);
+ float delta_err = fabsf(delta_y / delta_x);
+ float error = 0.0f;
+ int y = y0;
+ for (int x = x0; x >= x1; --x)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ y -= 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else if (bigger_delta_x && quadrant_03)
+ {
+ // octant 5
+ // Bresenham's line algorithm
+ assert(0.0f != delta_x);
+ float delta_err = fabsf(delta_y / delta_x);
+ float error = 0.0f;
+ int y = y0;
+ for (int x = x0; x >= x1; --x)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ y += 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else if (bigger_delta_x && quadrant_04)
{
- game_set_pixel(buffer, x, y, color);
- error += delta_err;
- if (error >= 0.5f)
+ // octant 8
+ // Bresenham's line algorithm
+ assert(0.0f != delta_x);
+ float delta_err = fabsf(delta_y / delta_x);
+ float error = 0.0f;
+ int y = y0;
+ for (int x = x0; x <= x1; ++x)
{
- y += 1;
- error -= 1.0f;
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ y += 1;
+ error -= 1.0f;
+ }
}
}
+ else if (bigger_delta_y && quadrant_01)
+ {
+ // octant 2
+ // Bresenham's line algorithm
+ assert(0.0f != delta_y);
+ float delta_err = fabsf(delta_x / delta_y);
+ float error = 0.0f;
+ int x = x0;
+ for (int y = y0; y >= y1; --y)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ x += 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else if (bigger_delta_y && quadrant_02)
+ {
+ // octant 3
+ // Bresenham's line algorithm
+ assert(0.0f != delta_y);
+ float delta_err = fabsf(delta_x / delta_y);
+ float error = 0.0f;
+ int x = x0;
+ for (int y = y0; y >= y1; --y)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ x -= 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else if (bigger_delta_y && quadrant_03)
+ {
+ // octant 6
+ // Bresenham's line algorithm
+ assert(0.0f != delta_y);
+ float delta_err = fabsf(delta_x / delta_y);
+ float error = 0.0f;
+ int x = x0;
+ for (int y = y0; y <= y1; ++y)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ x -= 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else if (bigger_delta_y && quadrant_04)
+ {
+ // octant 7
+ // Bresenham's line algorithm
+ assert(0.0f != delta_y);
+ float delta_err = fabsf(delta_x / delta_y);
+ float error = 0.0f;
+ int x = x0;
+ for (int y = y0; y <= y1; ++y)
+ {
+ game_set_pixel(buffer, x, y, color);
+ error += delta_err;
+ if (error >= 0.5f)
+ {
+ x += 1;
+ error -= 1.0f;
+ }
+ }
+ }
+ else
+ {
+ printf("ERROR: Your vector is as some angle you didn't catch!!!");
+ }
}
}