bresenham
This commit is contained in:
parent
50188813f8
commit
175bf4a397
3
Makefile
3
Makefile
@ -21,7 +21,8 @@ OBJS = \
|
||||
src/opengl.o \
|
||||
src/test.o \
|
||||
src/font.o \
|
||||
src/window.o
|
||||
src/window.o \
|
||||
src/bresenham.o
|
||||
|
||||
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 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,
|
||||
int up, int down, int left, int right,
|
||||
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 update_window(int width, int height);
|
||||
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,
|
||||
int up, int down, int left, int right,
|
||||
int a, int b, int x, int y);
|
||||
@ -34,8 +35,17 @@ local update = function(dt)
|
||||
local b = joystick:isGamepadDown("b")
|
||||
local x = joystick:isGamepadDown("x")
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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 "font.h"
|
||||
#include "window.h"
|
||||
#include "bresenham.h"
|
||||
|
||||
#include "data.inc"
|
||||
|
||||
@ -33,6 +34,22 @@ struct test_location {
|
||||
static unsigned int test_program;
|
||||
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 {
|
||||
unsigned int texture_sampler;
|
||||
@ -443,6 +460,105 @@ view_state view_state;
|
||||
|
||||
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)
|
||||
{
|
||||
g_source_path_length = strlen(source_path);
|
||||
@ -487,6 +603,16 @@ void load(const char * source_path)
|
||||
|
||||
load_lighting_program();
|
||||
load_light_uniform_buffer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// line
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
load_line_program();
|
||||
load_line_vertex_attributes();
|
||||
|
||||
glGenBuffers(1, &line_instance_buffer);
|
||||
load_line();
|
||||
}
|
||||
|
||||
float _ry = 0.0;
|
||||
@ -500,6 +626,13 @@ light_parameters lighting = {
|
||||
.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,
|
||||
int up, int down, int left, int right,
|
||||
int a, int b, int x, int y)
|
||||
@ -594,11 +727,8 @@ void draw_hud()
|
||||
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);
|
||||
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
|
||||
|
||||
@ -608,6 +738,13 @@ void draw_minecraft()
|
||||
float far_z = 0.1;
|
||||
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
|
||||
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);
|
||||
|
||||
@ -618,6 +755,7 @@ void draw_minecraft()
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
XMMATRIX transform = current_view_projection();
|
||||
glUniformMatrix4fv(test_location.uniform.transform, 1, false, (float *)&transform);
|
||||
glUniform1i(test_location.uniform.terrain_sampler, 0);
|
||||
|
||||
@ -720,6 +858,34 @@ void draw_lighting()
|
||||
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()
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@ -729,6 +895,7 @@ void draw()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
draw_minecraft();
|
||||
draw_line();
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user