pipelines use lua
This commit is contained in:
parent
4ed1561443
commit
8a40ad9c4c
5 changed files with 360 additions and 587 deletions
|
@ -2,6 +2,8 @@
|
|||
#include "core/json_serializer.h"
|
||||
#include "core/vec3.h"
|
||||
#include "graphics/gl_ext.h"
|
||||
#include <lua.hpp>
|
||||
#include <lauxlib.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "graphics/shader.h"
|
||||
#include "graphics/terrain.h"
|
||||
#include "graphics/texture.h"
|
||||
#include <lua.hpp>
|
||||
#include <lauxlib.h>
|
||||
|
||||
|
||||
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<Command* (IAllocator&)> Creator;
|
||||
Creator m_creator;
|
||||
uint32_t m_type_hash;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static Command* CreateCommand(IAllocator& allocator)
|
||||
{
|
||||
return allocator.newObject<T>(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<ClearCommand> >();
|
||||
addCommandCreator("custom").bind<&CreateCommand<CustomCommand> >();
|
||||
addCommandCreator("render_models").bind<&CreateCommand<RenderModelsCommand> >();
|
||||
addCommandCreator("apply_camera").bind<&CreateCommand<ApplyCameraCommand> >();
|
||||
addCommandCreator("bind_framebuffer").bind<&CreateCommand<BindFramebufferCommand> >();
|
||||
addCommandCreator("unbind_framebuffer").bind<&CreateCommand<UnbindFramebufferCommand> >();
|
||||
addCommandCreator("draw_screen_quad").bind<&CreateCommand<DrawScreenQuadCommand> >();
|
||||
addCommandCreator("bind_framebuffer_texture").bind<&CreateCommand<BindFramebufferTextureCommand> >();
|
||||
addCommandCreator("render_shadowmap").bind<&CreateCommand<RenderShadowmapCommand> >();
|
||||
addCommandCreator("render_debug_lines").bind<&CreateCommand<RenderDebugLinesCommand> >();
|
||||
addCommandCreator("render_debug_texts").bind<&CreateCommand<RenderDebugTextsCommand> >();
|
||||
addCommandCreator("polygon_mode").bind<&CreateCommand<PolygonModeCommand> >();
|
||||
addCommandCreator("cull_face").bind<&CreateCommand<CullFaceCommand> >();
|
||||
addCommandCreator("set_pass").bind<&CreateCommand<SetPassCommand> >();
|
||||
addCommandCreator("deferred_point_light_loop").bind<&CreateCommand<DeferredPointLightLoopCommand> >();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Command*> m_commands;
|
||||
Array<CommandCreator> m_command_creators;
|
||||
Array<FrameBuffer::Declaration> 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<Material*>(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<Geometry>();
|
||||
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<Material*>(pipeline.getResourceManager().get(ResourceManager::MATERIAL)->load(Path(material_path)));
|
||||
m_mesh = m_allocator.newObject<Mesh>(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<PipelineImpl>(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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -247,13 +247,10 @@ void Shader::loaded(FS::IFile* file, bool success, FS::FileSystem& fs)
|
|||
{
|
||||
if(success)
|
||||
{
|
||||
ShaderManager* manager = static_cast<ShaderManager*>(getResourceManager().get(ResourceManager::SHADER));
|
||||
char* text = reinterpret_cast<char*>(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);
|
||||
|
|
Loading…
Reference in a new issue