bresenham
This commit is contained in:
parent
50188813f8
commit
175bf4a397
3
Makefile
3
Makefile
@ -21,7 +21,8 @@ OBJS = \
|
|||||||
src/opengl.o \
|
src/opengl.o \
|
||||||
src/test.o \
|
src/test.o \
|
||||||
src/font.o \
|
src/font.o \
|
||||||
src/window.o
|
src/window.o \
|
||||||
|
src/bresenham.o
|
||||||
|
|
||||||
all: test.so
|
all: test.so
|
||||||
|
|
||||||
|
|||||||
13
include/bresenham.h
Normal file
13
include/bresenham.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void bresenham(int x1, int y1, int z1,
|
||||||
|
int x2, int y2, int z2,
|
||||||
|
void (*func)(int x, int y, int z));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -6,6 +6,7 @@ extern "C" {
|
|||||||
|
|
||||||
void load(const char * source_path);
|
void load(const char * source_path);
|
||||||
void draw();
|
void draw();
|
||||||
|
void kb_update(int up, int down, int left, int right);
|
||||||
void update(float lx, float ly, float rx, float ry, float tl, float tr,
|
void update(float lx, float ly, float rx, float ry, float tl, float tr,
|
||||||
int up, int down, int left, int right,
|
int up, int down, int left, int right,
|
||||||
int a, int b, int x, int y);
|
int a, int b, int x, int y);
|
||||||
|
|||||||
12
main.lua
12
main.lua
@ -8,6 +8,7 @@ function init()
|
|||||||
void load(const char * source_path);
|
void load(const char * source_path);
|
||||||
void update_window(int width, int height);
|
void update_window(int width, int height);
|
||||||
void draw();
|
void draw();
|
||||||
|
void kb_update(int kbup, int kbdown, int kbleft, int kbright);
|
||||||
void update(float lx, float ly, float rx, float ry, float tl, float tr,
|
void update(float lx, float ly, float rx, float ry, float tl, float tr,
|
||||||
int up, int down, int left, int right,
|
int up, int down, int left, int right,
|
||||||
int a, int b, int x, int y);
|
int a, int b, int x, int y);
|
||||||
@ -34,8 +35,17 @@ local update = function(dt)
|
|||||||
local b = joystick:isGamepadDown("b")
|
local b = joystick:isGamepadDown("b")
|
||||||
local x = joystick:isGamepadDown("x")
|
local x = joystick:isGamepadDown("x")
|
||||||
local y = joystick:isGamepadDown("y")
|
local y = joystick:isGamepadDown("y")
|
||||||
test.update(lx, ly, rx, ry, tl, tr, up, down, left, right, a, b, x, y)
|
|
||||||
|
test.update(lx, ly, rx, ry, tl, tr,
|
||||||
|
up, down, left, right,
|
||||||
|
a, b, x, y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local up = love.keyboard.isDown("up")
|
||||||
|
local down = love.keyboard.isDown("down")
|
||||||
|
local left = love.keyboard.isDown("left")
|
||||||
|
local right = love.keyboard.isDown("right")
|
||||||
|
test.kb_update(up, down, left, right);
|
||||||
end
|
end
|
||||||
|
|
||||||
local draw = function()
|
local draw = function()
|
||||||
|
|||||||
18
shader/line.frag
Normal file
18
shader/line.frag
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in VS_OUT {
|
||||||
|
vec3 Position; // world coordinates
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 Texture;
|
||||||
|
} fs_in;
|
||||||
|
|
||||||
|
layout (location = 0) out vec3 Position;
|
||||||
|
layout (location = 1) out vec3 Normal;
|
||||||
|
layout (location = 2) out vec3 Color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Position = fs_in.Position.xzy;
|
||||||
|
Normal = normalize(fs_in.Normal.xzy);
|
||||||
|
Color = vec3(0.5, 0, 1);
|
||||||
|
}
|
||||||
27
shader/line.vert
Normal file
27
shader/line.vert
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
// per-vertex:
|
||||||
|
in vec3 Position;
|
||||||
|
in vec3 Normal;
|
||||||
|
in vec2 Texture;
|
||||||
|
// per-instance:
|
||||||
|
in vec3 BlockPosition;
|
||||||
|
|
||||||
|
out VS_OUT {
|
||||||
|
vec3 Position;
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 Texture;
|
||||||
|
} vs_out;
|
||||||
|
|
||||||
|
uniform mat4 Transform;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 position = Position + BlockPosition; // world coordinates
|
||||||
|
|
||||||
|
vs_out.Position = position;
|
||||||
|
vs_out.Normal = Normal;
|
||||||
|
vs_out.Texture = Texture;
|
||||||
|
|
||||||
|
gl_Position = Transform * vec4(position.xzy, 1.0);
|
||||||
|
}
|
||||||
78
src/bresenham.c
Normal file
78
src/bresenham.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include "bresenham.h"
|
||||||
|
|
||||||
|
void bresenham(int x1, int y1, int z1,
|
||||||
|
int x2, int y2, int z2,
|
||||||
|
void (*func)(int x, int y, int z))
|
||||||
|
{
|
||||||
|
int pt_x = x1;
|
||||||
|
int pt_y = y1;
|
||||||
|
int pt_z = z1;
|
||||||
|
|
||||||
|
int dx = x2 - x1;
|
||||||
|
int dy = y2 - y1;
|
||||||
|
int dz = z2 - z1;
|
||||||
|
int x_inc = (dx < 0) ? -1 : 1;
|
||||||
|
int y_inc = (dy < 0) ? -1 : 1;
|
||||||
|
int z_inc = (dz < 0) ? -1 : 1;
|
||||||
|
int l = abs(dx);
|
||||||
|
int m = abs(dy);
|
||||||
|
int n = abs(dz);
|
||||||
|
int dx2 = l << 1;
|
||||||
|
int dy2 = m << 1;
|
||||||
|
int dz2 = n << 1;
|
||||||
|
|
||||||
|
if ((l >= m) && (l >= n)) {
|
||||||
|
int err_1 = dy2 - l;
|
||||||
|
int err_2 = dz2 - l;
|
||||||
|
for (int i = 0; i < l; i++) {
|
||||||
|
func(pt_x, pt_y, pt_z);
|
||||||
|
if (err_1 > 0) {
|
||||||
|
pt_y += y_inc;
|
||||||
|
err_1 -= dx2;
|
||||||
|
}
|
||||||
|
if (err_2 > 0) {
|
||||||
|
pt_z += z_inc;
|
||||||
|
err_2 -= dx2;
|
||||||
|
}
|
||||||
|
err_1 += dy2;
|
||||||
|
err_2 += dz2;
|
||||||
|
pt_x += x_inc;
|
||||||
|
}
|
||||||
|
} else if ((m >= l) && (m >= n)) {
|
||||||
|
int err_1 = dx2 - m;
|
||||||
|
int err_2 = dz2 - m;
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
func(pt_x, pt_y, pt_z);
|
||||||
|
if (err_1 > 0) {
|
||||||
|
pt_x += x_inc;
|
||||||
|
err_1 -= dy2;
|
||||||
|
}
|
||||||
|
if (err_2 > 0) {
|
||||||
|
pt_z += z_inc;
|
||||||
|
err_2 -= dy2;
|
||||||
|
}
|
||||||
|
err_1 += dx2;
|
||||||
|
err_2 += dz2;
|
||||||
|
pt_y += y_inc;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int err_1 = dy2 - n;
|
||||||
|
int err_2 = dx2 - n;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
func(pt_x, pt_y, pt_z);
|
||||||
|
if (err_1 > 0) {
|
||||||
|
pt_y += y_inc;
|
||||||
|
err_1 -= dz2;
|
||||||
|
}
|
||||||
|
if (err_2 > 0) {
|
||||||
|
pt_x += x_inc;
|
||||||
|
err_2 -= dz2;
|
||||||
|
}
|
||||||
|
err_1 += dy2;
|
||||||
|
err_2 += dx2;
|
||||||
|
pt_z += z_inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func(pt_x, pt_y, pt_z);
|
||||||
|
}
|
||||||
175
src/test.cpp
175
src/test.cpp
@ -8,6 +8,7 @@
|
|||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "bresenham.h"
|
||||||
|
|
||||||
#include "data.inc"
|
#include "data.inc"
|
||||||
|
|
||||||
@ -33,6 +34,22 @@ struct test_location {
|
|||||||
static unsigned int test_program;
|
static unsigned int test_program;
|
||||||
static test_location test_location;
|
static test_location test_location;
|
||||||
|
|
||||||
|
struct line_location {
|
||||||
|
struct {
|
||||||
|
unsigned int position;
|
||||||
|
unsigned int normal;
|
||||||
|
unsigned int texture;
|
||||||
|
unsigned int block_position;
|
||||||
|
} attrib;
|
||||||
|
struct {
|
||||||
|
unsigned int transform;
|
||||||
|
} uniform;
|
||||||
|
};
|
||||||
|
static unsigned int line_program;
|
||||||
|
static line_location line_location;
|
||||||
|
static unsigned int line_vertex_array_object;
|
||||||
|
static unsigned int line_instance_buffer;
|
||||||
|
|
||||||
struct quad_location {
|
struct quad_location {
|
||||||
struct {
|
struct {
|
||||||
unsigned int texture_sampler;
|
unsigned int texture_sampler;
|
||||||
@ -443,6 +460,105 @@ view_state view_state;
|
|||||||
|
|
||||||
font::font * terminus_fonts;
|
font::font * terminus_fonts;
|
||||||
|
|
||||||
|
struct short_point {
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
short z;
|
||||||
|
};
|
||||||
|
static_assert((sizeof (short_point)) == 6);
|
||||||
|
|
||||||
|
short_point line_points[128];
|
||||||
|
static int line_point_ix = 0;
|
||||||
|
|
||||||
|
void line_point(int x, int y, int z)
|
||||||
|
{
|
||||||
|
if (line_point_ix >= 128)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("%d %d %d\n", x, y, z);
|
||||||
|
line_points[line_point_ix].x = x;
|
||||||
|
line_points[line_point_ix].y = y;
|
||||||
|
line_points[line_point_ix].z = z;
|
||||||
|
line_point_ix += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_line_program()
|
||||||
|
{
|
||||||
|
unsigned int program = compile_from_files("shader/line.vert",
|
||||||
|
NULL,
|
||||||
|
"shader/line.frag");
|
||||||
|
|
||||||
|
line_location.attrib.position = glGetAttribLocation(program, "Position");
|
||||||
|
line_location.attrib.normal = glGetAttribLocation(program, "Normal");
|
||||||
|
line_location.attrib.texture = glGetAttribLocation(program, "Texture");
|
||||||
|
|
||||||
|
line_location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
|
||||||
|
|
||||||
|
printf("line program:\n");
|
||||||
|
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n",
|
||||||
|
line_location.attrib.position,
|
||||||
|
line_location.attrib.normal,
|
||||||
|
line_location.attrib.texture,
|
||||||
|
line_location.attrib.block_position);
|
||||||
|
|
||||||
|
line_location.uniform.transform = glGetUniformLocation(program, "Transform");
|
||||||
|
printf(" uniforms:\n transform %u\n\n",
|
||||||
|
line_location.uniform.transform);
|
||||||
|
|
||||||
|
line_program = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_line_vertex_attributes()
|
||||||
|
{
|
||||||
|
glGenVertexArrays(1, &line_vertex_array_object);
|
||||||
|
glBindVertexArray(line_vertex_array_object);
|
||||||
|
|
||||||
|
glVertexBindingDivisor(0, 0);
|
||||||
|
glVertexBindingDivisor(1, 1);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(line_location.attrib.position);
|
||||||
|
glVertexAttribFormat(line_location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0);
|
||||||
|
glVertexAttribBinding(line_location.attrib.position, 0);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(line_location.attrib.normal);
|
||||||
|
glVertexAttribFormat(line_location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6);
|
||||||
|
glVertexAttribBinding(line_location.attrib.normal, 0);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(line_location.attrib.texture);
|
||||||
|
glVertexAttribFormat(line_location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12);
|
||||||
|
glVertexAttribBinding(line_location.attrib.texture, 0);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(line_location.attrib.block_position);
|
||||||
|
glVertexAttribFormat(line_location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0);
|
||||||
|
glVertexAttribBinding(line_location.attrib.block_position, 1);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_line_instance_buffer()
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, line_instance_buffer);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, (sizeof (short_point)) * line_point_ix, line_points, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_line()
|
||||||
|
{
|
||||||
|
int x1 = -55;
|
||||||
|
int z1 = 48;
|
||||||
|
int y1 = 50;
|
||||||
|
|
||||||
|
int x2 = -60;
|
||||||
|
int z2 = 55;
|
||||||
|
int y2 = 53;
|
||||||
|
|
||||||
|
line_point_ix = 0;
|
||||||
|
bresenham(x1, y1, z1, x2, y2, z2, line_point);
|
||||||
|
|
||||||
|
load_line_instance_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
void load(const char * source_path)
|
void load(const char * source_path)
|
||||||
{
|
{
|
||||||
g_source_path_length = strlen(source_path);
|
g_source_path_length = strlen(source_path);
|
||||||
@ -487,6 +603,16 @@ void load(const char * source_path)
|
|||||||
|
|
||||||
load_lighting_program();
|
load_lighting_program();
|
||||||
load_light_uniform_buffer();
|
load_light_uniform_buffer();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// line
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
load_line_program();
|
||||||
|
load_line_vertex_attributes();
|
||||||
|
|
||||||
|
glGenBuffers(1, &line_instance_buffer);
|
||||||
|
load_line();
|
||||||
}
|
}
|
||||||
|
|
||||||
float _ry = 0.0;
|
float _ry = 0.0;
|
||||||
@ -500,6 +626,13 @@ light_parameters lighting = {
|
|||||||
.linear = 1.0
|
.linear = 1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void kb_update(int up, int down, int left, int right)
|
||||||
|
{
|
||||||
|
XMVECTOR normal = XMVector3NormalizeEst(XMVector3Cross(view_state.forward, view_state.up));
|
||||||
|
view_state.eye += view_state.forward * (0.1f * up + -0.1f * down);
|
||||||
|
view_state.eye += normal * (-0.1f * left + 0.1f * right);
|
||||||
|
}
|
||||||
|
|
||||||
void update(float lx, float ly, float rx, float ry, float tl, float tr,
|
void update(float lx, float ly, float rx, float ry, float tl, float tr,
|
||||||
int up, int down, int left, int right,
|
int up, int down, int left, int right,
|
||||||
int a, int b, int x, int y)
|
int a, int b, int x, int y)
|
||||||
@ -594,11 +727,8 @@ void draw_hud()
|
|||||||
y += ter_best.desc->glyph_height;
|
y += ter_best.desc->glyph_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_minecraft()
|
XMMATRIX current_view_projection()
|
||||||
{
|
{
|
||||||
// possibly re-initialize geometry buffer if window width/height changes
|
|
||||||
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
|
||||||
|
|
||||||
XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction);
|
XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction);
|
||||||
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
|
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
|
||||||
|
|
||||||
@ -608,6 +738,13 @@ void draw_minecraft()
|
|||||||
float far_z = 0.1;
|
float far_z = 0.1;
|
||||||
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
|
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
|
||||||
XMMATRIX transform = view * projection;
|
XMMATRIX transform = view * projection;
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_minecraft()
|
||||||
|
{
|
||||||
|
// possibly re-initialize geometry buffer if window width/height changes
|
||||||
|
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
||||||
|
|
||||||
glUseProgram(test_program);
|
glUseProgram(test_program);
|
||||||
|
|
||||||
@ -618,6 +755,7 @@ void draw_minecraft()
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
|
||||||
|
XMMATRIX transform = current_view_projection();
|
||||||
glUniformMatrix4fv(test_location.uniform.transform, 1, false, (float *)&transform);
|
glUniformMatrix4fv(test_location.uniform.transform, 1, false, (float *)&transform);
|
||||||
glUniform1i(test_location.uniform.terrain_sampler, 0);
|
glUniform1i(test_location.uniform.terrain_sampler, 0);
|
||||||
|
|
||||||
@ -720,6 +858,34 @@ void draw_lighting()
|
|||||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
|
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_line()
|
||||||
|
{
|
||||||
|
glUseProgram(line_program);
|
||||||
|
|
||||||
|
glBlendFunc(GL_ONE, GL_ZERO);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_GREATER);
|
||||||
|
|
||||||
|
XMMATRIX transform = current_view_projection();
|
||||||
|
glUniformMatrix4fv(line_location.uniform.transform, 1, false, (float *)&transform);
|
||||||
|
|
||||||
|
//glEnable(GL_CULL_FACE);
|
||||||
|
//glCullFace(GL_FRONT);
|
||||||
|
//glFrontFace(GL_CCW);
|
||||||
|
|
||||||
|
glBindVertexArray(line_vertex_array_object);
|
||||||
|
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
||||||
|
int line_instance_vertex_size = (sizeof (short_point));
|
||||||
|
glBindVertexBuffer(1, line_instance_buffer, 0, line_instance_vertex_size);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||||
|
|
||||||
|
int configuration = 63;
|
||||||
|
int element_count = 6 * popcount(configuration);
|
||||||
|
const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
||||||
|
int instance_count = line_point_ix;
|
||||||
|
glDrawElementsInstanced(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count);
|
||||||
|
}
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
@ -729,6 +895,7 @@ void draw()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
draw_minecraft();
|
draw_minecraft();
|
||||||
|
draw_line();
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user