summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmin Mesbah <mesbahamin@gmail.com>2017-12-10 23:04:30 -0800
committerAmin Mesbah <mesbahamin@gmail.com>2017-12-10 23:04:30 -0800
commit74281c2d2a86be4aec63e6dd16dd722bcd4ef3dc (patch)
tree3ecc44f53a4a1b074039de9a1e139030781590d9
parent7ea4f54b70e07ebc229e443cc818e8d2d10d8eac (diff)
downloadohsp-74281c2d2a86be4aec63e6dd16dd722bcd4ef3dc.zip
ohsp-74281c2d2a86be4aec63e6dd16dd722bcd4ef3dc.tar.gz
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...
-rwxr-xr-xMakefile2
-rw-r--r--src/game.c178
2 files changed, 165 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index 4f42b36..ce7f3eb 100755
--- 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
index 015f6a3..820939f 100644
--- 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!!!");
+ }
}
}