better billboarding
This commit is contained in:
parent
90758175ca
commit
a6875adf13
@ -355,7 +355,7 @@
|
|||||||
"contacts": false,
|
"contacts": false,
|
||||||
"constraints": true,
|
"constraints": true,
|
||||||
"rays": false,
|
"rays": false,
|
||||||
"depthTest": true
|
"depthTest": false
|
||||||
},
|
},
|
||||||
"fixed step": true,
|
"fixed step": true,
|
||||||
"substeps": 4,
|
"substeps": 4,
|
||||||
|
|||||||
@ -9,17 +9,25 @@ layout (constant_id = 0) const uint PASSES = 1;
|
|||||||
layout (location = 0) in vec3 inPos;
|
layout (location = 0) in vec3 inPos;
|
||||||
layout (location = 1) in vec2 inUv;
|
layout (location = 1) in vec2 inUv;
|
||||||
layout (location = 2) in vec4 inColor;
|
layout (location = 2) in vec4 inColor;
|
||||||
|
layout (location = 3) in vec2 inOffset;
|
||||||
|
|
||||||
layout( push_constant ) uniform PushBlock {
|
layout( push_constant ) uniform PushBlock {
|
||||||
uint pass;
|
uint pass;
|
||||||
uint draw;
|
uint draw;
|
||||||
} PushConstant;
|
} PushConstant;
|
||||||
|
|
||||||
|
layout (binding = 0) uniform Camera {
|
||||||
|
Viewport viewport[PASSES];
|
||||||
|
} camera;
|
||||||
|
|
||||||
layout (location = 0) out vec2 outUv;
|
layout (location = 0) out vec2 outUv;
|
||||||
layout (location = 1) out vec4 outColor;
|
layout (location = 1) out vec4 outColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
outUv = inUv;
|
outUv = inUv;
|
||||||
outColor = inColor;
|
outColor = inColor;
|
||||||
gl_Position = vec4(inPos.xyz, 1.0);
|
|
||||||
}
|
vec4 clipPos = camera.viewport[PushConstant.pass].projection * camera.viewport[PushConstant.pass].view * vec4(inPos.xyz, 1.0);
|
||||||
|
//clipPos.xy += inOffset * (clipPos.w / max(clipPos.w, 1.0));
|
||||||
|
clipPos.xy += inOffset * min(clipPos.w, 1.0);
|
||||||
|
gl_Position = clipPos;}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
layout (constant_id = 0) const uint PASSES = 6;
|
layout (constant_id = 0) const uint PASSES = 6;
|
||||||
layout (location = 0) in vec2 inPos;
|
layout (location = 0) in vec2 inPos;
|
||||||
layout (location = 1) in vec2 inUv;
|
layout (location = 1) in vec2 inUv;
|
||||||
|
layout (location = 3) in vec2 inOffset;
|
||||||
|
|
||||||
#include "./gui.h"
|
#include "./gui.h"
|
||||||
|
|
||||||
@ -33,10 +34,16 @@ layout (location = 1) out flat Gui outGui;
|
|||||||
void main() {
|
void main() {
|
||||||
outUv = inUv;
|
outUv = inUv;
|
||||||
outGui = ubo.gui;
|
outGui = ubo.gui;
|
||||||
|
|
||||||
#if GLYPH
|
#if GLYPH
|
||||||
outVertexID = gl_VertexIndex;
|
outVertexID = gl_VertexIndex;
|
||||||
outGlyph = uboGlyph.glyph;
|
outGlyph = uboGlyph.glyph;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy + inOffset.xy, ubo.gui.depth, 1.0);
|
||||||
|
/*
|
||||||
|
vec4 clipPos = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
||||||
|
clipPos.xy += inOffset * clipPos.w;
|
||||||
|
gl_Position = clipPos;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
@ -9,11 +9,12 @@
|
|||||||
namespace pod {
|
namespace pod {
|
||||||
struct GlyphBox {
|
struct GlyphBox {
|
||||||
struct {
|
struct {
|
||||||
float x, y, w, h, z;
|
float x = 0, y = 0, w = 0, h = 0, z = 0;
|
||||||
} box;
|
} box = {};
|
||||||
|
|
||||||
pod::Vector4f color;
|
pod::Vector4f color = { 1, 1, 1, 1 };
|
||||||
uint64_t code;
|
pod::Vector3f anchor = { 0, 0, 0 };
|
||||||
|
uint64_t code = 0;
|
||||||
};
|
};
|
||||||
struct TextToken {
|
struct TextToken {
|
||||||
uf::stl::string text;
|
uf::stl::string text;
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
#define EXT_COLOR_FLOATS 1
|
#define EXT_COLOR_FLOATS 1
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct Mesh {
|
struct GuiVertex {
|
||||||
pod::Vector3f position;
|
pod::Vector3f position;
|
||||||
pod::Vector2f uv;
|
pod::Vector2f uv;
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ namespace {
|
|||||||
#else
|
#else
|
||||||
pod::Vector4b color;
|
pod::Vector4b color;
|
||||||
#endif
|
#endif
|
||||||
|
pod::Vector2f offset;
|
||||||
|
|
||||||
static uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
static uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||||
};
|
};
|
||||||
@ -58,14 +59,15 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
UF_VERTEX_DESCRIPTOR(Mesh,
|
UF_VERTEX_DESCRIPTOR(GuiVertex,
|
||||||
UF_VERTEX_DESCRIPTION(Mesh, R32G32B32_SFLOAT, position)
|
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32B32_SFLOAT, position)
|
||||||
UF_VERTEX_DESCRIPTION(Mesh, R32G32_SFLOAT, uv)
|
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32_SFLOAT, uv)
|
||||||
#if EXT_COLOR_FLOATS
|
#if EXT_COLOR_FLOATS
|
||||||
UF_VERTEX_DESCRIPTION(Mesh, R32G32B32A32_SFLOAT, color)
|
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32B32A32_SFLOAT, color)
|
||||||
#else
|
#else
|
||||||
UF_VERTEX_DESCRIPTION(Mesh, R8G8B8A8_UNORM, color)
|
UF_VERTEX_DESCRIPTION(GuiVertex, R8G8B8A8_UNORM, color)
|
||||||
#endif
|
#endif
|
||||||
|
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32_SFLOAT, offset)
|
||||||
)
|
)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -87,15 +89,15 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uf::Mesh& generateMesh( uf::Mesh& mesh, const pod::Vector4f& color, const pod::Vector2f& center ) {
|
uf::Mesh& generateMesh( uf::Mesh& mesh, const pod::Vector4f& color, const pod::Vector2f& center ) {
|
||||||
mesh.bind<::Mesh, uint16_t>();
|
mesh.bind<::GuiVertex, uint16_t>();
|
||||||
mesh.insertVertices<::Mesh>({
|
mesh.insertVertices<::GuiVertex>({
|
||||||
{ pod::Vector3f{-1.0f, 1.0f, 0.0f} - center, pod::Vector2f{0.0f, 0.0f}, color },
|
{ pod::Vector3f{-1.0f, 1.0f, 0.0f}, pod::Vector2f{0.0f, 0.0f}, color, center },
|
||||||
{ pod::Vector3f{-1.0f, -1.0f, 0.0f} - center, pod::Vector2f{0.0f, 1.0f}, color },
|
{ pod::Vector3f{-1.0f, -1.0f, 0.0f}, pod::Vector2f{0.0f, 1.0f}, color, center },
|
||||||
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f} - center, pod::Vector2f{1.0f, 1.0f}, color },
|
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f}, pod::Vector2f{1.0f, 1.0f}, color, center },
|
||||||
|
|
||||||
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f} - center, pod::Vector2f{1.0f, 1.0f}, color },
|
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f}, pod::Vector2f{1.0f, 1.0f}, color, center },
|
||||||
{ pod::Vector3f{ 1.0f, 1.0f, 0.0f} - center, pod::Vector2f{1.0f, 0.0f}, color },
|
{ pod::Vector3f{ 1.0f, 1.0f, 0.0f}, pod::Vector2f{1.0f, 0.0f}, color, center },
|
||||||
{ pod::Vector3f{-1.0f, 1.0f, 0.0f} - center, pod::Vector2f{0.0f, 0.0f}, color },
|
{ pod::Vector3f{-1.0f, 1.0f, 0.0f}, pod::Vector2f{0.0f, 0.0f}, color, center },
|
||||||
});
|
});
|
||||||
mesh.insertIndices<uint16_t>({
|
mesh.insertIndices<uint16_t>({
|
||||||
0, 1, 2, 3, 4, 5
|
0, 1, 2, 3, 4, 5
|
||||||
@ -551,14 +553,20 @@ void ext::GuiBehavior::tick( uf::Object& self ) {
|
|||||||
pod::Vector2f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
pod::Vector2f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||||
pod::Vector2f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
pod::Vector2f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||||
|
|
||||||
uf::Mesh::Attribute vertexAttribute;
|
uf::Mesh::Attribute positionAttribute;
|
||||||
for ( auto& attribute : mesh.vertex.attributes ) if ( attribute.descriptor.name == "position" ) { vertexAttribute = attribute; break; }
|
uf::Mesh::Attribute offsetAttribute;
|
||||||
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
|
for ( auto& attribute : mesh.vertex.attributes ) {
|
||||||
|
if ( attribute.descriptor.name == "position" ) positionAttribute = attribute;
|
||||||
|
if ( attribute.descriptor.name == "offset" ) offsetAttribute = attribute;
|
||||||
|
}
|
||||||
|
UF_ASSERT( positionAttribute.descriptor.name == "position" );
|
||||||
|
|
||||||
for ( auto i = 0; i < mesh.vertex.count; ++i ) {
|
for ( auto i = 0; i < mesh.vertex.count; ++i ) {
|
||||||
float* p = (float*) (static_cast<uint8_t*>(vertexAttribute.pointer) + i * vertexAttribute.stride );
|
float* p = (float*) (static_cast<uint8_t*>(positionAttribute.pointer) + i * positionAttribute.stride );
|
||||||
|
float* o = (float*) (static_cast<uint8_t*>(offsetAttribute.pointer) + i * offsetAttribute.stride );
|
||||||
// pod::Vector4f position = { p[0], p[1], p[2], 1 };
|
// pod::Vector4f position = { p[0], p[1], p[2], 1 };
|
||||||
pod::Vector4f position = { p[0], p[1], 0, 1 };
|
pod::Vector4f position = { p[0] + o[0], p[1] + o[1], 0, 1 };
|
||||||
|
|
||||||
pod::Vector4f translated = uf::matrix::multiply<float>( model, position );
|
pod::Vector4f translated = uf::matrix::multiply<float>( model, position );
|
||||||
min.x = std::min( min.x, translated.x );
|
min.x = std::min( min.x, translated.x );
|
||||||
max.x = std::max( max.x, translated.x );
|
max.x = std::max( max.x, translated.x );
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace impl {
|
|||||||
pod::GlyphSettings textSettings = {
|
pod::GlyphSettings textSettings = {
|
||||||
.alignment = "center",
|
.alignment = "center",
|
||||||
.font = "FragmentMono.ttf",
|
.font = "FragmentMono.ttf",
|
||||||
.size = 24,
|
.size = 48,
|
||||||
.sdf = false,
|
.sdf = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ void uf::debug::drawTexts( float dt ) {
|
|||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
auto& controller = scene.getController();
|
auto& controller = scene.getController();
|
||||||
auto& camera = scene.getCamera( controller );
|
auto& camera = scene.getCamera( controller );
|
||||||
auto& transform = camera.getTransform();
|
auto transform = uf::transform::flatten( camera.getTransform() );
|
||||||
|
|
||||||
uf::stl::vector<pod::GlyphBox> textLayout;
|
uf::stl::vector<pod::GlyphBox> textLayout;
|
||||||
// pre-init with ASCII characters
|
// pre-init with ASCII characters
|
||||||
@ -309,27 +309,8 @@ void uf::debug::drawTexts( float dt ) {
|
|||||||
for ( auto& text : texts ) {
|
for ( auto& text : texts ) {
|
||||||
auto tokens = uf::glyph::parseTextTokens( text.string, text.color );
|
auto tokens = uf::glyph::parseTextTokens( text.string, text.color );
|
||||||
auto layout = uf::glyph::calculateLayout( tokens, impl::textSettings );
|
auto layout = uf::glyph::calculateLayout( tokens, impl::textSettings );
|
||||||
|
|
||||||
auto world = pod::Vector4f{ text.position.x, text.position.y, text.position.z, 1.0f };
|
|
||||||
auto view = camera.getProjection() * camera.getView();
|
|
||||||
auto clip = uf::matrix::multiply( view, world );
|
|
||||||
|
|
||||||
if ( clip.w <= 0.0f ) continue;
|
|
||||||
|
|
||||||
auto ndc = pod::Vector3f{ clip.x, clip.y, clip.z } / clip.w;
|
|
||||||
float scale = 2.0f / clip.w;
|
|
||||||
|
|
||||||
if ( ndc.z < 0.0f || ndc.z > 1.0f ) continue;
|
|
||||||
|
|
||||||
for ( auto& g : layout ) {
|
for ( auto& g : layout ) {
|
||||||
g.box.x = g.box.x * scale + ndc.x;
|
g.anchor += text.position;
|
||||||
g.box.y = g.box.y * scale + ndc.y;
|
|
||||||
g.box.z = ndc.z;
|
|
||||||
g.box.w *= scale;
|
|
||||||
g.box.h *= scale;
|
|
||||||
|
|
||||||
if ( (g.box.x + g.box.w < -1.0f) || (g.box.x > 1.0f) || (g.box.y + g.box.h < -1.0f) || (g.box.y > 1.0f) ) continue;
|
|
||||||
|
|
||||||
textLayout.emplace_back( g );
|
textLayout.emplace_back( g );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ void impl::drawBody( const pod::PhysicsBody& body ) {
|
|||||||
auto& projection = camera.getProjection();
|
auto& projection = camera.getProjection();
|
||||||
auto fov = std::atan(1.0f / fabs(projection(1,1)));
|
auto fov = std::atan(1.0f / fabs(projection(1,1)));
|
||||||
auto angleThreshold = std::cos(fov * 1.5f);
|
auto angleThreshold = std::cos(fov * 1.5f);
|
||||||
auto viewThresholdSq = std::pow(5, 2);
|
auto viewThresholdSq = std::pow(10, 2);
|
||||||
|
|
||||||
// continuously pick the closest point on the AABB
|
// continuously pick the closest point on the AABB
|
||||||
auto position = impl::closestPointOnAABB( cameraTransform.position, bounds );
|
auto position = impl::closestPointOnAABB( cameraTransform.position, bounds );
|
||||||
|
|||||||
@ -28,6 +28,8 @@ namespace {
|
|||||||
pod::Vector4b color;
|
pod::Vector4b color;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pod::Vector3f offset;
|
||||||
|
|
||||||
static uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
static uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -40,6 +42,7 @@ UF_VERTEX_DESCRIPTOR(GlyphVertex,
|
|||||||
#else
|
#else
|
||||||
UF_VERTEX_DESCRIPTION(GlyphVertex, R8G8B8A8_UNORM, color)
|
UF_VERTEX_DESCRIPTION(GlyphVertex, R8G8B8A8_UNORM, color)
|
||||||
#endif
|
#endif
|
||||||
|
UF_VERTEX_DESCRIPTION(GlyphVertex, R32G32_SFLOAT, offset)
|
||||||
)
|
)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -216,6 +219,7 @@ uf::stl::vector<pod::GlyphBox> uf::glyph::calculateLayout( const uf::stl::vector
|
|||||||
.z = 0,
|
.z = 0,
|
||||||
},
|
},
|
||||||
.color = token.color,
|
.color = token.color,
|
||||||
|
.anchor = anchor,
|
||||||
.code = c,
|
.code = c,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -315,10 +319,15 @@ void uf::glyph::generateMesh( const uf::stl::vector<pod::GlyphBox>& layout, cons
|
|||||||
indices.insert( indices.end(), { idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 });
|
indices.insert( indices.end(), { idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 });
|
||||||
|
|
||||||
// insert vertices
|
// insert vertices
|
||||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x, g.box.y + g.box.h, g.box.z }, atlas.mapUv(pod::Vector2f{ 0.0f, 0.0f }, hash), color});
|
auto p0 = pod::Vector2f{ g.box.x, g.box.y + g.box.h };
|
||||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x, g.box.y, g.box.z }, atlas.mapUv(pod::Vector2f{ 0.0f, 1.0f }, hash), color});
|
auto p1 = pod::Vector2f{ g.box.x, g.box.y };
|
||||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x + g.box.w, g.box.y, g.box.z }, atlas.mapUv(pod::Vector2f{ 1.0f, 1.0f }, hash), color});
|
auto p2 = pod::Vector2f{ g.box.x + g.box.w, g.box.y };
|
||||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x + g.box.w, g.box.y + g.box.h, g.box.z }, atlas.mapUv(pod::Vector2f{ 1.0f, 0.0f }, hash), color});
|
auto p3 = pod::Vector2f{ g.box.x + g.box.w, g.box.y + g.box.h };
|
||||||
|
|
||||||
|
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 0.0f, 0.0f }, hash), color, p0});
|
||||||
|
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 0.0f, 1.0f }, hash), color, p1});
|
||||||
|
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 1.0f, 1.0f }, hash), color, p2});
|
||||||
|
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 1.0f, 0.0f }, hash), color, p3});
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.insertVertices(vertices);
|
mesh.insertVertices(vertices);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user