From 8a40ad9c4cdefba2cbb48877ccbcdc186d52cc3d Mon Sep 17 00:00:00 2001 From: Mikulas Florek Date: Sat, 16 May 2015 13:17:20 +0200 Subject: [PATCH] pipelines use lua --- src/graphics/frame_buffer.cpp | 30 +- src/graphics/frame_buffer.h | 6 +- src/graphics/pipeline.cpp | 900 +++++++++++++--------------------- src/graphics/pipeline.h | 2 - src/graphics/shader.cpp | 9 +- 5 files changed, 360 insertions(+), 587 deletions(-) diff --git a/src/graphics/frame_buffer.cpp b/src/graphics/frame_buffer.cpp index 1082c40c5..a03055613 100644 --- a/src/graphics/frame_buffer.cpp +++ b/src/graphics/frame_buffer.cpp @@ -2,6 +2,8 @@ #include "core/json_serializer.h" #include "core/vec3.h" #include "graphics/gl_ext.h" +#include +#include namespace Lumix @@ -146,28 +148,18 @@ static GLint getGLFormat(const char* format) } -void FrameBuffer::RenderBuffer::deserialize(JsonSerializer& serializer) +void FrameBuffer::RenderBuffer::parse(lua_State* L) { - serializer.deserializeObjectBegin(); - while (!serializer.isObjectEnd()) + if (lua_getfield(L, -1, "format") == LUA_TSTRING) { - char tmp[50]; - serializer.deserializeLabel(tmp, sizeof(tmp)); - if (strcmp(tmp, "format") == 0) - { - serializer.deserialize(tmp, sizeof(tmp), "rgb"); - m_format = getGLFormat(tmp); - } - else if (strcmp(tmp, "is_texture") == 0) - { - serializer.deserialize(m_is_texture, "false"); - } - else - { - g_log_error.log("deserialize") << "Unknown renderbuffer format " << tmp; - } + m_format = getGLFormat(lua_tostring(L, -1)); } - serializer.deserializeObjectEnd(); + lua_pop(L, 1); + if (lua_getfield(L, -1, "is_texture") == LUA_TBOOLEAN) + { + m_is_texture = lua_toboolean(L, -1) != 0; + } + lua_pop(L, 1); } diff --git a/src/graphics/frame_buffer.h b/src/graphics/frame_buffer.h index 5d48747da..78dba2c83 100644 --- a/src/graphics/frame_buffer.h +++ b/src/graphics/frame_buffer.h @@ -6,6 +6,9 @@ #include "graphics/gl_ext.h" +struct lua_State; + + namespace Lumix { @@ -24,7 +27,7 @@ class FrameBuffer bool m_is_texture; GLuint m_id; - void deserialize(JsonSerializer& serializer); + void parse(lua_State* state); bool isDepth() const; }; @@ -32,6 +35,7 @@ class FrameBuffer { Declaration() : m_name(m_name_allocator) + , m_renderbuffers_count(0) { } static const int MAX_RENDERBUFFERS = 16; diff --git a/src/graphics/pipeline.cpp b/src/graphics/pipeline.cpp index 8c74fa4bc..a2effe670 100644 --- a/src/graphics/pipeline.cpp +++ b/src/graphics/pipeline.cpp @@ -26,6 +26,8 @@ #include "graphics/shader.h" #include "graphics/terrain.h" #include "graphics/texture.h" +#include +#include namespace Lumix @@ -48,225 +50,29 @@ static const float SHADOW_CAM_NEAR = 0.1f; static const float SHADOW_CAM_FAR = 10000.0f; -struct Command -{ - virtual ~Command() {} - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) = 0; - virtual void execute(PipelineInstanceImpl& pipeline) = 0; -}; - - -struct CustomCommand : public Command -{ - CustomCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - uint32_t m_name; -}; - - -struct PolygonModeCommand : public Command -{ - PolygonModeCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - bool m_fill; -}; - - -struct CullFaceCommand : public Command -{ - CullFaceCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - bool m_is_front; -}; - - - -struct SetPassCommand : public Command -{ - SetPassCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - uint32_t m_pass_hash; -}; - - -struct ClearCommand : public Command -{ - ClearCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - uint32_t m_buffers; -}; - - -struct RenderModelsCommand : public Command -{ - RenderModelsCommand(IAllocator&) : m_point_light_influenced_geometry(false) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - int64_t m_layer_mask; - bool m_point_light_influenced_geometry; -}; - - -struct DeferredPointLightLoopCommand : public Command -{ - DeferredPointLightLoopCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - Material* m_material; -}; - - -struct ApplyCameraCommand : public Command -{ - ApplyCameraCommand(IAllocator& allocator) - : m_camera_slot(allocator) - { } - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - string m_camera_slot; -}; - - -struct BindFramebufferCommand : public Command -{ - BindFramebufferCommand(IAllocator& allocator) - : m_buffer_name(allocator) - { } - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - string m_buffer_name; -}; - - -struct UnbindFramebufferCommand : public Command -{ - UnbindFramebufferCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl&, JsonSerializer&) override {} - virtual void execute(PipelineInstanceImpl& pipeline) override; -}; - - -struct DrawScreenQuadCommand : public Command -{ - DrawScreenQuadCommand(IAllocator& allocator) : m_allocator(allocator) {} - ~DrawScreenQuadCommand(); - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - IAllocator& m_allocator; - Mesh* m_mesh; - Geometry* m_geometry; -}; - - -struct RenderDebugLinesCommand : public Command -{ - RenderDebugLinesCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; -}; - - -struct RenderDebugTextsCommand : public Command -{ - RenderDebugTextsCommand(IAllocator&) {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; -}; - - -struct BindFramebufferTextureCommand : public Command -{ - BindFramebufferTextureCommand(IAllocator&) - { } - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - uint32_t m_renderbuffer_index; - char m_framebuffer_name[20]; - char m_uniform[20]; -}; - - -struct RenderShadowmapCommand : public Command -{ - RenderShadowmapCommand(IAllocator& allocator) - : m_camera_slot(allocator) - {} - - virtual void deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) override; - virtual void execute(PipelineInstanceImpl& pipeline) override; - - int64_t m_layer_mask; - StackAllocator<128> m_string_allocator; - string m_camera_slot; -}; +static int setPass(lua_State* L); +static int applyCamera(lua_State* L); +static int clear(lua_State* L); +static int renderModels(lua_State* L); +static int renderShadowmap(lua_State* L); +static int bindFramebufferTexture(lua_State* L); +static int polygonMode(lua_State* L); +static int executeCustomCommand(lua_State* L); +static int renderDebugTexts(lua_State* L); +static int renderDebugLines(lua_State* L); +static int cullFaces(lua_State* L); +static int bindFramebuffer(lua_State* L); +static int unbindFramebuffer(lua_State* L); struct PipelineImpl : public Pipeline { - struct CommandCreator - { - typedef Delegate Creator; - Creator m_creator; - uint32_t m_type_hash; - }; - - template - static Command* CreateCommand(IAllocator& allocator) - { - return allocator.newObject(allocator); - } - - PipelineImpl(const Path& path, ResourceManager& resource_manager, IAllocator& allocator) : Pipeline(path, resource_manager, allocator) , m_allocator(allocator) - , m_commands(allocator) , m_framebuffers(allocator) - , m_command_creators(allocator) + , m_lua_state(nullptr) { - addCommandCreator("clear").bind<&CreateCommand >(); - addCommandCreator("custom").bind<&CreateCommand >(); - addCommandCreator("render_models").bind<&CreateCommand >(); - addCommandCreator("apply_camera").bind<&CreateCommand >(); - addCommandCreator("bind_framebuffer").bind<&CreateCommand >(); - addCommandCreator("unbind_framebuffer").bind<&CreateCommand >(); - addCommandCreator("draw_screen_quad").bind<&CreateCommand >(); - addCommandCreator("bind_framebuffer_texture").bind<&CreateCommand >(); - addCommandCreator("render_shadowmap").bind<&CreateCommand >(); - addCommandCreator("render_debug_lines").bind<&CreateCommand >(); - addCommandCreator("render_debug_texts").bind<&CreateCommand >(); - addCommandCreator("polygon_mode").bind<&CreateCommand >(); - addCommandCreator("cull_face").bind<&CreateCommand >(); - addCommandCreator("set_pass").bind<&CreateCommand >(); - addCommandCreator("deferred_point_light_loop").bind<&CreateCommand >(); } @@ -278,127 +84,129 @@ struct PipelineImpl : public Pipeline virtual ~PipelineImpl() override { + if (m_lua_state) + { + lua_close(m_lua_state); + } ASSERT(isEmpty()); } virtual void doUnload(void) override { - for (int i = 0; i < m_commands.size(); ++i) + if (m_lua_state) { - m_allocator.deleteObject(m_commands[i]); + lua_close(m_lua_state); + m_lua_state = nullptr; } - m_commands.clear(); onEmpty(); } - CommandCreator::Creator& addCommandCreator(const char* type) + void parseRenderbuffers(lua_State* L, FrameBuffer::Declaration& decl) { - CommandCreator& creator = m_command_creators.pushEmpty(); - creator.m_type_hash = crc32(type); - return creator.m_creator; - } - - - Command* createCommand(uint32_t type_hash) - { - for (int i = 0; i < m_command_creators.size(); ++i) + int len = (int)lua_rawlen(L, -1); + for (int i = 0; i < len; ++i) { - if (m_command_creators[i].m_type_hash == type_hash) + if (lua_rawgeti(L, -1, 1 + i) == LUA_TTABLE) { - return m_command_creators[i].m_creator.invoke(m_allocator); + FrameBuffer::RenderBuffer& buf = decl.m_renderbuffers[decl.m_renderbuffers_count]; + buf.parse(L); + ++decl.m_renderbuffers_count; } + lua_pop(L, 1); } - return NULL; } - - bool deserializeFramebuffers(JsonSerializer& serializer) + + void parseFramebuffers(lua_State* L) { - while (!serializer.isArrayEnd()) + if (lua_getglobal(L, "framebuffers") == LUA_TTABLE) { - serializer.nextArrayItem(); - serializer.deserializeObjectBegin(); - FrameBuffer::Declaration& framebuffer = m_framebuffers.pushEmpty(); - - framebuffer.m_renderbuffers_count = 0; - while (!serializer.isObjectEnd()) + int len = (int)lua_rawlen(L, -1); + m_framebuffers.resize(len); + for (int i = 0; i < len; ++i) { - char label[40]; - serializer.deserializeLabel(label, sizeof(label)); - if (strcmp(label, "name") == 0) + if (lua_rawgeti(L, -1, 1 + i) == LUA_TTABLE) { - serializer.deserialize(label, sizeof(label), ""); - framebuffer.m_name = label; - } - else if (strcmp(label, "width") == 0) - { - serializer.deserialize(framebuffer.m_width, 0); - } - else if (strcmp(label, "height") == 0) - { - serializer.deserialize(framebuffer.m_height, 0); - } - else if (strcmp(label, "renderbuffers") == 0) - { - serializer.deserializeArrayBegin(); - while (!serializer.isArrayEnd()) + FrameBuffer::Declaration& decl = m_framebuffers[i]; + if (lua_getfield(L, -1, "name") == LUA_TSTRING) { - serializer.nextArrayItem(); - framebuffer.m_renderbuffers[framebuffer.m_renderbuffers_count].deserialize(serializer); - ++framebuffer.m_renderbuffers_count; + decl.m_name = lua_tostring(L, -1); } - serializer.deserializeArrayEnd(); - } - else - { - g_log_error.log("deserialize") << "Unknown label " << label << " found in " << getPath().c_str(); + lua_pop(L, 1); + if (lua_getfield(L, -1, "width") == LUA_TNUMBER) + { + decl.m_width = (int)lua_tointeger(L, -1); + } + lua_pop(L, 1); + if (lua_getfield(L, -1, "height") == LUA_TNUMBER) + { + decl.m_height = (int)lua_tointeger(L, -1); + } + lua_pop(L, 1); + if (lua_getfield(L, -1, "renderbuffers") == LUA_TTABLE) + { + parseRenderbuffers(L, decl); + } + lua_pop(L, 1); } + lua_pop(L, 1); } - serializer.deserializeObjectEnd(); } - serializer.deserializeArrayEnd(); - return true; + lua_pop(L, 1); } - virtual bool deserialize(JsonSerializer& serializer) override + + void registerCFunction(const char* name, lua_CFunction function) { - serializer.deserializeObjectBegin(); - serializer.deserializeArrayBegin("frame_buffers"); - m_framebuffers.clear(); - bool status = deserializeFramebuffers(serializer); - - serializer.deserializeArrayBegin("commands"); - while (!serializer.isArrayEnd()) - { - char tmp[255]; - serializer.deserializeArrayItem(tmp, 255, ""); - uint32_t command_type_hash = crc32(tmp); - Command* cmd = createCommand(command_type_hash); - if(cmd) - { - cmd->deserialize(*this, serializer); - m_commands.push(cmd); - } - else - { - status = false; - g_log_error.log("renderer") << "Unknown pipeline command \"" << tmp << "\" in pipeline " << getPath().c_str(); - } - } - serializer.deserializeArrayEnd(); - serializer.deserializeObjectEnd(); - return status; + lua_pushcfunction(m_lua_state, function); + lua_setglobal(m_lua_state, name); + } + + + void registerCFunctions() + { + registerCFunction("setPass", setPass); + registerCFunction("applyCamera", applyCamera); + registerCFunction("clear", clear); + registerCFunction("renderModels", renderModels); + registerCFunction("renderShadowmap", renderShadowmap); + registerCFunction("bindFramebufferTexture", bindFramebufferTexture); + registerCFunction("polygonMode", polygonMode); + registerCFunction("executeCustomCommand", executeCustomCommand); + registerCFunction("renderDebugLines", renderDebugLines); + registerCFunction("renderDebugTexts", renderDebugTexts); + registerCFunction("cullFaces", cullFaces); + registerCFunction("bindFramebuffer", bindFramebuffer); + registerCFunction("unbindFramebuffer", unbindFramebuffer); } virtual void loaded(FS::IFile* file, bool success, FS::FileSystem& fs) override { + if (m_lua_state) + { + lua_close(m_lua_state); + m_lua_state = nullptr; + } if(success) { - JsonSerializer serializer(*file, JsonSerializer::READ, m_path.c_str(), m_allocator); - deserialize(serializer); + m_lua_state = luaL_newstate(); + bool errors = luaL_loadbuffer(m_lua_state, (const char*)file->getBuffer(), file->size(), "") != LUA_OK; + errors = errors || lua_pcall(m_lua_state, 0, LUA_MULTRET, 0) != LUA_OK; + if (errors) + { + g_log_error.log("lua") << getPath().c_str() << ": " << lua_tostring(m_lua_state, -1); + onFailure(); + } + else + { + parseFramebuffers(m_lua_state); + } + + registerCFunctions(); + decrementDepCount(); } else @@ -409,9 +217,8 @@ struct PipelineImpl : public Pipeline fs.close(file); } + lua_State* m_lua_state; IAllocator& m_allocator; - Array m_commands; - Array m_command_creators; Array m_framebuffers; }; @@ -1141,15 +948,23 @@ struct PipelineInstanceImpl : public PipelineInstance virtual void render() override { PROFILE_FUNCTION(); + + if (!m_source.isReady()) + { + return; + } m_draw_calls_count = 0; m_vertices_count = 0; - if (m_scene) + + if (lua_getglobal(m_source.m_lua_state, "render") == LUA_TFUNCTION) { - for (int i = 0; i < m_source.m_commands.size(); ++i) + lua_pushlightuserdata(m_source.m_lua_state, this); + if (lua_pcall(m_source.m_lua_state, 1, 0, 0) != LUA_OK) { - m_source.m_commands[i]->execute(*this); + g_log_error.log("lua") << lua_tostring(m_source.m_lua_state, -1); } } + m_global_textures.clear(); m_frame_allocator.clear(); } @@ -1230,267 +1045,6 @@ void PipelineInstance::destroy(PipelineInstance* pipeline) } -void CullFaceCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - char tmp[20]; - serializer.deserializeArrayItem(tmp, sizeof(tmp), ""); - m_is_front = strcmp(tmp, "front") == 0; -} - - -void CullFaceCommand::execute(PipelineInstanceImpl&) -{ - glEnable(GL_CULL_FACE); - glCullFace(m_is_front ? GL_FRONT : GL_BACK); -} - - -void PolygonModeCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - serializer.deserializeArrayItem(m_fill, true); -} - - -void PolygonModeCommand::execute(PipelineInstanceImpl& pipeline) -{ - glPolygonMode(GL_FRONT_AND_BACK, m_fill && !pipeline.getRenderer().isEditorWireframe() ? GL_FILL : GL_LINE); -} - - -void SetPassCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - char pass_name[50]; - serializer.deserializeArrayItem(pass_name, sizeof(pass_name), ""); - m_pass_hash = crc32(pass_name); -} - - -void SetPassCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.getRenderer().setPass(m_pass_hash); -} - - -void ClearCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - char tmp[256]; - serializer.deserializeArrayItem(tmp, 255, "all"); - if (strcmp(tmp, "all") == 0) - { - m_buffers = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; - } - else if (strcmp(tmp, "depth") == 0) - { - m_buffers = GL_DEPTH_BUFFER_BIT; - } -} - - -void ClearCommand::execute(PipelineInstanceImpl&) -{ - glClear(m_buffers); -} - - -void CustomCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - char tmp[256]; - serializer.deserializeArrayItem(tmp, 255, ""); - m_name = crc32(tmp); -} - - -void CustomCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.executeCustomCommand(m_name); -} - - -void DeferredPointLightLoopCommand::deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) -{ - char material_path[LUMIX_MAX_PATH]; - serializer.deserializeArrayItem(material_path, LUMIX_MAX_PATH, ""); - m_material = static_cast(pipeline.getResourceManager().get(ResourceManager::MATERIAL)->load(Path(material_path))); -} - - -void DeferredPointLightLoopCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.deferredPointLightLoop(m_material); -} - - -void RenderModelsCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - serializer.deserializeArrayItem(m_layer_mask, 0); - serializer.deserializeArrayItem(m_point_light_influenced_geometry, false); -} - - -void RenderModelsCommand::execute(PipelineInstanceImpl& pipeline) -{ - if (m_point_light_influenced_geometry) - { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - - pipeline.renderPointLightInfluencedGeometry(pipeline.getScene()->getFrustum(), m_layer_mask); - - glDisable(GL_BLEND); - } - else - { - pipeline.renderModels(pipeline.getScene()->getFrustum(), m_layer_mask, false); - } -} - - -void ApplyCameraCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - serializer.deserializeArrayItem(m_camera_slot, "main"); -} - - -void ApplyCameraCommand::execute(PipelineInstanceImpl& pipeline) -{ - ASSERT(pipeline.m_renderer != NULL); - Component cmp = pipeline.m_scene->getCameraInSlot(m_camera_slot.c_str()); - pipeline.setActiveCamera(cmp); - if (cmp.isValid()) - { - if (pipeline.m_framebuffer_width > 0) - { - pipeline.getRenderer().setViewport((float)pipeline.m_framebuffer_width, (float)pipeline.m_framebuffer_height); - } - else - { - pipeline.getRenderer().setViewport((float)pipeline.m_width, (float)pipeline.m_height); - } - - pipeline.m_scene->setCameraSize(cmp, pipeline.m_width, pipeline.m_height); - pipeline.m_scene->applyCamera(cmp); - } -} - - -void BindFramebufferCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - serializer.deserializeArrayItem(m_buffer_name, ""); -} - - -void BindFramebufferCommand::execute(PipelineInstanceImpl& pipeline) -{ - FrameBuffer* fb = pipeline.getFrameBuffer(m_buffer_name.c_str()); - if (fb) - { - fb->bind(); - pipeline.m_framebuffer_width = fb->getWidth(); - pipeline.m_framebuffer_height = fb->getHeight(); - } -} - - -void UnbindFramebufferCommand::execute(PipelineInstanceImpl& pipeline) -{ - FrameBuffer::unbind(); - pipeline.m_framebuffer_width = pipeline.m_framebuffer_height = -1; -} - - -void RenderDebugLinesCommand::deserialize(PipelineImpl&, JsonSerializer&) -{ -} - - -void RenderDebugLinesCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.renderDebugLines(); -} - - -void RenderDebugTextsCommand::deserialize(PipelineImpl&, JsonSerializer&) -{ -} - - -void RenderDebugTextsCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.renderDebugTexts(); -} - - -DrawScreenQuadCommand::~DrawScreenQuadCommand() -{ - m_allocator.deleteObject(m_geometry); - m_allocator.deleteObject(m_mesh); -} - - -void DrawScreenQuadCommand::deserialize(PipelineImpl& pipeline, JsonSerializer& serializer) -{ - m_geometry = m_allocator.newObject(); - VertexDef def; - Renderer& renderer = pipeline.getRenderer(); - def.addAttribute(renderer, "in_position", VertexAttributeDef::FLOAT2); - def.addAttribute(renderer, "in_tex_coords", VertexAttributeDef::FLOAT2); - int indices[6] = { 0, 1, 2, 0, 2, 3 }; - const int GEOMETRY_VERTEX_ATTRIBUTE_COUNT = 16; - float v[GEOMETRY_VERTEX_ATTRIBUTE_COUNT]; - - for (int i = 0; i < GEOMETRY_VERTEX_ATTRIBUTE_COUNT; ++i) - { - serializer.deserializeArrayItem(v[i], 0); - } - - m_geometry->setAttributesData(v, sizeof(v)); - m_geometry->setIndicesData(indices, sizeof(indices)); - - char material_path[LUMIX_MAX_PATH]; - serializer.deserializeArrayItem(material_path, LUMIX_MAX_PATH, ""); - Material* material = static_cast(pipeline.getResourceManager().get(ResourceManager::MATERIAL)->load(Path(material_path))); - m_mesh = m_allocator.newObject(def, material, 0, 0, sizeof(v), 6, "screen_quad", m_allocator); -} - - -void DrawScreenQuadCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.getRenderer().setViewport((float)pipeline.m_width, (float)pipeline.m_height); - pipeline.renderScreenGeometry(m_geometry, m_mesh); -} - - -void BindFramebufferTextureCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - serializer.deserializeArrayItem(m_framebuffer_name, sizeof(m_framebuffer_name), ""); - serializer.deserializeArrayItem(m_renderbuffer_index, 0); - serializer.deserializeArrayItem(m_uniform, sizeof(m_uniform), ""); -} - - -void BindFramebufferTextureCommand::execute(PipelineInstanceImpl& pipeline) -{ - FrameBuffer* fb = pipeline.getFrameBuffer(m_framebuffer_name); - if (fb) - { - pipeline.addGlobalTexture(fb->getTexture(m_renderbuffer_index), m_uniform); - } -} - - -void RenderShadowmapCommand::deserialize(PipelineImpl&, JsonSerializer& serializer) -{ - serializer.deserializeArrayItem(m_layer_mask, 0); - serializer.deserializeArrayItem(m_camera_slot, 0); -} - - -void RenderShadowmapCommand::execute(PipelineInstanceImpl& pipeline) -{ - pipeline.renderShadowmap(pipeline.getScene()->getCameraInSlot(m_camera_slot.c_str()), m_layer_mask); -} - - Resource* PipelineManager::createResource(const Path& path) { return m_allocator.newObject(path, getOwner(), m_allocator); @@ -1503,4 +1057,232 @@ void PipelineManager::destroyResource(Resource& resource) } +static int setPass(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + const char* pass = lua_tostring(L, 2); + pipeline->getRenderer().setPass(crc32(pass)); + return 0; +} + + +static int applyCamera(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + const char* slot = lua_tostring(L, 2); + Component cmp = pipeline->m_scene->getCameraInSlot(slot); + pipeline->setActiveCamera(cmp); + if (cmp.isValid()) + { + if (pipeline->m_framebuffer_width > 0) + { + pipeline->getRenderer().setViewport((float)pipeline->m_framebuffer_width, (float)pipeline->m_framebuffer_height); + } + else + { + pipeline->getRenderer().setViewport((float)pipeline->m_width, (float)pipeline->m_height); + } + + pipeline->m_scene->setCameraSize(cmp, pipeline->m_width, pipeline->m_height); + pipeline->m_scene->applyCamera(cmp); + } + return 0; +} + + +static int polygonMode(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + bool fill = lua_toboolean(L, 2) != 0; + glPolygonMode(GL_FRONT_AND_BACK, fill && !pipeline->getRenderer().isEditorWireframe() ? GL_FILL : GL_LINE); + return 0; +} + + +static int clear(lua_State* L) +{ + const char* buffers = lua_tostring(L, 1); + if (strcmp(buffers, "all") == 0) + { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + else if (strcmp(buffers, "depth") == 0) + { + glClear(GL_DEPTH_BUFFER_BIT); + } + return 0; +} + + +static int renderModels(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + + int64_t layer_mask = lua_tointeger(L, 2); + bool is_point_light_render = lua_toboolean(L, 3) != 0; + if (is_point_light_render) + { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + + pipeline->renderPointLightInfluencedGeometry(pipeline->getScene()->getFrustum(), layer_mask); + + glDisable(GL_BLEND); + } + else + { + pipeline->renderModels(pipeline->getScene()->getFrustum(), layer_mask, false); + } + + + return 0; +} + + +static int bindFramebufferTexture(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + + const char* framebuffer_name = lua_tostring(L, 2); + int renderbuffer_index = (int)lua_tointeger(L, 3); + const char* uniform = lua_tostring(L, 4); + + FrameBuffer* fb = pipeline->getFrameBuffer(framebuffer_name); + if (fb) + { + pipeline->addGlobalTexture(fb->getTexture(renderbuffer_index), uniform); + } + + return 0; +} + + +static int executeCustomCommand(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + + const char* command = lua_tostring(L, 2); + pipeline->executeCustomCommand(crc32(command)); + + return 0; +} + + +static int renderDebugLines(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + pipeline->renderDebugLines(); + + return 0; +} + + +static int cullFaces(lua_State* L) +{ + glEnable(GL_CULL_FACE); + if (strcmp(lua_tostring(L, 1), "front") == 0) + { + glCullFace(GL_FRONT); + } + else + { + glCullFace(GL_BACK); + } + return 0; +} + + +static int renderDebugTexts(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + pipeline->renderDebugTexts(); + + return 0; +} + + +static int renderShadowmap(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + + int64_t layer_mask = lua_tointeger(L, 2); + const char* slot = lua_tostring(L, 3); + + pipeline->renderShadowmap(pipeline->getScene()->getCameraInSlot(slot), layer_mask); + + return 0; +} + + +static int bindFramebuffer(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + + const char* buffer_name = lua_tostring(L, 2); + FrameBuffer* fb = pipeline->getFrameBuffer(buffer_name); + if (fb) + { + fb->bind(); + pipeline->m_framebuffer_width = fb->getWidth(); + pipeline->m_framebuffer_height = fb->getHeight(); + } + + return 0; +} + + +static int unbindFramebuffer(lua_State* L) +{ + PipelineInstanceImpl* pipeline = (PipelineInstanceImpl*)lua_touserdata(L, 1); + if (!pipeline) + { + return 0; + } + + FrameBuffer::unbind(); + pipeline->m_framebuffer_width = pipeline->m_framebuffer_height = -1; + return 0; +} + + } // ~namespace Lumix diff --git a/src/graphics/pipeline.h b/src/graphics/pipeline.h index 955f425c9..453289d74 100644 --- a/src/graphics/pipeline.h +++ b/src/graphics/pipeline.h @@ -51,8 +51,6 @@ class LUMIX_ENGINE_API Pipeline : public Resource Pipeline(const Path& path, ResourceManager& resource_manager, IAllocator& allocator); virtual ~Pipeline() {} - virtual bool deserialize(JsonSerializer& serializer) = 0; - static Pipeline* create(Renderer& renderer); static void destroy(Pipeline* pipeline); }; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 6ca0e0b37..32943ba7d 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -247,13 +247,10 @@ void Shader::loaded(FS::IFile* file, bool success, FS::FileSystem& fs) { if(success) { - ShaderManager* manager = static_cast(getResourceManager().get(ResourceManager::SHADER)); - char* text = reinterpret_cast(manager->getBuffer(file->size() + 1)); - lua_State* L = luaL_newstate(); - memcpy(text, file->getBuffer(), file->size()); - text[file->size()] = 0; - bool errors = luaL_dostring(L, text); + + bool errors = luaL_loadbuffer(L, (const char*)file->getBuffer(), file->size(), "") != LUA_OK; + errors = errors || lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK; if (errors) { g_log_error.log("lua") << getPath().c_str() << ": " << lua_tostring(L, -1);