This commit is contained in:
Mikulas Florek 2018-09-05 20:45:06 +02:00
parent baeaf81839
commit 63fde5871a
14 changed files with 419 additions and 71 deletions

View file

@ -475,7 +475,7 @@ public:
m_engine->update(*m_universe);
m_pipeline->render();
auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
static_cast<Renderer*>(renderer)->frame(false);
static_cast<Renderer*>(renderer)->frame();
m_engine->getFileSystem().updateAsyncTransactions();
if (frame_time < 1 / 60.0f)
{

View file

@ -65,8 +65,8 @@ struct System
MT::Event m_work_signal;
Array<MT::Task*> m_workers;
Array<Job> m_job_queue;
FiberDecl m_fiber_pool[256];
int m_free_fibers_indices[256];
FiberDecl m_fiber_pool[512];
int m_free_fibers_indices[512];
int m_num_free_fibers;
Array<SleepingFiber> m_sleeping_fibers;
IAllocator& m_allocator;

View file

@ -1,3 +0,0 @@
#include "stb/mf_resource.h"
const mf_resource* mf_resources = nullptr;
int mf_resources_count = 0;

View file

@ -1515,12 +1515,13 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
void generateCubemap(ComponentUID cmp)
{
// TODO
/*static const int TEXTURE_SIZE = 1024;
ASSERT(cmp.isValid());
const EntityRef entity = (EntityRef)cmp.entity;
static const int TEXTURE_SIZE = 1024;
Universe* universe = m_app.getWorldEditor().getUniverse();
if (universe->getName()[0] == '\0')
{
if (universe->getName()[0] == '\0') {
g_log_error.log("Editor") << "Universe must be saved before environment probe can be generated.";
return;
}
@ -1532,46 +1533,40 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
Vec3 probe_position = universe->getPosition((EntityRef)cmp.entity);
auto* scene = static_cast<RenderScene*>(universe->getScene(CAMERA_TYPE));
EntityRef camera_entity = scene->getCameraInSlot("probe");
if (!camera_entity.isValid())
{
g_log_error.log("Renderer") << "No camera in slot 'probe'.";
return;
}
scene->setCameraFOV(camera_entity, Math::degreesToRadians(90));
Viewport viewport;
viewport.is_ortho = false;
viewport.fov = Math::degreesToRadians(90.f);
viewport.near = 0.1f;
viewport.far = 10000.f;
viewport.w = TEXTURE_SIZE;
viewport.h = TEXTURE_SIZE;
m_pipeline->setScene(scene);
// TODO
//m_pipeline->resize(TEXTURE_SIZE, TEXTURE_SIZE);
m_pipeline->setViewport(viewport);
Renderer* renderer = static_cast<Renderer*>(plugin_manager.getPlugin("renderer"));
Vec3 dirs[] = {{-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};
Vec3 ups[] = {{0, 1, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, 1, 0}};
Vec3 ups_opengl[] = { { 0, -1, 0 },{ 0, -1, 0 },{ 0, 0, 1 },{ 0, 0, -1 },{ 0, -1, 0 },{ 0, -1, 0 } };
Array<u8> data(allocator);
data.resize(6 * TEXTURE_SIZE * TEXTURE_SIZE * 4);
ffr::TextureHandle texture = ffr::allocTextureHandle();
ffr::createTexture(texture, TEXTURE_SIZE, TEXTURE_SIZE, ffr::TextureFormat::RGBA8, 0, nullptr);
renderer->frame(false); // submit
renderer->frame(false); // wait for gpu
for (int i = 0; i < 6; ++i)
{
Matrix mtx = Matrix::IDENTITY;
mtx.setTranslation(probe_position);
renderer->startCapture();
for (int i = 0; i < 6; ++i) {
const bool ndc_bottom_left = ffr::isOriginBottomLeft();
Vec3 side = crossProduct(ndc_bottom_left ? ups_opengl[i] : ups[i], dirs[i]);
Matrix mtx = Matrix::IDENTITY;
mtx.setZVector(dirs[i]);
mtx.setYVector(ndc_bottom_left ? ups_opengl[i] : ups[i]);
mtx.setXVector(side);
universe->setMatrix(camera_entity, mtx);
viewport.pos = probe_position;
viewport.rot = mtx.getRotation();
m_pipeline->setViewport(viewport);
m_pipeline->render();
const ffr::TextureHandle res = m_pipeline->getOutput();
ffr::getTextureImage(res, TEXTURE_SIZE * TEXTURE_SIZE * 4, &data[i * TEXTURE_SIZE * TEXTURE_SIZE * 4]);
renderer->getTextureImage(res, TEXTURE_SIZE * TEXTURE_SIZE * 4, &data[i * TEXTURE_SIZE * TEXTURE_SIZE * 4]);
if (ndc_bottom_left) continue;
@ -1585,6 +1580,10 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
flipX(tmp, TEXTURE_SIZE);
}
}
renderer->stopCapture();
renderer->frame();
renderer->frame();
cmft::Image image;
cmft::Image irradiance;
@ -1612,29 +1611,38 @@ struct EnvironmentProbePlugin final : public PropertyGrid::IPlugin
cmft::imageFromRgba32f(image, cmft::TextureFormat::RGBA8);
cmft::imageFromRgba32f(irradiance, cmft::TextureFormat::RGBA8);
int irradiance_size = 32;
int radiance_size = 128;
int reflection_size = TEXTURE_SIZE;
if (scene->isEnvironmentProbeCustomSize(cmp.entity))
{
irradiance_size = scene->getEnvironmentProbeIrradianceSize(cmp.entity);
radiance_size = scene->getEnvironmentProbeRadianceSize(cmp.entity);
reflection_size = scene->getEnvironmentProbeReflectionSize(cmp.entity);
if (scene->isEnvironmentProbeCustomSize(entity)) {
irradiance_size = scene->getEnvironmentProbeIrradianceSize(entity);
radiance_size = scene->getEnvironmentProbeRadianceSize(entity);
reflection_size = scene->getEnvironmentProbeReflectionSize(entity);
}
for (int i = 3; i < data.size(); i += 4) data[i] = 0xff;
saveCubemap(cmp, (u8*)irradiance.m_data, irradiance_size, "_irradiance");
saveCubemap(cmp, (u8*)image.m_data, radiance_size, "_radiance");
if (scene->isEnvironmentProbeReflectionEnabled(cmp.entity))
{
if (scene->isEnvironmentProbeReflectionEnabled(entity)) {
auto& fs = m_app.getWorldEditor().getEngine().getFileSystem();
for(int i = 0; i < 6; ++i) {
const char* pp[] = {
"test0.tga",
"test1.tga",
"test2.tga",
"test3.tga",
"test4.tga",
"test5.tga",
};
auto* f = fs.open(fs.getDefaultDevice(), Path(pp[i]), FS::Mode::CREATE_AND_WRITE);
Lumix::Texture::saveTGA(f, TEXTURE_SIZE, TEXTURE_SIZE, 4, data.begin() + 4 * TEXTURE_SIZE * TEXTURE_SIZE * i, Path(pp[i]), m_app.getWorldEditor().getAllocator());
fs.close(*f);
}
saveCubemap(cmp, &data[0], reflection_size, "");
}
ffr::destroy(texture);
scene->reloadEnvironmentProbe(cmp.entity);*/
scene->reloadEnvironmentProbe(entity);
}
@ -2878,7 +2886,7 @@ struct EditorUIRenderPlugin final : public StudioApp::GUIPlugin
cmd->plugin = this;
renderer->push(cmd);
renderer->frame(false);
renderer->frame();
}

View file

@ -893,6 +893,16 @@ void applyUniformMatrix4x3f(int location, const float* value)
glUniformMatrix4x3fv(location, 1, false, value);
}
void applyUniform1i(int location, int value)
{
glUniform1i(location, value);
}
void applyUniform4f(int location, const float* value)
{
glUniform4fv(location, 1, value);
}
void applyUniformMatrix3x4f(int location, const float* value)
{
glUniformMatrix3x4fv(location, 1, false, value);
@ -933,6 +943,9 @@ void useProgram(ProgramHandle handle)
case UniformType::INT:
glUniform1i(pu.loc, *(int*)u.data);
break;
case UniformType::IVEC2:
glUniform2iv(pu.loc, u.count, (int*)u.data);
break;
default: ASSERT(false); break;
}
}
@ -1160,6 +1173,22 @@ void update(BufferHandle buffer, const void* data, size_t offset, size_t size)
}
void startCapture()
{
if (g_ffr.rdoc_api) {
g_ffr.rdoc_api->StartFrameCapture(nullptr, nullptr);
}
}
void stopCapture()
{
if (g_ffr.rdoc_api) {
g_ffr.rdoc_api->EndFrameCapture(nullptr, nullptr);
}
}
void swapBuffers()
{
checkThread();
@ -1553,6 +1582,7 @@ static uint getSize(UniformType type)
{
case UniformType::INT: return sizeof(int);
case UniformType::FLOAT: return sizeof(float);
case UniformType::IVEC2: return sizeof(int) * 2;
case UniformType::VEC2: return sizeof(float) * 2;
case UniformType::VEC3: return sizeof(float) * 3;
case UniformType::VEC4: return sizeof(float) * 4;
@ -1700,6 +1730,7 @@ ProgramHandle createProgram(const char** srcs, const ShaderType* types, int num,
case GL_FLOAT_MAT4: ffr_type = UniformType::MAT4; break;
case GL_FLOAT_MAT4x3: ffr_type = UniformType::MAT4X3; break;
case GL_FLOAT_MAT3x4: ffr_type = UniformType::MAT3X4; break;
case GL_INT_VEC2: ffr_type = UniformType::IVEC2; break;
default: ASSERT(false); ffr_type = UniformType::VEC4; break;
}

View file

@ -103,6 +103,7 @@ enum class UniformType : uint {
VEC2,
VEC3,
VEC4,
IVEC2,
MAT4,
MAT4X3,
MAT3X4
@ -151,6 +152,8 @@ bool isHomogenousDepth();
bool isOriginBottomLeft();
void checkThread();
void shutdown();
void startCapture();
void stopCapture();
void clear(uint flags, const float* color, float depth);
@ -210,6 +213,8 @@ void setUniformMatrix3x4f(UniformHandle uniform, const float* value);
void setUniformMatrix4f(UniformHandle uniform, const float* value);
void setUniformMatrix4x3f(UniformHandle uniform, const float* value);
int getUniformLocation(ProgramHandle program_handle, UniformHandle uniform);
void applyUniform1i(int location, int value);
void applyUniform4f(int location, const float* value);
void applyUniformMatrix3x4f(int location, const float* value);
void applyUniformMatrix4f(int location, const float* value);
void applyUniformMatrix4fv(int location, uint count, const float* value);

View file

@ -85,6 +85,7 @@ FFR_GL_IMPORT(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri);
FFR_GL_IMPORT(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D);
FFR_GL_IMPORT(PFNGLTEXTURESTORAGE3DPROC, glTextureStorage3D);
FFR_GL_IMPORT(PFNGLUNIFORM1IPROC, glUniform1i);
FFR_GL_IMPORT(PFNGLUNIFORM2IVPROC, glUniform2iv);
FFR_GL_IMPORT(PFNGLUNIFORM1FVPROC, glUniform1fv);
FFR_GL_IMPORT(PFNGLUNIFORM2FVPROC, glUniform2fv);
FFR_GL_IMPORT(PFNGLUNIFORM3FVPROC, glUniform3fv);

View file

@ -75,6 +75,7 @@ struct PipelineImpl final : Pipeline
m_draw2d.PushClipRectFullScreen();
m_draw2d.PushTextureID(font_atlas.TexID);
m_position_radius_uniform = ffr::allocUniform("u_pos_radius", ffr::UniformType::VEC4, 1);
m_terrain_params_uniform = ffr::allocUniform("u_terrain_params", ffr::UniformType::VEC4, 1);
m_rel_camera_pos_uniform = ffr::allocUniform("u_rel_camera_pos", ffr::UniformType::VEC4, 1);
m_terrain_scale_uniform = ffr::allocUniform("u_terrain_scale", ffr::UniformType::VEC4, 1);
@ -87,6 +88,37 @@ struct PipelineImpl final : Pipeline
m_radiance_map_uniform = ffr::allocUniform("u_radiancemap", ffr::UniformType::INT, 1);
m_material_params_uniform = ffr::allocUniform("u_material_params", ffr::UniformType::VEC4, 1);
m_material_color_uniform = ffr::allocUniform("u_material_color", ffr::UniformType::VEC4, 1);
float cube_verts[] = {
-1, -1, -1,
1, -1, -1,
1, -1, 1,
-1, -1, 1,
-1, 1, -1,
1, 1, -1,
1, 1, 1,
-1, 1, 1
};
const Renderer::MemRef vb_mem = m_renderer.copy(cube_verts, sizeof(cube_verts));
m_cube_vb = m_renderer.createBuffer(vb_mem);
u16 cube_indices[] = {
0, 1, 2,
0, 2, 3,
4, 6, 5,
4, 7, 6,
0, 4, 5,
0, 5, 1,
2, 6, 7,
2, 7, 3,
0, 3, 7,
0, 7, 4,
1, 2, 6,
1, 6, 5
};
const Renderer::MemRef ib_mem = m_renderer.copy(cube_indices, sizeof(cube_indices));
m_cube_ib = m_renderer.createBuffer(ib_mem);
}
@ -350,6 +382,8 @@ struct PipelineImpl final : Pipeline
state.camera_inv_view_projection = state.camera_view_projection;
state.camera_inv_view_projection.inverse();
state.time = m_timer->getTimeSinceStart();
state.framebuffer_size.x = m_viewport.w;
state.framebuffer_size.y = m_viewport.h;
const EntityPtr global_light = m_scene->getActiveGlobalLight();
if(global_light.isValid()) {
@ -516,7 +550,6 @@ struct PipelineImpl final : Pipeline
vertex_decl.addAttribute(2, ffr::AttributeType::FLOAT, false, false);
vertex_decl.addAttribute(4, ffr::AttributeType::U8, true, false);
ffr::BufferHandle vb = ffr::allocBufferHandle();
ffr::BufferHandle ib = ffr::allocBufferHandle();
ffr::createBuffer(vb, vtx_buffer_mem.size, vtx_buffer_mem.data);
@ -835,6 +868,168 @@ struct PipelineImpl final : Pipeline
return cp;
}
static int bindTextures(lua_State* L)
{
struct Cmd : Renderer::RenderCommandBase {
void setup() override {}
void execute() override
{
for(int i = 0; i < m_textures_count; ++i) {
ffr::bindTexture(m_offset + i, m_textures[i].handle);
ffr::setUniform1i(m_textures[i].uniform, i + m_offset);
}
}
struct {
ffr::TextureHandle handle;
ffr::UniformHandle uniform;
} m_textures[16];
int m_offset = 0;
int m_textures_count = 0;
};
const int pipeline_idx = lua_upvalueindex(1);
if (lua_type(L, pipeline_idx) != LUA_TLIGHTUSERDATA) {
LuaWrapper::argError<PipelineImpl*>(L, pipeline_idx);
}
PipelineImpl* pipeline = LuaWrapper::toType<PipelineImpl*>(L, pipeline_idx);
LuaWrapper::checkTableArg(L, 1);
const int offset = lua_gettop(L) > 1 ? LuaWrapper::checkArg<int>(L, 2) : 0;
Cmd* cmd = LUMIX_NEW(pipeline->m_renderer.getAllocator(), Cmd);
cmd->m_offset = offset;
lua_pushnil(L);
while (lua_next(L, 1) != 0) {
if(lua_type(L, -1) != LUA_TNUMBER) {
LUMIX_DELETE(pipeline->m_renderer.getAllocator(), cmd);
return luaL_error(L, "%s", "Incorrect texture arguments of bindTextures");
}
if(lua_type(L, -2) != LUA_TSTRING) {
LUMIX_DELETE(pipeline->m_renderer.getAllocator(), cmd);
return luaL_error(L, "%s", "Incorrect texture arguments of bindTextures");
}
if (cmd->m_textures_count > lengthOf(cmd->m_textures)) {
LUMIX_DELETE(pipeline->m_renderer.getAllocator(), cmd);
return luaL_error(L, "%s", "Too many texture in bindTextures call");
}
const char* uniform_name = lua_tostring(L, -2);
cmd->m_textures[cmd->m_textures_count].uniform = ffr::allocUniform(uniform_name, ffr::UniformType::INT, 1);
const int rb_idx = (int)lua_tointeger(L, -1);
cmd->m_textures[cmd->m_textures_count].handle = pipeline->m_renderbuffers[rb_idx].handle;
++cmd->m_textures_count;
lua_pop(L, 1);
}
pipeline->m_renderer.push(cmd);
return 0;
};
static int renderEnvProbeVolumes(lua_State* L)
{
const int pipeline_idx = lua_upvalueindex(1);
if (lua_type(L, pipeline_idx) != LUA_TLIGHTUSERDATA) {
LuaWrapper::argError<PipelineImpl*>(L, pipeline_idx);
}
PipelineImpl* pipeline = LuaWrapper::toType<PipelineImpl*>(L, pipeline_idx);
const int shader_id = LuaWrapper::checkArg<int>(L, 1);
const Shader* shader = [&] {
for (const ShaderRef& s : pipeline->m_shaders) {
if(s.id == shader_id) {
return s.res;
}
}
return (Shader*)nullptr;
}();
if (!shader) {
return luaL_error(L, "Unknown shader id %d in renderEnvProbeVolumes.", shader_id);
}
const CameraParams cp = checkCameraParams(L, 2);
struct Cmd : public Renderer::RenderCommandBase
{
struct Probe
{
Vec3 pos;
ffr::TextureHandle texture;
};
Cmd(IAllocator& allocator) : m_probes(allocator) {}
void setup() override
{
m_pipeline->getScene()->getEnvironmentProbes(m_probes);
}
void execute() override
{
PROFILE_FUNCTION();
if(m_probes.empty()) return;
ffr::pushDebugGroup("environment");
const Shader::Program& prog = Shader::getProgram(m_shader, 0);
if(!prog.handle.isValid()) return;
const int pos_radius_uniform_loc = ffr::getUniformLocation(prog.handle, m_pos_radius_uniform);
ffr::VertexDecl decl;
decl.addAttribute(3, ffr::AttributeType::FLOAT, false, false);
ffr::setVertexBuffer(&decl, m_vb, 0, nullptr);
ffr::setIndexBuffer(m_ib);
ffr::useProgram(prog.handle);
ffr::setState(0);
const int irradiance_map_loc = ffr::getUniformLocation(prog.handle, m_irradiance_map_uniform);
const int radiance_map_loc = ffr::getUniformLocation(prog.handle, m_radiance_map_uniform);
const Vec3 cam_pos = m_camera_params.pos;
for (const EnvProbeInfo& probe : m_probes) {
const Vec4 pos_radius(probe.position - cam_pos, probe.radius);
ffr::bindTexture(0, probe.radiance);
ffr::applyUniform1i(irradiance_map_loc, 0);
ffr::bindTexture(1, probe.radiance);
ffr::applyUniform1i(radiance_map_loc, 1);
ffr::applyUniform4f(pos_radius_uniform_loc, &pos_radius.x);
ffr::drawTriangles(36);
}
ffr::popDebugGroup();
}
ffr::BufferHandle m_ib;
ffr::BufferHandle m_vb;
ffr::UniformHandle m_pos_radius_uniform;
ffr::UniformHandle m_irradiance_map_uniform;
ffr::UniformHandle m_radiance_map_uniform;
CameraParams m_camera_params;
PipelineImpl* m_pipeline;
Array<EnvProbeInfo> m_probes;
Shader::RenderData* m_shader;
};
if(shader->isReady()) {
IAllocator& allocator = pipeline->m_renderer.getAllocator();
Cmd* cmd = LUMIX_NEW(allocator, Cmd)(allocator);
cmd->m_pipeline = pipeline;
cmd->m_shader = shader->m_render_data;
cmd->m_ib = pipeline->m_cube_ib;
cmd->m_vb = pipeline->m_cube_vb;
cmd->m_camera_params = cp;
cmd->m_irradiance_map_uniform = pipeline->m_irradiance_map_uniform;
cmd->m_radiance_map_uniform = pipeline->m_radiance_map_uniform;
cmd->m_pos_radius_uniform = pipeline->m_position_radius_uniform;
pipeline->m_renderer.push(cmd);
}
return 0;
}
static int renderMeshes(lua_State* L)
{
@ -2090,9 +2285,11 @@ struct PipelineImpl final : Pipeline
registerConst("STENCIL_KEEP", (uint)ffr::StencilOps::KEEP);
registerConst("STENCIL_REPLACE", (uint)ffr::StencilOps::REPLACE);
registerCFunction("bindTextures", PipelineImpl::bindTextures);
registerCFunction("drawArray", PipelineImpl::drawArray);
registerCFunction("getCameraParams", PipelineImpl::getCameraParams);
registerCFunction("getShadowCameraParams", PipelineImpl::getShadowCameraParams);
registerCFunction("renderEnvProbeVolumes", PipelineImpl::renderEnvProbeVolumes);
registerCFunction("renderMeshes", PipelineImpl::renderMeshes);
registerCFunction("renderParticles", PipelineImpl::renderParticles);
registerCFunction("renderTerrains", PipelineImpl::renderTerrains);
@ -2151,6 +2348,7 @@ struct PipelineImpl final : Pipeline
Array<ShaderRef> m_shaders;
Timer* m_timer;
ffr::UniformHandle m_position_radius_uniform;
ffr::UniformHandle m_terrain_params_uniform;
ffr::UniformHandle m_rel_camera_pos_uniform;
ffr::UniformHandle m_terrain_scale_uniform;
@ -2163,6 +2361,8 @@ struct PipelineImpl final : Pipeline
ffr::UniformHandle m_radiance_map_uniform;
ffr::UniformHandle m_material_params_uniform;
ffr::UniformHandle m_material_color_uniform;
ffr::BufferHandle m_cube_vb;
ffr::BufferHandle m_cube_ib;
};

View file

@ -117,6 +117,7 @@ struct EnvironmentProbe
Texture* texture;
Texture* irradiance;
Texture* radiance;
float radius;
u64 guid;
FlagSet<Flags, u32> flags;
u16 radiance_size = 128;
@ -1093,6 +1094,7 @@ public:
EnvironmentProbe& probe = m_environment_probes[entity];
serializer.write("guid", probe.guid);
serializer.write("flags", probe.flags.base);
serializer.write("radius", probe.radius);
serializer.write("radiance_size", probe.radiance_size);
serializer.write("irradiance_size", probe.irradiance_size);
serializer.write("reflection_size", probe.reflection_size);
@ -1109,6 +1111,7 @@ public:
EnvironmentProbe& probe = m_environment_probes.insert(entity);
serializer.read(&probe.guid);
serializer.read(&probe.flags.base);
serializer.read(&probe.radius);
serializer.read(&probe.radiance_size);
serializer.read(&probe.irradiance_size);
serializer.read(&probe.reflection_size);
@ -1319,6 +1322,7 @@ public:
EntityRef entity = m_environment_probes.getKey(i);
serializer.write(entity);
const EnvironmentProbe& probe = m_environment_probes.at(i);
serializer.write(probe.radius);
serializer.write(probe.guid);
serializer.write(probe.flags.base);
serializer.write(probe.radiance_size);
@ -3417,32 +3421,31 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
void reloadEnvironmentProbe(EntityRef entity) override
{
// TODO
ASSERT(false);
/*
auto& probe = m_environment_probes[entity];
auto* texture_manager = m_engine.getResourceManager().get(Texture::TYPE);
if (probe.texture) texture_manager->unload(*probe.texture);
ResourceManagerHub& rm = m_engine.getResourceManager();
if (probe.texture) probe.texture->getResourceManager().unload(*probe.texture);
probe.texture = nullptr;
StaticString<MAX_PATH_LENGTH> path;
if (probe.flags.isSet(EnvironmentProbe::REFLECTION))
{
if (probe.flags.isSet(EnvironmentProbe::REFLECTION)) {
path << "universes/" << m_universe.getName() << "/probes/" << probe.guid << ".dds";
probe.texture = static_cast<Texture*>(texture_manager->load(Path(path)));
probe.texture->setFlag(BGFX_TEXTURE_SRGB, true);
probe.texture = rm.load<Texture>(Path(path));
// TODO
//probe.texture->setFlag(BGFX_TEXTURE_SRGB, true);
}
path = "universes/";
path << m_universe.getName() << "/probes/" << probe.guid << "_irradiance.dds";
probe.irradiance = static_cast<Texture*>(texture_manager->load(Path(path)));
probe.irradiance->setFlag(BGFX_TEXTURE_SRGB, true);
probe.irradiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
probe.irradiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);
if(probe.irradiance) probe.irradiance->getResourceManager().unload(*probe.irradiance);
probe.irradiance = rm.load<Texture>(Path(path));
//probe.irradiance->setFlag(BGFX_TEXTURE_SRGB, true);
//probe.irradiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
//probe.irradiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);
path = "universes/";
path << m_universe.getName() << "/probes/" << probe.guid << "_radiance.dds";
probe.radiance = static_cast<Texture*>(texture_manager->load(Path(path)));
probe.radiance->setFlag(BGFX_TEXTURE_SRGB, true);
probe.radiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
probe.radiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);*/
if (probe.radiance) probe.irradiance->getResourceManager().unload(*probe.radiance);
probe.radiance = rm.load<Texture>(Path(path));
//probe.radiance->setFlag(BGFX_TEXTURE_SRGB, true);
//probe.radiance->setFlag(BGFX_TEXTURE_MIN_ANISOTROPIC, true);
//probe.radiance->setFlag(BGFX_TEXTURE_MAG_ANISOTROPIC, true);
}
@ -3465,38 +3468,67 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
return nearest;
}
void getEnvironmentProbes(Array<EnvProbeInfo>& probes) override
{
PROFILE_FUNCTION();
probes.resize(m_environment_probes.size());
for (int i = 0; i < m_environment_probes.size(); ++i) {
const EnvironmentProbe& probe = m_environment_probes.at(i);
const EntityRef entity = m_environment_probes.getKey(i);
EnvProbeInfo& out = probes[i];
out.radius = probe.radius;
out.position = m_universe.getPosition(entity);
out.radiance = probe.radiance && probe.radiance->isReady() ? probe.radiance->handle : ffr::INVALID_TEXTURE;
out.irradiance = probe.irradiance && probe.irradiance->isReady() ? probe.irradiance->handle : ffr::INVALID_TEXTURE;
out.reflection = probe.texture && probe.texture->isReady() ? probe.texture->handle : ffr::INVALID_TEXTURE;
}
}
int getEnvironmentProbeIrradianceSize(EntityRef entity)
int getEnvironmentProbeIrradianceSize(EntityRef entity) override
{
return m_environment_probes[entity].irradiance_size;
}
void setEnvironmentProbeIrradianceSize(EntityRef entity, int size)
void setEnvironmentProbeIrradianceSize(EntityRef entity, int size) override
{
m_environment_probes[entity].irradiance_size = size;
}
int getEnvironmentProbeRadianceSize(EntityRef entity)
float getEnvironmentProbeRadius(EntityRef entity) override
{
return m_environment_probes[entity].radius;
}
void setEnvironmentProbeRadius(EntityRef entity, float radius) override
{
m_environment_probes[entity].radius = radius;
}
int getEnvironmentProbeRadianceSize(EntityRef entity) override
{
return m_environment_probes[entity].radiance_size;
}
void setEnvironmentProbeRadianceSize(EntityRef entity, int size)
void setEnvironmentProbeRadianceSize(EntityRef entity, int size) override
{
m_environment_probes[entity].radiance_size = size;
}
int getEnvironmentProbeReflectionSize(EntityRef entity)
int getEnvironmentProbeReflectionSize(EntityRef entity) override
{
return m_environment_probes[entity].reflection_size;
}
void setEnvironmentProbeReflectionSize(EntityRef entity, int size)
void setEnvironmentProbeReflectionSize(EntityRef entity, int size) override
{
m_environment_probes[entity].reflection_size = size;
}
@ -3916,6 +3948,7 @@ bgfx::TextureHandle& handle = pipeline->getRenderbuffer(framebuffer_name, render
probe.irradiance->setFlag(Texture::Flags::SRGB, true);
probe.radiance = rm.load<Texture>(Path("models/common/default_probe.dds"));
probe.radiance->setFlag(Texture::Flags::SRGB, true);
probe.radius = 1;
probe.guid = Math::randGUID();
m_universe.onComponentCreated(entity, ENVIRONMENT_PROBE_TYPE, this);

View file

@ -5,6 +5,7 @@
#include "engine/flag_set.h"
#include "engine/matrix.h"
#include "engine/iplugin.h"
#include "ffr/ffr.h"
struct lua_State;
@ -102,6 +103,16 @@ struct GrassInfo
};
struct EnvProbeInfo
{
Vec3 position;
float radius;
ffr::TextureHandle reflection;
ffr::TextureHandle radiance;
ffr::TextureHandle irradiance;
};
struct DebugTriangle
{
Vec3 p0;
@ -355,6 +366,7 @@ public:
virtual float getPointLightSpecularIntensity(EntityRef entity) = 0;
virtual void setPointLightSpecularIntensity(EntityRef entity, float color) = 0;
virtual void getEnvironmentProbes(Array<EnvProbeInfo>& probes) = 0;
virtual int getEnvironmentProbeIrradianceSize(EntityRef entity) = 0;
virtual void setEnvironmentProbeIrradianceSize(EntityRef entity, int size) = 0;
virtual int getEnvironmentProbeRadianceSize(EntityRef entity) = 0;
@ -371,6 +383,8 @@ public:
virtual void reloadEnvironmentProbe(EntityRef entity) = 0;
virtual EntityPtr getNearestEnvironmentProbe(const Vec3& pos) const = 0;
virtual u64 getEnvironmentProbeGUID(EntityRef entity) const = 0;
virtual float getEnvironmentProbeRadius(EntityRef entity) = 0;
virtual void setEnvironmentProbeRadius(EntityRef entity, float radius) = 0;
virtual void setTextMeshText(EntityRef entity, const char* text) = 0;
virtual const char* getTextMeshText(EntityRef entity) = 0;

View file

@ -281,6 +281,7 @@ static void registerProperties(IAllocator& allocator)
BoneProperty()
),
component("environment_probe",
property("Radius", LUMIX_PROP(RenderScene, EnvironmentProbeRadius)),
property("Enabled reflection", LUMIX_PROP_FULL(RenderScene, isEnvironmentProbeReflectionEnabled, enableEnvironmentProbeReflection)),
property("Override global size", LUMIX_PROP_FULL(RenderScene, isEnvironmentProbeCustomSize, enableEnvironmentProbeCustomSize)),
property("Radiance size", LUMIX_PROP(RenderScene, EnvironmentProbeRadianceSize)),
@ -506,6 +507,29 @@ struct RendererImpl final : public Renderer
}
void getTextureImage(ffr::TextureHandle texture, int size, void* data) override
{
struct Cmd : RenderCommandBase {
void setup() override {}
void execute() override {
ffr::pushDebugGroup("get image data");
ffr::getTextureImage(handle, size, buf);
ffr::popDebugGroup();
}
ffr::TextureHandle handle;
uint size;
void* buf;
};
Cmd* cmd = LUMIX_NEW(m_render_task.m_allocator, Cmd);
cmd->handle = texture;
cmd->size = size;
cmd->buf = data;
push(cmd);
}
ffr::TextureHandle loadTexture(const MemRef& memory, u32 flags, ffr::TextureInfo* info) override
{
ASSERT(memory.size > 0);
@ -840,6 +864,34 @@ struct RendererImpl final : public Renderer
}
void startCapture() override
{
struct Cmd : RenderCommandBase {
void setup() override {}
void execute() override {
PROFILE_FUNCTION();
ffr::startCapture();
}
};
Cmd* cmd = LUMIX_NEW(m_allocator, Cmd);
push(cmd);
}
void stopCapture() override
{
struct Cmd : RenderCommandBase {
void setup() override {}
void execute() override {
PROFILE_FUNCTION();
ffr::stopCapture();
}
};
Cmd* cmd = LUMIX_NEW(m_allocator, Cmd);
push(cmd);
}
void pushSwapCommand()
{
struct SwapCmd : RenderCommandBase {
@ -852,6 +904,7 @@ struct RendererImpl final : public Renderer
renderer->m_render_task.m_transient_buffer_offset = 0;
}
RendererImpl* renderer;
bool capture;
};
SwapCmd* swap_cmd = LUMIX_NEW(m_allocator, SwapCmd);
swap_cmd->renderer = this;
@ -859,7 +912,7 @@ struct RendererImpl final : public Renderer
}
void frame(bool capture) override
void frame() override
{
PROFILE_FUNCTION();
pushSwapCommand();

View file

@ -80,7 +80,9 @@ class LUMIX_RENDERER_API Renderer : public IPlugin
enum { MAX_SHADER_DEFINES = 32 };
public:
virtual ~Renderer() {}
virtual void frame(bool capture) = 0;
virtual void startCapture() = 0;
virtual void stopCapture() = 0;
virtual void frame() = 0;
virtual void resize(int width, int height) = 0;
virtual void makeScreenshot(const Path& filename) = 0;
virtual u8 getShaderDefineIdx(const char* define) = 0;
@ -112,6 +114,7 @@ class LUMIX_RENDERER_API Renderer : public IPlugin
virtual ffr::TextureHandle createTexture(uint w, uint h, ffr::TextureFormat format, u32 flags, const MemRef& memory) = 0;
virtual ffr::TextureHandle loadTexture(const MemRef& memory, u32 flags, ffr::TextureInfo* info) = 0;
virtual void getTextureImage(ffr::TextureHandle texture, int size, void* data) = 0;
virtual void destroy(ffr::TextureHandle tex) = 0;
virtual void push(RenderCommandBase* cmd) = 0;

View file

@ -63,6 +63,7 @@ const Shader::Program& Shader::getProgram(RenderData* rd, u32 defines)
" float u_light_intensity;\n"
" float u_light_indirect_intensity;\n"
" float u_time;\n"
" ivec2 u_framebuffer_size;\n"
"};\n"
"uniform samplerCube u_irradiancemap;\n"
"uniform samplerCube u_radiancemap;\n"
@ -94,7 +95,7 @@ const Shader::Program& Shader::getProgram(RenderData* rd, u32 defines)
for(int& i : program.attribute_by_semantics) i = -1;
// TODO shader path - last argument
program.handle = ffr::createProgram(codes, types, rd->sources.size(), prefixes, 2 + defines_count, "TODO");
program.handle = ffr::createProgram(codes, types, rd->sources.size(), prefixes, 2 + defines_count, rd->path.c_str());
program.use_semantics = false;
if (program.handle.isValid()) {
ffr::uniformBlockBinding(program.handle, "GlobalState", 0);
@ -397,6 +398,7 @@ bool Shader::load(FS::IFile& file)
IAllocator& allocator = m_renderer.getAllocator();
m_render_data = LUMIX_NEW(allocator, RenderData)(m_renderer, allocator);
m_render_data->path = getPath();
lua_pushlightuserdata(L, this);
lua_setfield(L, LUA_GLOBALSINDEX, "this");

View file

@ -101,6 +101,7 @@ public:
Array<Source> sources;
Array<u8> include;
Array<AttributeInfo> attributes;
Path path;
}* m_render_data;
public: