Skip to content

Instantly share code, notes, and snippets.

@shakesoda
Created October 24, 2016 00:24
Show Gist options
  • Save shakesoda/a6041e2a28fc0095e0b39995773b273e to your computer and use it in GitHub Desktop.
Save shakesoda/a6041e2a28fc0095e0b39995773b273e to your computer and use it in GitHub Desktop.
#include "geometry.hpp"
//#include "math.hpp"
namespace math {
inline uint32_t float4_to_rgba8(const float *in_color) {
uint32_t color = 0;
color |= uint32_t(uint8_t(in_color[0] * 255) << 0);
color |= uint32_t(uint8_t(in_color[1] * 255) << 8);
color |= uint32_t(uint8_t(in_color[2] * 255) << 16);
color |= uint32_t(uint8_t(in_color[3] * 255) << 24);
return color;
}
}
#include <bx/fpumath.h>
#include <bgfx/bgfx.h>
#include <vector>
#include <cstdint>
using namespace myon;
namespace {
const float red[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
const float green[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
const float blue[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
// fallback color
const uint32_t white = 0xffffffff;
const int cube_indices[] = {
// sides
0, 4,
1, 5,
2, 6,
3, 7,
// top
0, 1,
0, 3,
2, 3,
2, 1,
// bottom
4, 5,
4, 7,
6, 7,
6, 5
};
const float mtx_identity[] = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
struct vertex_t {
float position[3];
uint32_t color;
};
std::vector<vertex_t> buffer;
}
void graphics::draw_line(const float *start, const float *end, const float *color, const float *mtx) {
const float *_mtx = mtx ? mtx : mtx_identity;
vertex_t v1, v2;
bx::vec3MulMtx(v1.position, start, _mtx);
bx::vec3MulMtx(v2.position, end, _mtx);
v1.color = v2.color = color ? math::float4_to_rgba8(color) : white;
buffer.push_back(v1);
buffer.push_back(v2);
}
void graphics::draw_grid(const float *position, int num_lines, float spacing, const float *color, const float *mtx) {
float v1[3], v2[3];
bx::vec3Move(v1, position);
bx::vec3Move(v2, position);
// X
float line_length = spacing * (num_lines/2);
v1[1] = position[1] - line_length;
v2[1] = position[1] + line_length;
for (int i = -num_lines/2; i <= num_lines/2; i++) {
v1[0] = position[0] + spacing * i;
v2[0] = v1[0];
draw_line(v1, v2, color, mtx);
}
// Y
v1[0] = position[0] - line_length;
v2[0] = position[0] + line_length;
for (int i = -num_lines/2; i <= num_lines/2; i++) {
v1[1] = position[1] + spacing * i;
v2[1] = v1[1];
draw_line(v1, v2, color, mtx);
}
}
void graphics::draw_cube(const float *min, const float *max, const float *color, const float *mtx) {
float vertices[] = {
min[0], min[1], max[2],
max[0], min[1], max[2],
max[0], max[1], max[2],
min[0], max[1], max[2],
min[0], min[1], min[2],
max[0], min[1], min[2],
max[0], max[1], min[2],
min[0], max[1], min[2]
};
vertex_t v1, v2;
v1.color = v2.color = color ? math::float4_to_rgba8(color) : white;
for (unsigned i = 1; i < BX_COUNTOF(cube_indices); i+=2) {
const float *_mtx = mtx ? mtx : mtx_identity;
bx::vec3MulMtx(v1.position, &vertices[cube_indices[i-1]*3], _mtx);
bx::vec3MulMtx(v2.position, &vertices[cube_indices[i] *3], _mtx);
buffer.push_back(v1);
buffer.push_back(v2);
}
}
void graphics::draw_axis(const float *position, const float scale, const float *mtx) {
float tmp[3];
bx::vec3Move(tmp, position);
tmp[0] += 1.0f * scale,
draw_line(position, tmp, red, mtx);
bx::vec3Move(tmp, position);
tmp[1] += 1.0f * scale,
draw_line(position, tmp, green, mtx);
bx::vec3Move(tmp, position);
tmp[2] += 1.0f * scale,
draw_line(position, tmp, blue, mtx);
}
void graphics::dump_geometry(bool clear_only) {
if (clear_only) {
buffer.clear();
return;
}
static bool vertex_ready = false;
static bgfx::VertexDecl decl;
if (!vertex_ready) {
decl.begin();
decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
decl.end();
}
if (bgfx::checkAvailTransientVertexBuffer(buffer.size(), decl)) {
bgfx::TransientVertexBuffer vb;
bgfx::allocTransientVertexBuffer(&vb, buffer.size(), decl);
memcpy(vb.data, buffer.data(), buffer.size()*sizeof(vertex_t));
bgfx::setVertexBuffer(&vb);
}
buffer.clear();
}
namespace myon {
namespace graphics {
void draw_line(const float *start, const float *end, const float *color = nullptr, const float *mtx = nullptr);
void draw_grid(const float *position, int num_lines = 16, float spacing = 1.0f, const float *color = nullptr, const float *mtx = nullptr);
void draw_cube(const float *min, const float *max, const float *color = nullptr, const float *mtx = nullptr);
void draw_axis(const float *position, const float scale = 1.0f, const float *mtx = nullptr);
void dump_geometry(bool clear_only = false);
} // graphics
} // myon
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment