ab aeterno

This commit is contained in:
Mikulas Florek 2018-10-20 01:55:30 +02:00
parent e13ae421a7
commit 8abb30da00
4 changed files with 129 additions and 31 deletions

View file

@ -107,15 +107,31 @@ static bool saveAsDDS(const char* path, const u8* image_data, int image_width, i
struct FontPlugin final : public AssetBrowser::IPlugin
struct FontPlugin final : public AssetBrowser::IPlugin, AssetCompiler::IPlugin
{
FontPlugin(StudioApp& app) { app.getAssetCompiler().registerExtension("ttf", FontResource::TYPE); }
FontPlugin(StudioApp& app) : app(app)
{
app.getAssetCompiler().registerExtension("ttf", FontResource::TYPE);
}
bool compile(const Path& src) override
{
const char* dst_dir = app.getAssetCompiler().getCompiledDir();
const u32 hash = crc32(src.c_str());
const StaticString<MAX_PATH_LENGTH> dst(dst_dir, hash, ".res");
copyFile(src.c_str(), dst);
return true;
}
void onGUI(Resource* resource) override {}
void onResourceUnloaded(Resource* resource) override {}
const char* getName() const override { return "Font"; }
ResourceType getResourceType() const override { return FontResource::TYPE; }
StudioApp& app;
};
@ -2870,6 +2886,9 @@ struct StudioAppPlugin : StudioApp::IPlugin
asset_compiler.addPlugin(*m_model_plugin, model_exts);
m_font_plugin = LUMIX_NEW(allocator, FontPlugin)(m_app);
const char* fonts_exts[] = {"ttf", nullptr};
asset_compiler.addPlugin(*m_font_plugin, fonts_exts);
AssetBrowser& asset_browser = m_app.getAssetBrowser();
asset_browser.addPlugin(*m_model_plugin);
asset_browser.addPlugin(*m_particle_emitter_plugin);
@ -2913,6 +2932,7 @@ struct StudioAppPlugin : StudioApp::IPlugin
asset_browser.removePlugin(*m_shader_plugin);
AssetCompiler& asset_compiler = m_app.getAssetCompiler();
asset_compiler.removePlugin(*m_font_plugin);
asset_compiler.removePlugin(*m_shader_plugin);
asset_compiler.removePlugin(*m_texture_plugin);
asset_compiler.removePlugin(*m_model_plugin);

View file

@ -204,6 +204,7 @@ struct PipelineImpl final : Pipeline
ResourceManagerHub& rm = renderer.getEngine().getResourceManager();
m_draw2d_shader = rm.load<Shader>(Path("pipelines/draw2d.shd"));
m_debug_shape_shader = rm.load<Shader>(Path("pipelines/debug_shape.shd"));
m_text_mesh_shader = rm.load<Shader>(Path("pipelines/text_mesh.shd"));
TextureManager& texture_manager = renderer.getTextureManager();
m_default_cubemap = rm.load<Texture>(Path("textures/common/default_probe.dds"));
@ -270,6 +271,7 @@ struct PipelineImpl final : Pipeline
m_draw2d_shader->getResourceManager().unload(*m_draw2d_shader);
m_debug_shape_shader->getResourceManager().unload(*m_debug_shape_shader);
m_text_mesh_shader->getResourceManager().unload(*m_text_mesh_shader);
m_default_cubemap->getResourceManager().unload(*m_default_cubemap);
for(ShaderRef& shader : m_shaders) {
@ -1508,6 +1510,88 @@ struct PipelineImpl final : Pipeline
}
void renderTextMeshes()
{
if (!m_text_mesh_shader->isReady()) return;
if (m_text_mesh_shader->m_texture_slot_count < 1) return;
struct RenderJob : Renderer::RenderJob
{
RenderJob(IAllocator& allocator) : m_vertices(allocator) {}
void setup() override
{
const Quat& rot = m_pipeline->m_viewport.rot;
const DVec3& pos = m_pipeline->m_viewport.pos;
m_pipeline->m_scene->getTextMeshesVertices(m_vertices, pos, rot);
Renderer& renderer = m_pipeline->m_renderer;
Texture* atlas = renderer.getFontManager().getAtlasTexture();
m_atlas = atlas ? atlas->handle : ffr::INVALID_TEXTURE;
}
void execute() override
{
const Shader::Program& p = Shader::getProgram(m_shader, 0);
if(!p.handle.isValid()) return;
Renderer& renderer = m_pipeline->m_renderer;
const Renderer::TransientSlice transient = renderer.allocTransient(m_vertices.byte_size());
ffr::update(transient.buffer, m_vertices.begin(), transient.offset, transient.size);
ffr::setUniform1i(m_texture_uniform, 0);
ffr::useProgram(p.handle);
ffr::VertexDecl decl;
ffr::blending(1);
ffr::setState((u64)ffr::StateFlags::DEPTH_WRITE | (u64)ffr::StateFlags::DEPTH_TEST);
ffr::bindTexture(0, m_atlas);
decl.addAttribute(3, ffr::AttributeType::FLOAT, false, false);
decl.addAttribute(4, ffr::AttributeType::U8, true, false);
decl.addAttribute(2, ffr::AttributeType::FLOAT, false, false);
ffr::setVertexBuffer(&decl, transient.buffer, transient.offset, nullptr);
ffr::drawArrays(0, m_vertices.size(), ffr::PrimitiveType::TRIANGLES);
}
ffr::TextureHandle m_atlas;
ShaderRenderData* m_shader;
PipelineImpl* m_pipeline;
ffr::UniformHandle m_texture_uniform;
Array<TextMeshVertex> m_vertices;
};
IAllocator& allocator = m_renderer.getAllocator();
RenderJob* job = LUMIX_NEW(allocator, RenderJob)(allocator);
job->m_pipeline = this;
job->m_shader = m_text_mesh_shader->m_render_data;
job->m_texture_uniform = m_text_mesh_shader->m_texture_slots[0].uniform_handle;
m_renderer.push(job);
/* if (!m_text_mesh_shader->isReady()) return;
IAllocator& allocator = m_renderer.getEngine().getLIFOAllocator();
Array<TextMeshVertex> vertices(allocator);
vertices.reserve(1024);
m_scene->getTextMeshesVertices(vertices, m_applied_camera);
const bgfx::VertexDecl& decl = m_renderer.getBasicVertexDecl();
bgfx::TransientVertexBuffer vertex_buffer;
if (vertices.empty()) return;
if (bgfx::getAvailTransientVertexBuffer(vertices.size(), decl) < (u32)vertices.size()) return;
bgfx::allocTransientVertexBuffer(&vertex_buffer, vertices.size(), decl);
copyMemory(vertex_buffer.data, &vertices[0], vertices.size() * sizeof(vertices[0]));
Texture* atlas_texture = m_renderer.getFontManager().getAtlasTexture();
bgfx::UniformHandle texture_uniform = m_text_mesh_shader->m_texture_slots[0].uniform_handle;
setTexture(0, atlas_texture->handle, texture_uniform);
ShaderInstance& shader_instance = m_text_mesh_shader->getInstance(0);
u64 state = m_text_mesh_shader->m_render_states & ~BGFX_STATE_CULL_MASK;
render(vertex_buffer, vertices.size(), state, shader_instance);*/
}
void renderBucket(const char* define, CommandSet* cmd_set)
{
struct RenderJob : Renderer::RenderJob
@ -2662,6 +2746,7 @@ struct PipelineImpl final : Pipeline
REGISTER_FUNCTION(render2D);
REGISTER_FUNCTION(renderBucket);
REGISTER_FUNCTION(renderDebugShapes);
REGISTER_FUNCTION(renderTextMeshes);
REGISTER_FUNCTION(setOutput);
REGISTER_FUNCTION(setStencil);
REGISTER_FUNCTION(viewport);
@ -2742,6 +2827,7 @@ struct PipelineImpl final : Pipeline
Viewport m_viewport;
int m_output;
Shader* m_debug_shape_shader;
Shader* m_text_mesh_shader;
Texture* m_default_cubemap;
Array<CommandSet*> m_command_sets;
Array<CustomCommandHandler> m_custom_commands_handlers;

View file

@ -918,44 +918,37 @@ public:
}
void getTextMeshesVertices(Array<TextMeshVertex>& vertices, EntityRef camera) override
void getTextMeshesVertices(Array<TextMeshVertex>& vertices, const DVec3& cam_pos, const Quat& cam_rot) override
{
// TODO
ASSERT(false);
/*
Matrix camera_mtx = m_universe.getMatrix(camera);
Vec3 cam_right = camera_mtx.getXVector();
Vec3 cam_up = -camera_mtx.getYVector();
for (int j = 0, nj = m_text_meshes.size(); j < nj; ++j)
{
TextMesh& text = *m_text_meshes.at(j);
Font* font = text.getFont();
const Vec3 cam_right = cam_rot * Vec3(1, 0, 0);
const Vec3 cam_up = cam_rot * Vec3(0, -1, 0);
for (int j = 0, nj = m_text_meshes.size(); j < nj; ++j) {
const TextMesh& text = *m_text_meshes.at(j);
const Font* font = text.getFont();
if (!font) font = m_renderer.getFontManager().getDefaultFont();
EntityRef entity = m_text_meshes.getKey(j);
const EntityRef entity = m_text_meshes.getKey(j);
const char* str = text.text.c_str();
Vec3 base = m_universe.getPosition(entity);
Quat rot = m_universe.getRotation(entity);
float scale = m_universe.getScale(entity);
Vec3 right = rot.rotate({ 1, 0, 0 }) * scale;
Vec3 up = rot.rotate({ 0, -1, 0 }) * scale;
if (text.m_flags.isSet(TextMesh::CAMERA_ORIENTED))
{
Vec3 base = (m_universe.getPosition(entity) - cam_pos).toFloat();
const Quat rot = m_universe.getRotation(entity);
const float scale = m_universe.getScale(entity);
Vec3 right = rot.rotate(Vec3(1, 0, 0)) * scale;
Vec3 up = rot.rotate(Vec3(0, -1, 0)) * scale;
if (text.m_flags.isSet(TextMesh::CAMERA_ORIENTED)) {
right = cam_right * scale;
up = cam_up * scale;
}
u32 color = text.color;
Vec2 text_size = font->CalcTextSizeA((float)text.getFontSize(), FLT_MAX, 0, str);
const Vec2 text_size = font->CalcTextSizeA((float)text.getFontSize(), FLT_MAX, 0, str);
base += right * text_size.x * -0.5f;
base += up * text_size.y * -0.5f;
for (int i = 0, n = text.text.length(); i < n; ++i)
{
for (int i = 0, n = text.text.length(); i < n; ++i) {
const Font::Glyph* glyph = font->FindGlyph(str[i]);
if (!glyph) continue;
Vec3 x0y0 = base + right * glyph->X0 + up * glyph->Y0;
Vec3 x1y0 = base + right * glyph->X1 + up * glyph->Y0;
Vec3 x1y1 = base + right * glyph->X1 + up * glyph->Y1;
Vec3 x0y1 = base + right * glyph->X0 + up * glyph->Y1;
const Vec3 x0y0 = base + right * glyph->X0 + up * glyph->Y0;
const Vec3 x1y0 = base + right * glyph->X1 + up * glyph->Y0;
const Vec3 x1y1 = base + right * glyph->X1 + up * glyph->Y1;
const Vec3 x0y1 = base + right * glyph->X0 + up * glyph->Y1;
vertices.push({ x0y0, color, { glyph->U0, glyph->V0 } });
vertices.push({ x1y0, color, { glyph->U1, glyph->V0 } });
@ -967,8 +960,7 @@ public:
base += right * glyph->XAdvance;
}
}*/
}
}

View file

@ -384,7 +384,7 @@ public:
virtual void setTextMeshFontPath(EntityRef entity, const Path& path) = 0;
virtual bool isTextMeshCameraOriented(EntityRef entity) = 0;
virtual void setTextMeshCameraOriented(EntityRef entity, bool is_oriented) = 0;
virtual void getTextMeshesVertices(Array<TextMeshVertex>& vertices, EntityRef camera) = 0;
virtual void getTextMeshesVertices(Array<TextMeshVertex>& vertices, const DVec3& cam_pos, const Quat& rot) = 0;
protected:
virtual ~RenderScene() {}