@@ -0,0 +1,28 @@ | |||||
{ | |||||
"configurations": [ | |||||
{ | |||||
"name": "Mac", | |||||
"includePath": ["/usr/include"], | |||||
"browse" : { | |||||
"limitSymbolsToIncludedHeaders" : true, | |||||
"databaseFilename" : "" | |||||
} | |||||
}, | |||||
{ | |||||
"name": "Linux", | |||||
"includePath": ["/usr/include"], | |||||
"browse" : { | |||||
"limitSymbolsToIncludedHeaders" : true, | |||||
"databaseFilename" : "" | |||||
} | |||||
}, | |||||
{ | |||||
"name": "Win32", | |||||
"includePath": ["c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", "src"], | |||||
"browse" : { | |||||
"limitSymbolsToIncludedHeaders" : true, | |||||
"databaseFilename" : "" | |||||
} | |||||
} | |||||
] | |||||
} |
@@ -66,6 +66,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B629 | |||||
EndProject | EndProject | ||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "15_lolimgui", "..\doc\tutorial\15_lolimgui.vcxproj", "{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}" | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "15_lolimgui", "..\doc\tutorial\15_lolimgui.vcxproj", "{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}" | ||||
EndProject | EndProject | ||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "14_lol_lua", "..\doc\tutorial\14_lol_lua.vcxproj", "{31B96262-1C41-43B9-BA38-27AA385B05DB}" | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|ORBIS = Debug|ORBIS | Debug|ORBIS = Debug|ORBIS | ||||
@@ -308,6 +310,18 @@ Global | |||||
{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|Win32.Build.0 = Release|Win32 | {81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|Win32.Build.0 = Release|Win32 | ||||
{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.ActiveCfg = Release|x64 | {81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.ActiveCfg = Release|x64 | ||||
{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.Build.0 = Release|x64 | {81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.Build.0 = Release|x64 | ||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|ORBIS.ActiveCfg = Debug|ORBIS | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|ORBIS.Build.0 = Debug|ORBIS | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|Win32.ActiveCfg = Debug|Win32 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|Win32.Build.0 = Debug|Win32 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|x64.ActiveCfg = Debug|x64 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|x64.Build.0 = Debug|x64 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|ORBIS.ActiveCfg = Release|ORBIS | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|ORBIS.Build.0 = Release|ORBIS | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|Win32.ActiveCfg = Release|Win32 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|Win32.Build.0 = Release|Win32 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|x64.ActiveCfg = Release|x64 | |||||
{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|x64.Build.0 = Release|x64 | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -341,5 +355,6 @@ Global | |||||
{73F1A804-1116-46C3-922A-9C0ADEB33F52} = {4C4BD478-3767-4C27-BD91-DAAFE7CD03A2} | {73F1A804-1116-46C3-922A-9C0ADEB33F52} = {4C4BD478-3767-4C27-BD91-DAAFE7CD03A2} | ||||
{B6297FF2-63D0-41EE-BE13-EFF720C9B0FA} = {1AFD580B-98B8-4689-B661-38C41132C60E} | {B6297FF2-63D0-41EE-BE13-EFF720C9B0FA} = {1AFD580B-98B8-4689-B661-38C41132C60E} | ||||
{81C83B42-D00A-4FA3-9A3D-80F9D46524BF} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} | {81C83B42-D00A-4FA3-9A3D-80F9D46524BF} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} | ||||
{31B96262-1C41-43B9-BA38-27AA385B05DB} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} | |||||
EndGlobalSection | EndGlobalSection | ||||
EndGlobal | EndGlobal |
@@ -414,7 +414,7 @@ void BtPhysTest::TickGame(float seconds) | |||||
return; | return; | ||||
} | } | ||||
Debug::DrawSetupSegment(1.f); | |||||
auto context = Debug::DrawContext::New(Color::white, 1.f); | |||||
Debug::DrawGrid(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | Debug::DrawGrid(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | ||||
if (m_controller->WasKeyReleasedThisFrame(BtPhysTestKeyInput::KEY_QUIT)) | if (m_controller->WasKeyReleasedThisFrame(BtPhysTestKeyInput::KEY_QUIT)) | ||||
@@ -0,0 +1,10 @@ | |||||
[Debug] | |||||
Pos=60,60 | |||||
Size=400,400 | |||||
Collapsed=0 | |||||
[Camera Setup] | |||||
Pos=60,60 | |||||
Size=307,314 | |||||
Collapsed=0 | |||||
@@ -384,8 +384,7 @@ void MeshViewer::TickDraw(float seconds, Scene &scene) | |||||
//Draw gizmos & grid | //Draw gizmos & grid | ||||
Debug::DrawGizmo(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | Debug::DrawGizmo(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | ||||
Debug::DrawSetupColor(Color::white); | |||||
Debug::DrawSetupSegment(1.f); | |||||
auto context = Debug::DrawContext::New(Color::white); | |||||
Debug::DrawGrid(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | Debug::DrawGrid(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f); | ||||
/** OLD STUFF **/ | /** OLD STUFF **/ | ||||
@@ -159,93 +159,83 @@ SceneSetupLuaObject::~SceneSetupLuaObject() | |||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
SceneSetupLuaObject* SceneSetupLuaObject::New(lua_State* l, int arg_nb) | SceneSetupLuaObject* SceneSetupLuaObject::New(lua_State* l, int arg_nb) | ||||
{ | { | ||||
UNUSED(l); | |||||
UNUSED(arg_nb); | UNUSED(arg_nb); | ||||
LuaStack s(l); | |||||
LuaString n; | |||||
s >> n; | |||||
return new SceneSetupLuaObject(n()); | |||||
auto s = LuaStack::Begin(l); | |||||
auto n = s.Get<String>(); | |||||
return new SceneSetupLuaObject(n); | |||||
} | } | ||||
//-- Setup command ------------------------------------------------------------ | //-- Setup command ------------------------------------------------------------ | ||||
int SceneSetupLuaObject::AddLight(lua_State* l) | int SceneSetupLuaObject::AddLight(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaString t; | |||||
s >> o >> t; | |||||
o->m_setup->AddLight(FindValue<LightType>(t().C())); | |||||
return 0; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto t = s.Get<String>(); | |||||
o->m_setup->AddLight(FindValue<LightType>(t.C())); | |||||
return s.End(); | |||||
} | } | ||||
int SceneSetupLuaObject::SetupScene(lua_State* l) | int SceneSetupLuaObject::SetupScene(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
s >> o; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
o->m_setup->SetupScene(); | o->m_setup->SetupScene(); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
//-- main funcs --------------------------------------------------------------- | //-- main funcs --------------------------------------------------------------- | ||||
int SceneSetupLuaObject::SetPosition(lua_State* l) | int SceneSetupLuaObject::SetPosition(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaVec3 c; | |||||
s >> o >> c; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto c = s.Get<vec3>(); | |||||
o->m_setup->SetPosition(c); | o->m_setup->SetPosition(c); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
int SceneSetupLuaObject::SetLookAt(lua_State* l) | int SceneSetupLuaObject::SetLookAt(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaVec3 c; | |||||
s >> o >> c; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto c = s.Get<vec3>(); | |||||
o->m_setup->SetLookAt(c); | o->m_setup->SetLookAt(c); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
int SceneSetupLuaObject::SetColor(lua_State* l) | int SceneSetupLuaObject::SetColor(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaColor c; | |||||
s >> o >> c; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto c = s.Get<vec4>(); | |||||
o->m_setup->SetColor(c); | o->m_setup->SetColor(c); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
int SceneSetupLuaObject::Show(lua_State* l) | int SceneSetupLuaObject::Show(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaDisplay e; | |||||
s >> o >> e; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto e = s.GetEnum<SceneSetup::DisplayBase>(); | |||||
o->m_setup->Show(e); | o->m_setup->Show(e); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
int SceneSetupLuaObject::Hide(lua_State* l) | int SceneSetupLuaObject::Hide(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaDisplay e; | |||||
s >> o >> e; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto e = s.GetEnum<SceneSetup::DisplayBase>(); | |||||
o->m_setup->Hide(e); | o->m_setup->Hide(e); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
int SceneSetupLuaObject::Toggle(lua_State* l) | int SceneSetupLuaObject::Toggle(lua_State* l) | ||||
{ | { | ||||
LuaStack s(l); | |||||
LuaSSetupPtr o; | |||||
LuaDisplay e; | |||||
s >> o >> e; | |||||
auto s = LuaStack::Begin(l); | |||||
auto o = s.GetPtr<SceneSetupLuaObject>(); | |||||
auto e = s.GetEnum<SceneSetup::DisplayBase>(); | |||||
o->m_setup->Toggle(e); | o->m_setup->Toggle(e); | ||||
return 0; | |||||
return s.End(); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
const LuaObjectLib* SceneSetupLuaObject::GetLib() | |||||
const LuaObjectLibrary* SceneSetupLuaObject::GetLib() | |||||
{ | { | ||||
typedef SceneSetupLuaObject SSLO; | typedef SceneSetupLuaObject SSLO; | ||||
static const LuaObjectLib lib = LuaObjectLib( | |||||
static const LuaObjectLibrary lib = LuaObjectLibrary( | |||||
"SceneSetup", | "SceneSetup", | ||||
//Statics | //Statics | ||||
{ { nullptr, nullptr } }, | { { nullptr, nullptr } }, | ||||
@@ -264,7 +254,7 @@ const LuaObjectLib* SceneSetupLuaObject::GetLib() | |||||
}, | }, | ||||
//Variables | //Variables | ||||
{ { nullptr, nullptr, nullptr } }); | { { nullptr, nullptr, nullptr } }); | ||||
return &lib; | |||||
return &lib; | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -273,7 +263,7 @@ SceneSetupLuaLoader::SceneSetupLuaLoader() : LuaLoader() | |||||
{ | { | ||||
lua_State* l = GetLuaState(); | lua_State* l = GetLuaState(); | ||||
LuaObjectDef::Register<SceneSetupLuaObject>(l); | |||||
LuaObjectHelper::Register<SceneSetupLuaObject>(l); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -103,12 +103,10 @@ public: | |||||
bool m_show_gizmo; | bool m_show_gizmo; | ||||
bool m_show_lights; | bool m_show_lights; | ||||
}; | }; | ||||
typedef Lolua::VarEnum<SceneSetup::DisplayBase> LuaDisplay; | |||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
class SceneSetupLuaObject : public LuaObject | class SceneSetupLuaObject : public LuaObject | ||||
{ | { | ||||
typedef Lolua::VarPtr<SceneSetupLuaObject> LuaSSetupPtr; | |||||
public: | public: | ||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
SceneSetupLuaObject(String& name); | SceneSetupLuaObject(String& name); | ||||
@@ -116,7 +114,7 @@ public: | |||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
static SceneSetupLuaObject* New(lua_State* l, int arg_nb); | static SceneSetupLuaObject* New(lua_State* l, int arg_nb); | ||||
static const LuaObjectLib* GetLib(); | |||||
static const LuaObjectLibrary* GetLib(); | |||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
public: | public: | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine — Simplex Noise tutorial | // Lol Engine — Simplex Noise tutorial | ||||
// | // | ||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// © 2013-2014 Guillaume Bittoun <guillaume.bittoun@gmail.com> | // © 2013-2014 Guillaume Bittoun <guillaume.bittoun@gmail.com> | ||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
@@ -31,8 +31,8 @@ int main(int argc, char **argv) | |||||
srand(time(nullptr)); | srand(time(nullptr)); | ||||
/* Create an image */ | /* Create an image */ | ||||
Image img(size); | |||||
array2d<vec4> &data = img.Lock2D<PixelFormat::RGBA_F32>(); | |||||
image img(size); | |||||
array2d<vec4> &data = img.lock2d<PixelFormat::RGBA_F32>(); | |||||
/* Declare plenty of allocators */ | /* Declare plenty of allocators */ | ||||
simplex_noise<2> s2; | simplex_noise<2> s2; | ||||
@@ -141,7 +141,7 @@ int main(int argc, char **argv) | |||||
#endif | #endif | ||||
/* Save image */ | /* Save image */ | ||||
img.Unlock2D(data); | |||||
img.Save("simplex.png"); | |||||
img.unlock2d(data); | |||||
img.save("simplex.png"); | |||||
} | } | ||||
@@ -44,6 +44,22 @@ public: | |||||
4, 5, 1, 1, 0, 4, 3, 2, 6, 6, 7, 3, }), | 4, 5, 1, 1, 0, 4, 3, 2, 6, 6, 7, 3, }), | ||||
m_ready(false) | m_ready(false) | ||||
{ | { | ||||
m_camera = new Camera(); | |||||
m_camera->SetProjection(mat4::perspective(radians(30.f), 960.f, 600.f, .1f, 1000.f)); | |||||
m_camera->SetView(mat4::lookat(vec3(-15.f, 5.f, 0.f), | |||||
vec3(0.f, -1.f, 0.f), | |||||
vec3(0.f, 1.f, 0.f))); | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.PushCamera(m_camera); | |||||
Ticker::Ref(m_camera); | |||||
} | |||||
~Cube() | |||||
{ | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.PopCamera(m_camera); | |||||
Ticker::Unref(m_camera); | |||||
} | } | ||||
virtual void TickGame(float seconds) | virtual void TickGame(float seconds) | ||||
@@ -58,6 +74,25 @@ public: | |||||
mat4 proj = mat4::perspective(radians(45.0f), 640.0f, 480.0f, 0.1f, 10.0f); | mat4 proj = mat4::perspective(radians(45.0f), 640.0f, 480.0f, 0.1f, 10.0f); | ||||
m_matrix = proj * view * model * anim; | m_matrix = proj * view * model * anim; | ||||
{ | |||||
auto context0 = Debug::DrawContext::New(Color::red); | |||||
{ | |||||
auto context1 = Debug::DrawContext::New(Color::blue); | |||||
Debug::DrawBox(box3(vec3(0.f), vec3(1.2f))); | |||||
Debug::DrawGrid(vec3(0.f), vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.0f); | |||||
{ | |||||
auto context2 = Debug::DrawContext::New(context0); | |||||
Debug::DrawBox(box3(vec3(0.f), vec3(1.3f))); | |||||
} | |||||
{ | |||||
auto context2 = Debug::DrawContext::New(context0); | |||||
context2.SetColor(Color::yellow); | |||||
Debug::DrawBox(box3(vec3(-1.f), vec3(1.4f))); | |||||
} | |||||
} | |||||
Debug::DrawBox(box3(vec3(0.f), vec3(1.1f))); | |||||
} | |||||
} | } | ||||
virtual void TickDraw(float seconds, Scene &scene) | virtual void TickDraw(float seconds, Scene &scene) | ||||
@@ -115,6 +150,7 @@ public: | |||||
} | } | ||||
private: | private: | ||||
Camera* m_camera = nullptr; | |||||
float m_angle; | float m_angle; | ||||
mat4 m_matrix; | mat4 m_matrix; | ||||
array<vec3,vec3> m_mesh; | array<vec3,vec3> m_mesh; | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine — Lua tutorial | // Lol Engine — Lua tutorial | ||||
// | // | ||||
// Copyright © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||||
// Copyright © 2014—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -23,7 +23,6 @@ using namespace lol; | |||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
class DemoObject : public LuaObject | class DemoObject : public LuaObject | ||||
{ | { | ||||
typedef Lolua::VarPtr<DemoObject> LuaDemoObjectPtr; | |||||
public: | public: | ||||
DemoObject() : LuaObject() {} | DemoObject() : LuaObject() {} | ||||
virtual ~DemoObject() {} | virtual ~DemoObject() {} | ||||
@@ -37,47 +36,67 @@ public: | |||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
static int AddFive(lua_State* l) | static int AddFive(lua_State* l) | ||||
{ | { | ||||
LuaInt32 i; i.Get(l, 1); | |||||
auto stack = LuaStack::Begin(l); | |||||
int32_t i = stack.Get<int32_t>(); | |||||
i += 5; | i += 5; | ||||
return i.Return(l); | |||||
return (stack << i).End(); | |||||
} | } | ||||
static int AddTenInstance(lua_State* l) | |||||
LOLUA_DECLARE_RETURN_METHOD_ARGS(AddTenInstance, GetPtr<DemoObject>(), AddTenMethod, Get<float>(), Get<int32_t>(), Get<int32_t>()); | |||||
static int _AddTenInstance(lua_State* l) | |||||
{ | { | ||||
LuaStack stack(l); | |||||
LuaDemoObjectPtr obj; | |||||
LuaFloat f; | |||||
stack >> obj >> f; | |||||
f = obj->AddTenMethod(f); | |||||
return f.Return(l); | |||||
auto stack = LuaStack::Begin(l); | |||||
DemoObject* obj = stack.GetPtr<DemoObject>(); | |||||
float f = stack.Get<float>(); | |||||
int32_t i = stack.Get<int32_t>(); | |||||
int32_t i2 = stack.Get<int32_t>(); | |||||
f = obj->AddTenMethod(f, i, i2); | |||||
return (stack << f).End(); | |||||
} | } | ||||
float AddTenMethod(float f) | |||||
float AddTenMethod(float f, int32_t i, int32_t i2) | |||||
{ | { | ||||
UNUSED(i, i2); | |||||
return (f + 10); | return (f + 10); | ||||
} | } | ||||
static int GetX(lua_State* l) | static int GetX(lua_State* l) | ||||
{ | { | ||||
LuaStack stack(l); | |||||
LuaDemoObjectPtr obj; | |||||
LuaInt32 i; | |||||
stack >> obj; | |||||
auto stack = LuaStack::Begin(l); | |||||
DemoObject* obj = stack.GetPtr<DemoObject>(); | |||||
auto i = stack.Get<int32_t>(); | |||||
i = obj->m_x; | i = obj->m_x; | ||||
return stack << i; | |||||
return (stack << i).End(); | |||||
} | } | ||||
static int SetX(lua_State* l) | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(SetX, GetPtr<DemoObject>(), SetXMethod, Get<int32_t>()); | |||||
static int _SetX(lua_State* l) | |||||
{ | { | ||||
LuaStack stack(l); | |||||
LuaDemoObjectPtr obj; | |||||
LuaInt32 i; | |||||
stack >> obj >> i; | |||||
auto stack = LuaStack::Begin(l); | |||||
DemoObject* obj = stack.GetPtr<DemoObject>(); | |||||
auto i = stack.Get<int32_t>(); | |||||
obj->m_x = i; | obj->m_x = i; | ||||
return 0; | |||||
return stack.End(); | |||||
} | |||||
void SetXMethod(int32_t i) | |||||
{ | |||||
m_x = i; | |||||
} | } | ||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
static const LuaObjectLib* GetLib() | |||||
static const LuaObjectLibrary* GetLib() | |||||
{ | { | ||||
static const LuaObjectLib lib = LuaObjectLib( | |||||
static const LuaObjectLibrary lib = LuaObjectLibrary( | |||||
"LoluaDemo", | "LoluaDemo", | ||||
{ { "AddFive", &DemoObject::AddFive } }, | { { "AddFive", &DemoObject::AddFive } }, | ||||
{ { "AddTenInstance", &DemoObject::AddTenInstance } }, | { { "AddTenInstance", &DemoObject::AddTenInstance } }, | ||||
@@ -91,9 +110,12 @@ public: | |||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
static int GlobalAddString(lua_State* l) | static int GlobalAddString(lua_State* l) | ||||
{ | { | ||||
LuaString s; s.Get(l, 1); | |||||
s() += "_added"; | |||||
return s.Return(l); | |||||
auto stack = LuaStack::Begin(l); | |||||
auto s = stack.Get<String>(); | |||||
s += "_added"; | |||||
return (stack << s).End(); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -105,7 +127,7 @@ public: | |||||
lua_State* l = GetLuaState(); | lua_State* l = GetLuaState(); | ||||
//Registering demo object | //Registering demo object | ||||
LuaObjectDef::Register<DemoObject>(l); | |||||
LuaObjectHelper::Register<DemoObject>(l); | |||||
//Registering function | //Registering function | ||||
LuaFunction add_string(l, "GlobalAddString", &GlobalAddString); | LuaFunction add_string(l, "GlobalAddString", &GlobalAddString); | ||||
@@ -158,27 +180,33 @@ public: | |||||
demo_loader->TestStuff(); | demo_loader->TestStuff(); | ||||
//Grab global test values | //Grab global test values | ||||
float testvalue_num = demo_loader->GetVar<float>("testvalue_num"); | |||||
int32_t testvalue_int = demo_loader->GetVar<int32_t>("testvalue_int"); | |||||
uint32_t testvalue_uint = demo_loader->GetVar<uint32_t>("testvalue_uint"); | |||||
String testvalue_str = demo_loader->GetVar<String>("testvalue_str"); | |||||
float testvalue_num = demo_loader->Get<float>("testvalue_num"); | |||||
int32_t testvalue_int = demo_loader->Get<int32_t>("testvalue_int"); | |||||
uint32_t testvalue_uint = demo_loader->Get<uint32_t>("testvalue_uint"); | |||||
String testvalue_str = demo_loader->Get<String>("testvalue_str"); | |||||
//Grab string modified with function | //Grab string modified with function | ||||
String function_return = demo_loader->GetVar<String>("function_return"); | |||||
String function_return = demo_loader->Get<String>("function_return"); | |||||
//Grab global values modified with DemoObject | //Grab global values modified with DemoObject | ||||
int32_t loluademo_return = demo_loader->GetVar<int32_t>("loluademo_return"); | |||||
int32_t loluademo_getx = demo_loader->GetVar<int32_t>("loluademo_getx"); | |||||
float loluademo_inst_return = demo_loader->GetVar<float>("loluademo_inst_return"); | |||||
int32_t loluademo_return = demo_loader->Get<int32_t>("loluademo_return"); | |||||
int32_t loluademo_getx = demo_loader->Get<int32_t>("loluademo_getx"); | |||||
float loluademo_inst_return = demo_loader->Get<float>("loluademo_inst_return"); | |||||
DemoObject* loluademo_inst = demo_loader->GetPtr<DemoObject>("loluademo_inst"); | DemoObject* loluademo_inst = demo_loader->GetPtr<DemoObject>("loluademo_inst"); | ||||
msg::info("Lua Vars: \ | msg::info("Lua Vars: \ | ||||
testvalue_num: %.2f, testvalue_int: %i, testvalue_uint: %i, testvalue_str: %s.\n", | testvalue_num: %.2f, testvalue_int: %i, testvalue_uint: %i, testvalue_str: %s.\n", | ||||
testvalue_num, testvalue_int, testvalue_uint, testvalue_str.C()); | testvalue_num, testvalue_int, testvalue_uint, testvalue_str.C()); | ||||
msg::info("Lua Vars: \ | msg::info("Lua Vars: \ | ||||
function_return: %s, loluademo_return: %i, loluademo_inst_return: %.f, loluademo_getx: %i, loluademo_inst->m_x: %i.\n", | |||||
function_return: %s, loluademo_return: %i, loluademo_inst_return: %.2f, loluademo_getx: %i, loluademo_inst->m_x: %i.\n", | |||||
function_return.C(), loluademo_return, loluademo_inst_return, loluademo_getx, loluademo_inst->m_x); | function_return.C(), loluademo_return, loluademo_inst_return, loluademo_getx, loluademo_inst->m_x); | ||||
#define /***/ _LOLUA_ARG_1(a00) (float)a00 | |||||
#define /***/ _LOLUA_ARG_2(a00, a01) _LOLUA_ARG_1(a00), _LOLUA_ARG_1(a01) | |||||
#define /***/ _LOLUA_ARG_3(a00, a01, a02) _LOLUA_ARG_1(a00), _LOLUA_ARG_2(a01, a02) | |||||
#define /***/ _LOLUA_ARG_4(a00, a01, a02, a03) _LOLUA_ARG_1(a00), _LOLUA_ARG_3(a01, a02, a03) | |||||
msg::info("_LOLUA_ARG_1: %f, %f, %f, %f\n", _LOLUA_ARG_4(0, 1, 2, 3)); | |||||
delete demo_loader; | delete demo_loader; | ||||
Ticker::Shutdown(); | Ticker::Shutdown(); | ||||
@@ -13,4 +13,4 @@ loluademo_return = LoluaDemo.AddFive(1); | |||||
loluademo_inst = LoluaDemo.New(); | loluademo_inst = LoluaDemo.New(); | ||||
loluademo_inst:SetX(10); | loluademo_inst:SetX(10); | ||||
loluademo_getx = loluademo_inst:GetX(); | loluademo_getx = loluademo_inst:GetX(); | ||||
loluademo_inst_return = loluademo_inst:AddTenInstance(2.0); | |||||
loluademo_inst_return = loluademo_inst:AddTenInstance(2.5, 4, 6); |
@@ -56,14 +56,12 @@ public: | |||||
bool open_file(char const *filename) | bool open_file(char const *filename) | ||||
{ | { | ||||
avformat_alloc_output_context2(&m_avformat, nullptr, nullptr, filename); | |||||
/* Third argument specifies format */ | |||||
avformat_alloc_output_context2(&m_avformat, nullptr, "gif", filename); | |||||
if (!m_avformat) | if (!m_avformat) | ||||
{ | { | ||||
msg::debug("could not deduce output format from file extension %s: using GIF\n", filename); | |||||
avformat_alloc_output_context2(&m_avformat, nullptr, "gif", filename); | |||||
if (!m_avformat) | |||||
return false; | |||||
msg::debug("could not create output context"); | |||||
return false; | |||||
} | } | ||||
if (!open_codec()) | if (!open_codec()) | ||||
@@ -89,7 +87,7 @@ public: | |||||
return true; | return true; | ||||
} | } | ||||
bool push_image(Image &im) | |||||
bool push_image(image &im) | |||||
{ | { | ||||
// Make sure the encoder does not hold a reference on our | // Make sure the encoder does not hold a reference on our | ||||
// frame (GIF does that in order to compress using deltas). | // frame (GIF does that in order to compress using deltas). | ||||
@@ -97,10 +95,10 @@ public: | |||||
return false; | return false; | ||||
// Convert image to 3:3:2. TODO: add some dithering | // Convert image to 3:3:2. TODO: add some dithering | ||||
u8vec3 *data = im.Lock<PixelFormat::RGB_8>(); | |||||
for (int n = 0; n < im.GetSize().x * im.GetSize().y; ++n) | |||||
u8vec3 *data = im.lock<PixelFormat::RGB_8>(); | |||||
for (int n = 0; n < im.size().x * im.size().y; ++n) | |||||
m_frame->data[0][n] = (data[n].r & 0xe0) | ((data[n].g & 0xe0) >> 3) | (data[n].b >> 6); | m_frame->data[0][n] = (data[n].r & 0xe0) | ((data[n].g & 0xe0) >> 3) | (data[n].b >> 6); | ||||
im.Unlock(data); | |||||
im.unlock(data); | |||||
m_frame->pts = m_index++; | m_frame->pts = m_index++; | ||||
@@ -234,9 +232,9 @@ int main(int argc, char **argv) | |||||
for (int i = 0; i < 256; ++i) | for (int i = 0; i < 256; ++i) | ||||
{ | { | ||||
Image im(size); | |||||
image im(size); | |||||
array2d<u8vec3> &data = im.Lock2D<PixelFormat::RGB_8>(); | |||||
array2d<u8vec3> &data = im.lock2d<PixelFormat::RGB_8>(); | |||||
for (int y = 0; y < size.y; ++y) | for (int y = 0; y < size.y; ++y) | ||||
for (int x = 0; x < size.x; ++x) | for (int x = 0; x < size.x; ++x) | ||||
{ | { | ||||
@@ -244,7 +242,7 @@ int main(int argc, char **argv) | |||||
data[x][y].g = x / 4 * 4 * y / 16 + i; | data[x][y].g = x / 4 * 4 * y / 16 + i; | ||||
data[x][y].b = y + i; | data[x][y].b = y + i; | ||||
} | } | ||||
im.Unlock2D(data); | |||||
im.unlock2d(data); | |||||
if (!enc.push_image(im)) | if (!enc.push_image(im)) | ||||
break; | break; | ||||
@@ -4,12 +4,12 @@ Size=400,400 | |||||
Collapsed=0 | Collapsed=0 | ||||
[testature] | [testature] | ||||
Pos=266,15 | |||||
Pos=187,98 | |||||
Size=494,359 | Size=494,359 | ||||
Collapsed=0 | Collapsed=0 | ||||
[SO FUN !!] | [SO FUN !!] | ||||
Pos=30,24 | |||||
Pos=16,24 | |||||
Size=113,99 | Size=113,99 | ||||
Collapsed=0 | Collapsed=0 | ||||
@@ -1 +1 @@ | |||||
Subproject commit e5f8968013e17a41aeed47ee1904c42ab1f452e2 | |||||
Subproject commit 267e992c17074a1afdc35ac361f7dd7525c37939 |
@@ -28,7 +28,7 @@ liblol_core_a_SOURCES = \ | |||||
liblol_core_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/3rdparty/bullet3/src -I$(srcdir)/3rdparty/lua/src | liblol_core_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/3rdparty/bullet3/src -I$(srcdir)/3rdparty/lua/src | ||||
liblol_core_headers = \ | liblol_core_headers = \ | ||||
lol/engine-internal.h lol/engine.h lol/public.h lol/extras.h \ | |||||
lol/engine-internal.h lol/engine.h lol/public.h lol/extras.h lol/legacy.h \ | |||||
\ | \ | ||||
lol/base/all.h \ | lol/base/all.h \ | ||||
lol/base/avl_tree.h lol/base/features.h lol/base/tuple.h lol/base/types.h \ | lol/base/avl_tree.h lol/base/features.h lol/base/tuple.h lol/base/types.h \ | ||||
@@ -54,7 +54,7 @@ liblol_core_headers = \ | |||||
lol/sys/threadtypes.h lol/sys/timer.h \ | lol/sys/threadtypes.h lol/sys/timer.h \ | ||||
\ | \ | ||||
lol/image/all.h \ | lol/image/all.h \ | ||||
lol/image/pixel.h lol/image/color.h lol/image/image.h lol/image/movie.h \ | |||||
lol/image/pixel.h lol/image/color.h lol/image/image.h lol/image/resource.h lol/image/movie.h \ | |||||
\ | \ | ||||
lol/gpu/all.h \ | lol/gpu/all.h \ | ||||
lol/gpu/shader.h lol/gpu/indexbuffer.h lol/gpu/vertexbuffer.h \ | lol/gpu/shader.h lol/gpu/indexbuffer.h lol/gpu/vertexbuffer.h \ | ||||
@@ -115,6 +115,7 @@ liblol_core_sources = \ | |||||
sys/init.cpp sys/file.cpp sys/hacks.cpp \ | sys/init.cpp sys/file.cpp sys/hacks.cpp \ | ||||
sys/thread.cpp sys/threadtypes.cpp sys/getopt.cpp \ | sys/thread.cpp sys/threadtypes.cpp sys/getopt.cpp \ | ||||
\ | \ | ||||
image/resource.cpp image/resource-private.h \ | |||||
image/image.cpp image/image-private.h image/kernel.cpp image/pixel.cpp \ | image/image.cpp image/image-private.h image/kernel.cpp image/pixel.cpp \ | ||||
image/crop.cpp image/resample.cpp image/noise.cpp image/combine.cpp \ | image/crop.cpp image/resample.cpp image/noise.cpp image/combine.cpp \ | ||||
image/codec/gdiplus-image.cpp image/codec/imlib2-image.cpp \ | image/codec/gdiplus-image.cpp image/codec/imlib2-image.cpp \ | ||||
@@ -33,6 +33,7 @@ struct audio_streamer | |||||
int m_channel; | int m_channel; | ||||
std::function<void(void *, int)> m_callback; | std::function<void(void *, int)> m_callback; | ||||
#if defined LOL_USE_SDL_MIXER | #if defined LOL_USE_SDL_MIXER | ||||
array<uint8_t> m_empty; // SDL keeps a reference to this | |||||
Mix_Chunk *m_chunk; | Mix_Chunk *m_chunk; | ||||
#endif | #endif | ||||
}; | }; | ||||
@@ -95,9 +96,8 @@ int audio::start_streaming(std::function<void(void *, int)> const &f) | |||||
audio_streamer *s = new audio_streamer(); | audio_streamer *s = new audio_streamer(); | ||||
g_streamers.push(s); | g_streamers.push(s); | ||||
array<uint8_t> empty; | |||||
empty.resize(1024); | |||||
s->m_chunk = Mix_QuickLoad_RAW(empty.data(), empty.bytes()); | |||||
s->m_empty.resize(1024); | |||||
s->m_chunk = Mix_QuickLoad_RAW(s->m_empty.data(), s->m_empty.bytes()); | |||||
s->m_channel = Mix_PlayChannel(-1, s->m_chunk, -1); | s->m_channel = Mix_PlayChannel(-1, s->m_chunk, -1); | ||||
s->m_callback = f; | s->m_callback = f; | ||||
Mix_RegisterEffect(s->m_channel, trampoline, nullptr, s); | Mix_RegisterEffect(s->m_channel, trampoline, nullptr, s); | ||||
@@ -12,60 +12,14 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
Debug::DrawContext::Data Debug::DrawContext::m_global = Debug::DrawContext::Data(vec4(1.f)); | |||||
//Resets draw infos | |||||
void Debug::DrawSetupReset() | |||||
{ | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.SetLineTime(); | |||||
scene.SetLineMask(); | |||||
} | |||||
//Sets draw infos | |||||
void Debug::DrawSetupTime(float new_time) | |||||
{ | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.SetLineTime(new_time); | |||||
} | |||||
//-- | |||||
void Debug::DrawSetupMask(int new_mask) | |||||
{ | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.SetLineMask(new_mask); | |||||
} | |||||
//-- | |||||
void Debug::DrawSetupSegment(float new_segment_size) | |||||
{ | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.SetLineSegmentSize(new_segment_size); | |||||
} | |||||
//-- | |||||
void Debug::DrawSetupColor(vec4 color) | |||||
{ | |||||
Scene& scene = Scene::GetScene(); | |||||
scene.SetLineColor(color); | |||||
} | |||||
//-- | |||||
void Debug::DrawSetup(float new_time, int new_mask, float segment_size, vec4 color) | |||||
{ | |||||
Debug::DrawSetupTime(new_time); | |||||
Debug::DrawSetupMask(new_mask); | |||||
Debug::DrawSetupSegment(segment_size); | |||||
Debug::DrawSetupColor(color); | |||||
} | |||||
typedef Debug::DrawContext DC; | |||||
typedef Debug::DrawContext::Data DCD; | |||||
//Screen to world conversion | //Screen to world conversion | ||||
vec3 Debug::WorldToScreen(vec3 pos) | |||||
{ | |||||
return Debug::WorldToScreen(vec4(pos, 1.f)); | |||||
} | |||||
vec3 Debug::WorldToScreen(vec3 pos, mat4 view_proj) | |||||
{ | |||||
return Debug::WorldToScreen(vec4(pos, 1.f), view_proj); | |||||
} | |||||
vec3 Debug::WorldToScreen(vec3 pos) { return Debug::WorldToScreen(vec4(pos, 1.f)); } | |||||
vec3 Debug::WorldToScreen(vec3 pos, mat4 view_proj) { return Debug::WorldToScreen(vec4(pos, 1.f), view_proj); } | |||||
vec3 Debug::WorldToScreen(vec4 pos) | vec3 Debug::WorldToScreen(vec4 pos) | ||||
{ | { | ||||
Scene& scene = Scene::GetScene(); | Scene& scene = Scene::GetScene(); | ||||
@@ -81,8 +35,7 @@ vec3 Debug::WorldToScreen(vec4 pos, mat4 view_proj) | |||||
} | } | ||||
//-- | //-- | ||||
vec3 Debug::ScreenToWorld(vec2 pos, float z) | |||||
{ return Debug::ScreenToWorld(vec3(pos, z)); } | |||||
vec3 Debug::ScreenToWorld(vec2 pos, float z) { return Debug::ScreenToWorld(vec3(pos, z)); } | |||||
vec3 Debug::ScreenToWorld(vec3 pos) | vec3 Debug::ScreenToWorld(vec3 pos) | ||||
{ | { | ||||
Scene& scene = Scene::GetScene(); | Scene& scene = Scene::GetScene(); | ||||
@@ -91,8 +44,7 @@ vec3 Debug::ScreenToWorld(vec3 pos) | |||||
mat4 const inv_view_proj = inverse(scene.GetCamera()->GetProjection() * scene.GetCamera()->GetView()); | mat4 const inv_view_proj = inverse(scene.GetCamera()->GetProjection() * scene.GetCamera()->GetView()); | ||||
return Debug::ScreenToWorld(pos, inv_view_proj); | return Debug::ScreenToWorld(pos, inv_view_proj); | ||||
} | } | ||||
vec3 Debug::ScreenToWorld(vec2 pos, mat4 inv_view_proj, float z) | |||||
{ return Debug::ScreenToWorld(vec3(pos, z), inv_view_proj); } | |||||
vec3 Debug::ScreenToWorld(vec2 pos, mat4 inv_view_proj, float z) { return Debug::ScreenToWorld(vec3(pos, z), inv_view_proj); } | |||||
vec3 Debug::ScreenToWorld(vec3 pos, mat4 inv_view_proj) | vec3 Debug::ScreenToWorld(vec3 pos, mat4 inv_view_proj) | ||||
{ | { | ||||
vec4 screen_pos = inv_view_proj * vec4(pos, 1.f); | vec4 screen_pos = inv_view_proj * vec4(pos, 1.f); | ||||
@@ -107,12 +59,16 @@ vec3 Debug::ScreenToWorld(vec3 pos, mat4 view, mat4 proj) | |||||
//Draw stuff in World | //Draw stuff in World | ||||
//-- LINE: 3D -2D - 3D_to_2D -------------------------------------------------- | //-- LINE: 3D -2D - 3D_to_2D -------------------------------------------------- | ||||
void Debug::DrawLine(vec3 a, vec3 b) { Scene& scene = Scene::GetScene(); Debug::DrawLine(a, b, scene.GetLineColor()); } | |||||
void Debug::DrawLine(vec2 a, vec3 b, float az) { Scene& scene = Scene::GetScene(); Debug::DrawLine(a, b, scene.GetLineColor(), az); } | |||||
void Debug::DrawLine(vec2 a, vec2 b, float az, float bz) { Scene& scene = Scene::GetScene(); Debug::DrawLine(a, b, scene.GetLineColor(), az, bz); } | |||||
void Debug::DrawLine(vec3 a, vec3 b, vec4 color) { Scene& scene = Scene::GetScene(); scene.AddLine(a, b, color); } | |||||
void Debug::DrawLine(vec2 a, vec3 b, vec4 color, float az) { Scene& scene = Scene::GetScene(); scene.AddLine(vec3(a, az), b, color); } | |||||
void Debug::DrawLine(vec2 a, vec2 b, vec4 color, float az, float bz){ Scene& scene = Scene::GetScene(); scene.AddLine(vec3(a, az), vec3(b, bz), color); } | |||||
//Root func | |||||
void Debug::DrawLine(vec3 a, vec3 b, DCD data) | |||||
{ | |||||
Scene::GetScene().AddLine(a, b, data.m_color, data.m_duration, data.m_mask); | |||||
} | |||||
void Debug::DrawLine(vec2 a, vec3 b, DCD data, float az) { DrawLine(vec3(a, az), b, data); } | |||||
void Debug::DrawLine(vec2 a, vec2 b, DCD data, float az, float bz) { DrawLine(vec3(a, az), vec3(b, bz), data); } | |||||
void Debug::DrawLine(vec3 a, vec3 b) { DrawLine(a, b, DC::GetGlobalData()); } | |||||
void Debug::DrawLine(vec2 a, vec3 b, float az) { DrawLine(a, b, DC::GetGlobalData(), az); } | |||||
void Debug::DrawLine(vec2 a, vec2 b, float az, float bz) { DrawLine(a, b, DC::GetGlobalData(), az, bz); } | |||||
//-- GIZMO -------------------------------------------------------------------- | //-- GIZMO -------------------------------------------------------------------- | ||||
void Debug::DrawGizmo(vec3 pos, vec3 x, vec3 y, vec3 z, float size) | void Debug::DrawGizmo(vec3 pos, vec3 x, vec3 y, vec3 z, float size) | ||||
@@ -131,8 +87,7 @@ void Debug::DrawGizmo(vec2 pos, vec3 x, vec3 y, vec3 z, float size, float posz) | |||||
//-- GRID --------------------------------------------------------------------- | //-- GRID --------------------------------------------------------------------- | ||||
void Debug::DrawGrid(vec3 pos, vec3 x, vec3 y, vec3 z, float size, bool draw_3d) | void Debug::DrawGrid(vec3 pos, vec3 x, vec3 y, vec3 z, float size, bool draw_3d) | ||||
{ | { | ||||
Scene& scene = Scene::GetScene(); | |||||
float seg_sz = scene.GetLineSegmentSize(); | |||||
float seg_sz = DC::GetGlobalData().m_segment_size; | |||||
int seg_nb = lol::max((int)(size / seg_sz), 1); | int seg_nb = lol::max((int)(size / seg_sz), 1); | ||||
seg_sz = size / (float)seg_nb; | seg_sz = size / (float)seg_nb; | ||||
@@ -165,38 +120,38 @@ void Debug::DrawGrid(vec3 pos, vec3 x, vec3 y, vec3 z, float size, bool draw_3d) | |||||
} | } | ||||
//-- ARROW: 3D -2D - 3D_to_2D ------------------------------------------------- | //-- ARROW: 3D -2D - 3D_to_2D ------------------------------------------------- | ||||
void Debug::DrawArrow(vec3 a, vec3 b, vec2 s) { Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y)); } | |||||
void Debug::DrawArrow(vec2 a, vec3 b, vec2 s, float az) { Debug::DrawArrow(a, b.xy, vec3(s.x, s.y, s.y), az, b.z); } | |||||
void Debug::DrawArrow(vec2 a, vec2 b, vec2 s, float az, float bz) { Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y), az, bz); } | |||||
void Debug::DrawArrow(vec3 a, vec3 b, vec3 s) { Scene& scene = Scene::GetScene(); Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y), scene.GetLineColor()); } | |||||
void Debug::DrawArrow(vec2 a, vec3 b, vec3 s, float az) { Scene& scene = Scene::GetScene(); Debug::DrawArrow(a, b.xy, vec3(s.x, s.y, s.y), scene.GetLineColor(), az, b.z); } | |||||
void Debug::DrawArrow(vec2 a, vec2 b, vec3 s, float az, float bz) { Scene& scene = Scene::GetScene(); Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y), scene.GetLineColor(), az, bz); } | |||||
void Debug::DrawArrow(vec3 a, vec3 b, vec3 s, vec4 color) | |||||
void Debug::DrawArrow(vec3 a, vec3 b, vec2 s) { Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y)); } | |||||
void Debug::DrawArrow(vec2 a, vec3 b, vec2 s, float az) { Debug::DrawArrow(a, b.xy, vec3(s.x, s.y, s.y), az, b.z); } | |||||
void Debug::DrawArrow(vec2 a, vec2 b, vec2 s, float az, float bz) { Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y), az, bz); } | |||||
void Debug::DrawArrow(vec3 a, vec3 b, vec3 s) { Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y), DC::GetGlobalData()); } | |||||
void Debug::DrawArrow(vec2 a, vec3 b, vec3 s, float az) { Debug::DrawArrow(a, b.xy, vec3(s.x, s.y, s.y), DC::GetGlobalData(), az, b.z); } | |||||
void Debug::DrawArrow(vec2 a, vec2 b, vec3 s, float az, float bz) { Debug::DrawArrow(a, b, vec3(s.x, s.y, s.y), DC::GetGlobalData(), az, bz); } | |||||
void Debug::DrawArrow(vec3 a, vec3 b, vec3 s, DCD data) | |||||
{ | { | ||||
vec3 z = s.x * normalize(b - a); | vec3 z = s.x * normalize(b - a); | ||||
vec3 x = s.z * orthonormal(b - a); | vec3 x = s.z * orthonormal(b - a); | ||||
vec3 y = s.y * cross(normalize(x), normalize(z)); | vec3 y = s.y * cross(normalize(x), normalize(z)); | ||||
Debug::DrawLine(a, b, color); | |||||
Debug::DrawLine(b, b - z + x, color); | |||||
Debug::DrawLine(b, b - z - x, color); | |||||
Debug::DrawLine(b, b - z + y, color); | |||||
Debug::DrawLine(b, b - z - y, color); | |||||
Debug::DrawLine(a, b, data); | |||||
Debug::DrawLine(b, b - z + x, data); | |||||
Debug::DrawLine(b, b - z - x, data); | |||||
Debug::DrawLine(b, b - z + y, data); | |||||
Debug::DrawLine(b, b - z - y, data); | |||||
Debug::DrawLine(b - z + x, b - z + y, color); | |||||
Debug::DrawLine(b - z + x, b - z - y, color); | |||||
Debug::DrawLine(b - z - x, b - z + y, color); | |||||
Debug::DrawLine(b - z - x, b - z - y, color); | |||||
Debug::DrawLine(b - z + x, b - z + y, data); | |||||
Debug::DrawLine(b - z + x, b - z - y, data); | |||||
Debug::DrawLine(b - z - x, b - z + y, data); | |||||
Debug::DrawLine(b - z - x, b - z - y, data); | |||||
Debug::DrawLine(b - z + x, b - z - x, color); | |||||
Debug::DrawLine(b - z + y, b - z - y, color); | |||||
Debug::DrawLine(b - z + x, b - z - x, data); | |||||
Debug::DrawLine(b - z + y, b - z - y, data); | |||||
} | } | ||||
void Debug::DrawArrow(vec2 a, vec3 b, vec3 s, vec4 color, float az) | |||||
void Debug::DrawArrow(vec2 a, vec3 b, vec3 s, DCD data, float az) | |||||
{ | { | ||||
vec3 bn = Debug::WorldToScreen(b); | vec3 bn = Debug::WorldToScreen(b); | ||||
DrawArrow(a, bn.xy, s, color, az, bn.z); | |||||
DrawArrow(a, bn.xy, s, data, az, bn.z); | |||||
} | } | ||||
void Debug::DrawArrow(vec2 a, vec2 b, vec3 s, vec4 color, float az, float bz) | |||||
void Debug::DrawArrow(vec2 a, vec2 b, vec3 s, DCD data, float az, float bz) | |||||
{ | { | ||||
vec3 an = vec3(a, az); | vec3 an = vec3(a, az); | ||||
vec3 bn = vec3(b, bz); | vec3 bn = vec3(b, bz); | ||||
@@ -204,40 +159,40 @@ void Debug::DrawArrow(vec2 a, vec2 b, vec3 s, vec4 color, float az, float bz) | |||||
vec3 x = s.z * orthonormal(bn - an); | vec3 x = s.z * orthonormal(bn - an); | ||||
vec3 y = s.y * cross(normalize(x), normalize(z)); | vec3 y = s.y * cross(normalize(x), normalize(z)); | ||||
Debug::DrawLine(a, b, color, az, bz); | |||||
Debug::DrawLine(b, b - (z + x).xy, color, bz, bz - (z + x).z); | |||||
Debug::DrawLine(b, b - (z - x).xy, color, bz, bz - (z - x).z); | |||||
Debug::DrawLine(b, b - (z + y).xy, color, bz, bz - (z + y).z); | |||||
Debug::DrawLine(b, b - (z - y).xy, color, bz, bz - (z - y).z); | |||||
Debug::DrawLine(a, b, data, az, bz); | |||||
Debug::DrawLine(b, b - (z + x).xy, data, bz, bz - (z + x).z); | |||||
Debug::DrawLine(b, b - (z - x).xy, data, bz, bz - (z - x).z); | |||||
Debug::DrawLine(b, b - (z + y).xy, data, bz, bz - (z + y).z); | |||||
Debug::DrawLine(b, b - (z - y).xy, data, bz, bz - (z - y).z); | |||||
Debug::DrawLine(b - (z + x).xy, b - (z + y).xy, color, bz - (z + x).z, bz - (z + y).z); | |||||
Debug::DrawLine(b - (z + x).xy, b - (z - y).xy, color, bz - (z + x).z, bz - (z - y).z); | |||||
Debug::DrawLine(b - (z - x).xy, b - (z + y).xy, color, bz - (z - x).z, bz - (z + y).z); | |||||
Debug::DrawLine(b - (z - x).xy, b - (z - y).xy, color, bz - (z - x).z, bz - (z - y).z); | |||||
Debug::DrawLine(b - (z + x).xy, b - (z + y).xy, data, bz - (z + x).z, bz - (z + y).z); | |||||
Debug::DrawLine(b - (z + x).xy, b - (z - y).xy, data, bz - (z + x).z, bz - (z - y).z); | |||||
Debug::DrawLine(b - (z - x).xy, b - (z + y).xy, data, bz - (z - x).z, bz - (z + y).z); | |||||
Debug::DrawLine(b - (z - x).xy, b - (z - y).xy, data, bz - (z - x).z, bz - (z - y).z); | |||||
Debug::DrawLine(b - (z + x).xy, b - (z - x).xy, color, bz - (z + x).z, bz - (z - x).z); | |||||
Debug::DrawLine(b - (z + y).xy, b - (z - y).xy, color, bz - (z + y).z, bz - (z - y).z); | |||||
Debug::DrawLine(b - (z + x).xy, b - (z - x).xy, data, bz - (z + x).z, bz - (z - x).z); | |||||
Debug::DrawLine(b - (z + y).xy, b - (z - y).xy, data, bz - (z + y).z, bz - (z - y).z); | |||||
} | } | ||||
//-- BOX: 3D -2D - 3D_to_2D --------------------------------------------------- | //-- BOX: 3D -2D - 3D_to_2D --------------------------------------------------- | ||||
void Debug::DrawBox(box3 a) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, scene.GetLineColor()); } | |||||
void Debug::DrawBox(box2 a) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, scene.GetLineColor()); } | |||||
void Debug::DrawBox(box3 a, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, color); } | |||||
void Debug::DrawBox(box2 a, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, color); } | |||||
void Debug::DrawBox(vec3 a, vec3 b) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, b, scene.GetLineColor()); } | |||||
void Debug::DrawBox(vec2 a, vec2 b) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, b, scene.GetLineColor()); } | |||||
void Debug::DrawBox(vec2 a, float s) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, s, scene.GetLineColor()); } | |||||
void Debug::DrawBox(vec3 a, vec3 b, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, b, mat4::identity, color); } | |||||
void Debug::DrawBox(vec2 a, vec2 b, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, b, mat2::identity, color); } | |||||
void Debug::DrawBox(vec2 a, float s, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, s, mat2::identity, color); } | |||||
void Debug::DrawBox(box3 a, mat4 transform) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, transform, scene.GetLineColor()); } | |||||
void Debug::DrawBox(box2 a, mat2 transform) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, transform, scene.GetLineColor()); } | |||||
void Debug::DrawBox(box3 a, mat4 transform, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, transform, color); } | |||||
void Debug::DrawBox(box2 a, mat2 transform, vec4 color) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a.aa, a.bb, transform, color); } | |||||
void Debug::DrawBox(vec3 a, vec3 b, mat4 transform) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, b, transform, scene.GetLineColor()); } | |||||
void Debug::DrawBox(vec2 a, vec2 b, mat2 transform) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, b, transform, scene.GetLineColor()); } | |||||
void Debug::DrawBox(vec2 a, float s, mat2 transform) { Scene& scene = Scene::GetScene(); Debug::DrawBox(a, s, transform, scene.GetLineColor()); } | |||||
void Debug::DrawBox(vec3 a, vec3 b, mat4 transform, vec4 color) | |||||
void Debug::DrawBox(box3 a) { Debug::DrawBox(a.aa, a.bb, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(box2 a) { Debug::DrawBox(a.aa, a.bb, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(box3 a, DCD data) { Debug::DrawBox(a.aa, a.bb, data); } | |||||
void Debug::DrawBox(box2 a, DCD data) { Debug::DrawBox(a.aa, a.bb, data); } | |||||
void Debug::DrawBox(vec3 a, vec3 b) { Debug::DrawBox(a, b, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(vec2 a, vec2 b) { Debug::DrawBox(a, b, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(vec2 a, float s) { Debug::DrawBox(a, s, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(vec3 a, vec3 b, DCD data) { Debug::DrawBox(a, b, mat4::identity, data); } | |||||
void Debug::DrawBox(vec2 a, vec2 b, DCD data) { Debug::DrawBox(a, b, mat2::identity, data); } | |||||
void Debug::DrawBox(vec2 a, float s, DCD data) { Debug::DrawBox(a, s, mat2::identity, data); } | |||||
void Debug::DrawBox(box3 a, mat4 transform) { Debug::DrawBox(a.aa, a.bb, transform, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(box2 a, mat2 transform) { Debug::DrawBox(a.aa, a.bb, transform, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(box3 a, mat4 transform, DCD data) { Debug::DrawBox(a.aa, a.bb, transform, data); } | |||||
void Debug::DrawBox(box2 a, mat2 transform, DCD data) { Debug::DrawBox(a.aa, a.bb, transform, data); } | |||||
void Debug::DrawBox(vec3 a, vec3 b, mat4 transform) { Debug::DrawBox(a, b, transform, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(vec2 a, vec2 b, mat2 transform) { Debug::DrawBox(a, b, transform, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(vec2 a, float s, mat2 transform) { Debug::DrawBox(a, s, transform, DC::GetGlobalData()); } | |||||
void Debug::DrawBox(vec3 a, vec3 b, mat4 transform, DCD data) | |||||
{ | { | ||||
vec4 v[8]; | vec4 v[8]; | ||||
for (int i = 0; i < 8; i++) | for (int i = 0; i < 8; i++) | ||||
@@ -252,12 +207,12 @@ void Debug::DrawBox(vec3 a, vec3 b, mat4 transform, vec4 color) | |||||
{ | { | ||||
int j = ((i & 1) << 1) | ((i >> 1) ^ 1); | int j = ((i & 1) << 1) | ((i >> 1) ^ 1); | ||||
Debug::DrawLine((transform * v[i]).xyz, (transform * v[i + 4]).xyz, color); | |||||
Debug::DrawLine((transform * v[i]).xyz, (transform * v[j]).xyz, color); | |||||
Debug::DrawLine((transform * v[i + 4]).xyz, (transform * v[j + 4]).xyz, color); | |||||
Debug::DrawLine((transform * v[i]).xyz, (transform * v[i + 4]).xyz, data); | |||||
Debug::DrawLine((transform * v[i]).xyz, (transform * v[j]).xyz, data); | |||||
Debug::DrawLine((transform * v[i + 4]).xyz, (transform * v[j + 4]).xyz, data); | |||||
} | } | ||||
} | } | ||||
void Debug::DrawBox(vec2 a, vec2 b, mat2 transform, vec4 color) | |||||
void Debug::DrawBox(vec2 a, vec2 b, mat2 transform, DCD data) | |||||
{ | { | ||||
vec2 v[4]; | vec2 v[4]; | ||||
v[0] = a; | v[0] = a; | ||||
@@ -266,41 +221,41 @@ void Debug::DrawBox(vec2 a, vec2 b, mat2 transform, vec4 color) | |||||
v[3] = vec2(b.x, a.y); | v[3] = vec2(b.x, a.y); | ||||
int i = 0; | int i = 0; | ||||
Debug::DrawLine((transform * v[0]).xy, (transform * v[1]).xy, color); | |||||
Debug::DrawLine((transform * v[1]).xy, (transform * v[2]).xy, color); | |||||
Debug::DrawLine((transform * v[2]).xy, (transform * v[3]).xy, color); | |||||
Debug::DrawLine((transform * v[3]).xy, (transform * v[0]).xy, color); | |||||
Debug::DrawLine((transform * v[0]).xy, (transform * v[1]).xy, data); | |||||
Debug::DrawLine((transform * v[1]).xy, (transform * v[2]).xy, data); | |||||
Debug::DrawLine((transform * v[2]).xy, (transform * v[3]).xy, data); | |||||
Debug::DrawLine((transform * v[3]).xy, (transform * v[0]).xy, data); | |||||
} | } | ||||
void Debug::DrawBox(vec2 a, float s, mat2 transform, vec4 color) | |||||
void Debug::DrawBox(vec2 a, float s, mat2 transform, DCD data) | |||||
{ | { | ||||
vec2 b = s * vec2(1.f, Renderer::Get()->GetXYRatio()); | vec2 b = s * vec2(1.f, Renderer::Get()->GetXYRatio()); | ||||
Debug::DrawBox(a - b, a + b, transform, color); | |||||
Debug::DrawBox(a - b, a + b, transform, data); | |||||
} | } | ||||
//-- CIRCLE ------------------------------------------------------------------- | //-- CIRCLE ------------------------------------------------------------------- | ||||
void Debug::DrawCircle(vec2 a, float s) { Scene& scene = Scene::GetScene(); Debug::DrawCircle(a, s * vec2(1.f, Renderer::Get()->GetXYRatio()), scene.GetLineColor()); } | |||||
void Debug::DrawCircle(vec3 a, vec3 n) { Scene& scene = Scene::GetScene(); Debug::DrawCircle(a, n, scene.GetLineColor()); } | |||||
void Debug::DrawCircle(vec2 a, vec2 s) { Scene& scene = Scene::GetScene(); Debug::DrawCircle(a, s * vec2(1.f, Renderer::Get()->GetXYRatio()), scene.GetLineColor()); } | |||||
void Debug::DrawCircle(vec3 a, vec3 x, vec3 y) { Scene& scene = Scene::GetScene(); Debug::DrawCircle(a, x, y, scene.GetLineColor()); } | |||||
void Debug::DrawCircle(vec2 a, vec2 x, vec2 y) { Scene& scene = Scene::GetScene(); Debug::DrawCircle(a, x, y, scene.GetLineColor()); } | |||||
void Debug::DrawCircle(vec3 a, vec3 n, vec4 color) | |||||
void Debug::DrawCircle(vec2 a, float s) { Debug::DrawCircle(a, s * vec2(1.f, Renderer::Get()->GetXYRatio()), DC::GetGlobalData()); } | |||||
void Debug::DrawCircle(vec3 a, vec3 n) { Debug::DrawCircle(a, n, DC::GetGlobalData()); } | |||||
void Debug::DrawCircle(vec2 a, vec2 s) { Debug::DrawCircle(a, s * vec2(1.f, Renderer::Get()->GetXYRatio()), DC::GetGlobalData()); } | |||||
void Debug::DrawCircle(vec3 a, vec3 x, vec3 y) { Debug::DrawCircle(a, x, y, DC::GetGlobalData()); } | |||||
void Debug::DrawCircle(vec2 a, vec2 x, vec2 y) { Debug::DrawCircle(a, x, y, DC::GetGlobalData()); } | |||||
void Debug::DrawCircle(vec3 a, vec3 n, DCD data) | |||||
{ | { | ||||
vec3 x = orthogonal(n); | vec3 x = orthogonal(n); | ||||
vec3 y = cross(normalize(n), normalize(x)) * length(n); | vec3 y = cross(normalize(n), normalize(x)) * length(n); | ||||
DrawCircle(a, x, y, color); | |||||
DrawCircle(a, x, y, data); | |||||
} | } | ||||
void Debug::DrawCircle(vec2 a, vec2 s, vec4 color) | |||||
void Debug::DrawCircle(vec2 a, vec2 s, DCD data) | |||||
{ | { | ||||
vec2 x = vec2::axis_x * s.x; | vec2 x = vec2::axis_x * s.x; | ||||
vec2 y = vec2::axis_y * s.y; | vec2 y = vec2::axis_y * s.y; | ||||
DrawCircle(a, x, y, color); | |||||
DrawCircle(a, x, y, data); | |||||
} | } | ||||
//-- | //-- | ||||
void Debug::DrawCircle(vec3 a, vec3 x, vec3 y, vec4 color) | |||||
void Debug::DrawCircle(vec3 a, vec3 x, vec3 y, DCD data) | |||||
{ | { | ||||
Scene& scene = Scene::GetScene(); | Scene& scene = Scene::GetScene(); | ||||
float size = F_PI * 2.f * lol::max(length(x), length(y)); | float size = F_PI * 2.f * lol::max(length(x), length(y)); | ||||
int segment_nb = lol::max(1, (int)((size * .25f) / scene.GetLineSegmentSize())); | |||||
int segment_nb = lol::max(1, (int)((size * .25f) / data.m_segment_size)); | |||||
for (int i = 0; i < segment_nb; i++) | for (int i = 0; i < segment_nb; i++) | ||||
{ | { | ||||
float a0 = (((float)i) / (float)segment_nb) * F_PI_2; | float a0 = (((float)i) / (float)segment_nb) * F_PI_2; | ||||
@@ -308,18 +263,18 @@ void Debug::DrawCircle(vec3 a, vec3 x, vec3 y, vec4 color) | |||||
vec2 p0 = vec2(lol::cos(a0), lol::sin(a0)); | vec2 p0 = vec2(lol::cos(a0), lol::sin(a0)); | ||||
vec2 p1 = vec2(lol::cos(a1), lol::sin(a1)); | vec2 p1 = vec2(lol::cos(a1), lol::sin(a1)); | ||||
Debug::DrawLine(a + p0.x * x + p0.y * y, a + p1.x * x + p1.y * y, color); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * -y, a + p1.x * -x + p1.y * -y, color); | |||||
Debug::DrawLine(a + p0.x * x + p0.y * -y, a + p1.x * x + p1.y * -y, color); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * y, a + p1.x * -x + p1.y * y, color); | |||||
Debug::DrawLine(a + p0.x * x + p0.y * y, a + p1.x * x + p1.y * y, data); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * -y, a + p1.x * -x + p1.y * -y, data); | |||||
Debug::DrawLine(a + p0.x * x + p0.y * -y, a + p1.x * x + p1.y * -y, data); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * y, a + p1.x * -x + p1.y * y, data); | |||||
} | } | ||||
} | } | ||||
//-- | //-- | ||||
void Debug::DrawCircle(vec2 a, vec2 x, vec2 y, vec4 color) | |||||
void Debug::DrawCircle(vec2 a, vec2 x, vec2 y, DCD data) | |||||
{ | { | ||||
Scene& scene = Scene::GetScene(); | Scene& scene = Scene::GetScene(); | ||||
float size = F_PI * 2.f * lol::max(length(x), length(y)); | float size = F_PI * 2.f * lol::max(length(x), length(y)); | ||||
int segment_nb = lol::max(1, (int)((size * .25f) / scene.GetLineSegmentSize())); | |||||
int segment_nb = lol::max(1, (int)((size * .25f) / data.m_segment_size)); | |||||
for (int i = 0; i < segment_nb; i++) | for (int i = 0; i < segment_nb; i++) | ||||
{ | { | ||||
float a0 = (((float)i) / (float)segment_nb) * F_PI_2; | float a0 = (((float)i) / (float)segment_nb) * F_PI_2; | ||||
@@ -327,52 +282,52 @@ void Debug::DrawCircle(vec2 a, vec2 x, vec2 y, vec4 color) | |||||
vec2 p0 = vec2(lol::cos(a0), lol::sin(a0)); | vec2 p0 = vec2(lol::cos(a0), lol::sin(a0)); | ||||
vec2 p1 = vec2(lol::cos(a1), lol::sin(a1)); | vec2 p1 = vec2(lol::cos(a1), lol::sin(a1)); | ||||
Debug::DrawLine(a + p0.x * x + p0.y * y, a + p1.x * x + p1.y * y, color); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * -y, a + p1.x * -x + p1.y * -y, color); | |||||
Debug::DrawLine(a + p0.x * x + p0.y * -y, a + p1.x * x + p1.y * -y, color); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * y, a + p1.x * -x + p1.y * y, color); | |||||
Debug::DrawLine(a + p0.x * x + p0.y * y, a + p1.x * x + p1.y * y, data); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * -y, a + p1.x * -x + p1.y * -y, data); | |||||
Debug::DrawLine(a + p0.x * x + p0.y * -y, a + p1.x * x + p1.y * -y, data); | |||||
Debug::DrawLine(a + p0.x * -x + p0.y * y, a + p1.x * -x + p1.y * y, data); | |||||
} | } | ||||
} | } | ||||
//-- SPHERE ------------------------------------------------------------------- | //-- SPHERE ------------------------------------------------------------------- | ||||
void Debug::DrawSphere(vec3 a, float s) { Scene& scene = Scene::GetScene(); Debug::DrawSphere(a, s, scene.GetLineColor()); } | |||||
void Debug::DrawSphere(vec3 a, float s, vec4 color) { Debug::DrawSphere(a, vec3::axis_x * s, vec3::axis_y * s, vec3::axis_z * s, color); } | |||||
void Debug::DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z) { Scene& scene = Scene::GetScene(); Debug::DrawSphere(a, x, y, z, scene.GetLineColor()); } | |||||
void Debug::DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z, vec4 color) | |||||
{ | |||||
Debug::DrawCircle(a, x, y, color); | |||||
Debug::DrawCircle(a, x, (y + z) * .707f, color); | |||||
Debug::DrawCircle(a, x, (y - z) * .707f, color); | |||||
Debug::DrawCircle(a, z, x, color); | |||||
Debug::DrawCircle(a, z, (x + y) * .707f, color); | |||||
Debug::DrawCircle(a, z, (x - y) * .707f, color); | |||||
Debug::DrawCircle(a, y, z, color); | |||||
Debug::DrawCircle(a, y, (z + x) * .707f, color); | |||||
Debug::DrawCircle(a, y, (z - x) * .707f, color); | |||||
void Debug::DrawSphere(vec3 a, float s) { Debug::DrawSphere(a, s, DC::GetGlobalData()); } | |||||
void Debug::DrawSphere(vec3 a, float s, DCD data) { Debug::DrawSphere(a, vec3::axis_x * s, vec3::axis_y * s, vec3::axis_z * s, data); } | |||||
void Debug::DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z) { Debug::DrawSphere(a, x, y, z, DC::GetGlobalData()); } | |||||
void Debug::DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z, DCD data) | |||||
{ | |||||
Debug::DrawCircle(a, x, y, data); | |||||
Debug::DrawCircle(a, x, (y + z) * .707f, data); | |||||
Debug::DrawCircle(a, x, (y - z) * .707f, data); | |||||
Debug::DrawCircle(a, z, x, data); | |||||
Debug::DrawCircle(a, z, (x + y) * .707f, data); | |||||
Debug::DrawCircle(a, z, (x - y) * .707f, data); | |||||
Debug::DrawCircle(a, y, z, data); | |||||
Debug::DrawCircle(a, y, (z + x) * .707f, data); | |||||
Debug::DrawCircle(a, y, (z - x) * .707f, data); | |||||
} | } | ||||
//-- CAPSULE ------------------------------------------------------------------ | //-- CAPSULE ------------------------------------------------------------------ | ||||
void Debug::DrawCapsule(vec3 a, float s, vec3 h) { Scene& scene = Scene::GetScene(); Debug::DrawCapsule(a, s, h, scene.GetLineColor()); } | |||||
void Debug::DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h) { Scene& scene = Scene::GetScene(); Debug::DrawCapsule(a, x, y, z, h, scene.GetLineColor()); } | |||||
void Debug::DrawCapsule(vec3 a, float s, vec3 h, vec4 color) | |||||
void Debug::DrawCapsule(vec3 a, float s, vec3 h) { Debug::DrawCapsule(a, s, h, DC::GetGlobalData()); } | |||||
void Debug::DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h) { Debug::DrawCapsule(a, x, y, z, h, DC::GetGlobalData()); } | |||||
void Debug::DrawCapsule(vec3 a, float s, vec3 h, DCD data) | |||||
{ | { | ||||
vec3 x = orthonormal(h) * s; | vec3 x = orthonormal(h) * s; | ||||
vec3 y = cross(normalize(h), normalize(x)) * s; | vec3 y = cross(normalize(h), normalize(x)) * s; | ||||
Debug::DrawCapsule(a, x, y, normalize(h) * s, h, color); | |||||
Debug::DrawCapsule(a, x, y, normalize(h) * s, h, data); | |||||
} | } | ||||
//-- | //-- | ||||
void Debug::DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h, vec4 color) | |||||
void Debug::DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h, DCD data) | |||||
{ | { | ||||
Scene& scene = Scene::GetScene(); | Scene& scene = Scene::GetScene(); | ||||
float size = F_PI * 2.f * lol::max(length(x), length(y)); | float size = F_PI * 2.f * lol::max(length(x), length(y)); | ||||
int segment_nb = lol::max(1, (int)((size * .25f) / scene.GetLineSegmentSize())); | |||||
int segment_nb = lol::max(1, (int)((size * .25f) / data.m_segment_size)); | |||||
for (int i = -1; i < 2; i += 2) | for (int i = -1; i < 2; i += 2) | ||||
{ | { | ||||
vec3 b = a + h * .5f * (float)i; | vec3 b = a + h * .5f * (float)i; | ||||
vec3 c = a - h * .5f * (float)i; | vec3 c = a - h * .5f * (float)i; | ||||
Debug::DrawCircle(b, x, y, color); | |||||
Debug::DrawLine(b + x * (float)i, c + x * (float)i, color); | |||||
Debug::DrawLine(b + y * (float)i, c + y * (float)i, color); | |||||
Debug::DrawCircle(b, x, y, data); | |||||
Debug::DrawLine(b + x * (float)i, c + x * (float)i, data); | |||||
Debug::DrawLine(b + y * (float)i, c + y * (float)i, data); | |||||
for (int j = 0; j < segment_nb; j++) | for (int j = 0; j < segment_nb; j++) | ||||
{ | { | ||||
float a0 = (((float)j) / (float)segment_nb) * F_PI_2; | float a0 = (((float)j) / (float)segment_nb) * F_PI_2; | ||||
@@ -380,18 +335,18 @@ void Debug::DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h, vec4 color) | |||||
vec2 p0 = vec2(lol::cos(a0), lol::sin(a0)); | vec2 p0 = vec2(lol::cos(a0), lol::sin(a0)); | ||||
vec2 p1 = vec2(lol::cos(a1), lol::sin(a1)); | vec2 p1 = vec2(lol::cos(a1), lol::sin(a1)); | ||||
Debug::DrawLine(b + p0.x * x + p0.y * z * (float)i, b + p1.x * x + p1.y * z * (float)i, color); | |||||
Debug::DrawLine(b + p0.x * -x + p0.y * z * (float)i, b + p1.x * -x + p1.y * z * (float)i, color); | |||||
Debug::DrawLine(b + p0.x * y + p0.y * z * (float)i, b + p1.x * y + p1.y * z * (float)i, color); | |||||
Debug::DrawLine(b + p0.x * -y + p0.y * z * (float)i, b + p1.x * -y + p1.y * z * (float)i, color); | |||||
Debug::DrawLine(b + p0.x * x + p0.y * z * (float)i, b + p1.x * x + p1.y * z * (float)i, data); | |||||
Debug::DrawLine(b + p0.x * -x + p0.y * z * (float)i, b + p1.x * -x + p1.y * z * (float)i, data); | |||||
Debug::DrawLine(b + p0.x * y + p0.y * z * (float)i, b + p1.x * y + p1.y * z * (float)i, data); | |||||
Debug::DrawLine(b + p0.x * -y + p0.y * z * (float)i, b + p1.x * -y + p1.y * z * (float)i, data); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
//-- VIEW PROJ ---------------------------------------------------------------- | //-- VIEW PROJ ---------------------------------------------------------------- | ||||
void Debug::DrawViewProj(mat4 view, mat4 proj) { Scene& scene = Scene::GetScene(); Debug::DrawViewProj(view, proj, scene.GetLineColor()); } | |||||
void Debug::DrawViewProj(mat4 view_proj) { Scene& scene = Scene::GetScene(); Debug::DrawViewProj(view_proj, scene.GetLineColor()); } | |||||
void Debug::DrawViewProj(mat4 view, mat4 proj, vec4 color) | |||||
void Debug::DrawViewProj(mat4 view, mat4 proj) { Debug::DrawViewProj(view, proj, DC::GetGlobalData()); } | |||||
void Debug::DrawViewProj(mat4 view_proj) { Debug::DrawViewProj(view_proj, DC::GetGlobalData()); } | |||||
void Debug::DrawViewProj(mat4 view, mat4 proj, DCD data) | |||||
{ | { | ||||
mat4 const view_proj = proj * view; | mat4 const view_proj = proj * view; | ||||
@@ -409,13 +364,13 @@ void Debug::DrawViewProj(mat4 view, mat4 proj, vec4 color) | |||||
//Draw near | //Draw near | ||||
for (int i = 0; i < 4; i++) | for (int i = 0; i < 4; i++) | ||||
Debug::DrawLine(p[i].xyz, p0, color); | |||||
Debug::DrawLine(p[i].xyz, p0, data); | |||||
Debug::DrawViewProj(view_proj, color); | |||||
Debug::DrawViewProj(view_proj, data); | |||||
} | } | ||||
//-- | //-- | ||||
void Debug::DrawViewProj(mat4 view_proj, vec4 color) | |||||
void Debug::DrawViewProj(mat4 view_proj, DCD data) | |||||
{ | { | ||||
//Near plane | //Near plane | ||||
mat4 const inv_view_proj = inverse(view_proj); | mat4 const inv_view_proj = inverse(view_proj); | ||||
@@ -433,16 +388,16 @@ void Debug::DrawViewProj(mat4 view_proj, vec4 color) | |||||
//Draw near | //Draw near | ||||
for (int i = 0; i < 4; i++) | for (int i = 0; i < 4; i++) | ||||
Debug::DrawLine(p[i].xyz, p[(i + 1) % 4].xyz, color); | |||||
Debug::DrawLine(p[i].xyz, p[(i + 1) % 4].xyz, data); | |||||
//Draw far | //Draw far | ||||
for (int i = 4; i < 8; i++) | for (int i = 4; i < 8; i++) | ||||
Debug::DrawLine(p[i].xyz, p[(i - 4 + 1) % 4 + 4].xyz, color); | |||||
Debug::DrawLine(p[i].xyz, p[(i - 4 + 1) % 4 + 4].xyz, data); | |||||
//Draw near to far | //Draw near to far | ||||
for (int i = 0; i < 4; i++) | for (int i = 0; i < 4; i++) | ||||
Debug::DrawLine(p[i].xyz, p[i + 4].xyz, color); | |||||
Debug::DrawLine(p[i].xyz, p[i + 4].xyz, data); | |||||
//Draw diagonal | //Draw diagonal | ||||
for (int i = 2; i < 6; i++) | for (int i = 2; i < 6; i++) | ||||
Debug::DrawLine(p[i].xyz, p[i + ((i < 4)?(-2):(+2))].xyz, color); | |||||
Debug::DrawLine(p[i].xyz, p[i + ((i < 4)?(-2):(+2))].xyz, data); | |||||
} | } | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -392,7 +392,11 @@ public: | |||||
- offset : useless | - offset : useless | ||||
*/ | */ | ||||
void AppendCog(int nbsides, float h, float d10, float d20, float d11, | void AppendCog(int nbsides, float h, float d10, float d20, float d11, | ||||
float d21, float d12, float d22, float sidemul=0.f, bool offset=false); | |||||
float d21, float d12, float d22, float sidemul = 0.f, bool offset = false); | |||||
void AppendCog(int nbsides, float h, vec2 d0, vec2 d1, vec2 d2, float sidemul = 0.f, bool offset = false) | |||||
{ | |||||
AppendCog(nbsides, h, d0.x, d0.y, d1.x, d1.y, d2.x, d2.y, sidemul, offset); | |||||
} | |||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
//TODO : Mesh Bone operations | //TODO : Mesh Bone operations | ||||
@@ -27,7 +27,7 @@ EasyMeshLuaLoader::EasyMeshLuaLoader() : LuaLoader() | |||||
lua_State* l = GetLuaState(); | lua_State* l = GetLuaState(); | ||||
//Registering demo object | //Registering demo object | ||||
LuaObjectDef::Register<EasyMeshLuaObject>(l); | |||||
LuaObjectHelper::Register<EasyMeshLuaObject>(l); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -81,17 +81,17 @@ EasyMeshLuaObject* EasyMeshLuaObject::New(lua_State* l, int arg_nb) | |||||
{ | { | ||||
UNUSED(l); | UNUSED(l); | ||||
UNUSED(arg_nb); | UNUSED(arg_nb); | ||||
LuaStack s(l); | |||||
LuaString n("", true); | |||||
s >> n; | |||||
return new EasyMeshLuaObject(n()); | |||||
LuaStack s = LuaStack::Begin(l); | |||||
String str = s.Get<String>(""); | |||||
return new EasyMeshLuaObject(str); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
const LuaObjectLib* EasyMeshLuaObject::GetLib() | |||||
const LuaObjectLibrary* EasyMeshLuaObject::GetLib() | |||||
{ | { | ||||
typedef EasyMeshLuaObject EMLO; | |||||
static const LuaObjectLib lib = LuaObjectLib( | |||||
#define EMLO EasyMeshLuaObject | |||||
static const LuaObjectLibrary lib = LuaObjectLibrary( | |||||
"EasyMesh", | "EasyMesh", | ||||
//Statics | //Statics | ||||
{ { nullptr, nullptr } }, | { { nullptr, nullptr } }, | ||||
@@ -182,6 +182,8 @@ const LuaObjectLib* EasyMeshLuaObject::GetLib() | |||||
//Variables | //Variables | ||||
{ { nullptr, nullptr, nullptr } }); | { { nullptr, nullptr, nullptr } }); | ||||
return &lib; | return &lib; | ||||
#undef EMLO | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -18,7 +18,6 @@ namespace lol | |||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
class EasyMeshLuaObject : public LuaObject | class EasyMeshLuaObject : public LuaObject | ||||
{ | { | ||||
typedef Lolua::VarPtr<EasyMeshLuaObject> EzMeshPtr; | |||||
EasyMesh m_instance; | EasyMesh m_instance; | ||||
public: | public: | ||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
@@ -28,610 +27,91 @@ public: | |||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
static EasyMeshLuaObject* New(lua_State* l, int arg_nb); | static EasyMeshLuaObject* New(lua_State* l, int arg_nb); | ||||
static const LuaObjectLib* GetLib(); | |||||
static const LuaObjectLibrary* GetLib(); | |||||
#define EMLO GetPtr<EasyMeshLuaObject>() | |||||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
static int AppendCylinder(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 nsides; | |||||
LuaFloat h, d1, d2; | |||||
LuaBool dualside(false, true), smooth(false, true), close(false, true); | |||||
s >> m >> nsides >> h >> d1 >> d2 >> dualside >> smooth >> close; | |||||
m->m_instance.AppendCylinder(nsides, h, d1, d2, dualside, smooth, close); | |||||
return 0; | |||||
} | |||||
static int AppendSphere(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 ndivisions; | |||||
LuaFloat d; | |||||
s >> m >> ndivisions >> d; | |||||
m->m_instance.AppendSphere(ndivisions, d); | |||||
return 0; | |||||
} | |||||
static int AppendCapsule(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 ndivisions; | |||||
LuaFloat h, d; | |||||
s >> m >> ndivisions >> h >> d; | |||||
m->m_instance.AppendCapsule(ndivisions, h, d); | |||||
return 0; | |||||
} | |||||
static int AppendTorus(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 ndivisions; | |||||
LuaFloat d1, d2; | |||||
s >> m >> ndivisions >> d1 >> d2; | |||||
m->m_instance.AppendTorus(ndivisions, d1, d2); | |||||
return 0; | |||||
} | |||||
static int AppendBox(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaVec3 size; | |||||
LuaFloat chamf(0.f, true); | |||||
LuaBool smooth(false, true); | |||||
s >> m >> size >> chamf >> smooth; | |||||
m->m_instance.AppendBox(size, chamf, smooth); | |||||
return 0; | |||||
} | |||||
static int AppendStar(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 nbranches; | |||||
LuaFloat d1, d2; | |||||
LuaBool fade(false, true), fade2(false, true); | |||||
s >> m >> nbranches >> d1 >> d2 >> fade >> fade2; | |||||
m->m_instance.AppendStar(nbranches, d1, d2, fade, fade2); | |||||
return 0; | |||||
} | |||||
static int AppendExpandedStar(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 nbranches; | |||||
LuaFloat d1, d2, extrad(0.f, true); | |||||
s >> m >> nbranches >> d1 >> d2 >> extrad; | |||||
m->m_instance.AppendExpandedStar(nbranches, d1, d2, extrad); | |||||
return 0; | |||||
} | |||||
static int AppendDisc(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 nsides; | |||||
LuaFloat d; | |||||
LuaBool fade(false, true); | |||||
s >> m >> nsides >> d >> fade; | |||||
m->m_instance.AppendDisc(nsides, d, fade); | |||||
return 0; | |||||
} | |||||
static int AppendSimpleTriangle(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat d; | |||||
LuaBool fade(false, true); | |||||
s >> m >> d >> fade; | |||||
m->m_instance.AppendSimpleTriangle(d, fade); | |||||
return 0; | |||||
} | |||||
static int AppendSimpleQuad(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat size; | |||||
LuaBool fade(false, true); | |||||
s >> m >> size >> fade; | |||||
m->m_instance.AppendSimpleQuad(size, fade); | |||||
return 0; | |||||
} | |||||
static int AppendCog(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 nbsides; | |||||
LuaFloat h, sidemul(0.f, true); | |||||
LuaVec2 d0, d1, d2; | |||||
LuaBool offset(false, true); | |||||
s >> m >> nbsides >> h >> d0 >> d1 >> d2 >> sidemul >> offset; | |||||
m->m_instance.AppendCog(nbsides, h, d0().x, d0().y, d1().x, d1().y, d2().x, d2().y, sidemul, offset); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int TranslateX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat f; | |||||
s >> m >> f; | |||||
m->m_instance.TranslateX(f); | |||||
return 0; | |||||
} | |||||
static int TranslateY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat f; | |||||
s >> m >> f; | |||||
m->m_instance.TranslateY(f); | |||||
return 0; | |||||
} | |||||
static int TranslateZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat f; | |||||
s >> m >> f; | |||||
m->m_instance.TranslateZ(f); | |||||
return 0; | |||||
} | |||||
static int Translate(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaVec3 v; | |||||
s >> m >> v; | |||||
m->m_instance.Translate(v); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int RotateX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat a; | |||||
s >> m >> a; | |||||
m->m_instance.RotateX(a); | |||||
return 0; | |||||
} | |||||
static int RotateY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat a; | |||||
s >> m >> a; | |||||
m->m_instance.RotateY(a); | |||||
return 0; | |||||
} | |||||
static int RotateZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat a; | |||||
s >> m >> a; | |||||
m->m_instance.RotateZ(a); | |||||
return 0; | |||||
} | |||||
static int Rotate(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat a; | |||||
LuaVec3 v; | |||||
s >> m >> a >> v; | |||||
m->m_instance.Rotate(a, v); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int ScaleX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x; | |||||
s >> m >> x; | |||||
m->m_instance.ScaleX(x); | |||||
return 0; | |||||
} | |||||
static int ScaleY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat y; | |||||
s >> m >> y; | |||||
m->m_instance.ScaleY(y); | |||||
return 0; | |||||
} | |||||
static int ScaleZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat z; | |||||
s >> m >> z; | |||||
m->m_instance.ScaleZ(z); | |||||
return 0; | |||||
} | |||||
static int Scale(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaVec3 v; | |||||
s >> m >> v; | |||||
m->m_instance.Scale(v); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int RadialJitter(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat f; | |||||
s >> m >> f; | |||||
m->m_instance.RadialJitter(f); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int TaperX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat y, z, xoff(0.f, true); | |||||
LuaBool abs(true, true); | |||||
s >> m >> y >> z >> xoff >> abs; | |||||
m->m_instance.TaperX(y, z, xoff, abs); | |||||
return 0; | |||||
} | |||||
static int TaperY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x, z, yoff(0.f, true); | |||||
LuaBool abs(true, true); | |||||
s >> m >> x >> z >> yoff >> abs; | |||||
m->m_instance.TaperY(x, z, yoff, abs); | |||||
return 0; | |||||
} | |||||
static int TaperZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x, y, zoff(0.f, true); | |||||
LuaBool abs(true, true); | |||||
s >> m >> x >> y >> zoff >> abs; | |||||
m->m_instance.TaperZ(x, y, zoff, abs); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int TwistX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.TwistX(t, toff); | |||||
return 0; | |||||
} | |||||
static int TwistY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.TwistY(t, toff); | |||||
return 0; | |||||
} | |||||
static int TwistZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.TwistZ(t, toff); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int ShearX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat y, z, xoff(0.f, true); | |||||
LuaBool abs(true, true); | |||||
s >> m >> y >> z >> xoff >> abs; | |||||
m->m_instance.ShearX(y, z, xoff, abs); | |||||
return 0; | |||||
} | |||||
static int ShearY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x, z, yoff(0.f, true); | |||||
LuaBool abs(true, true); | |||||
s >> m >> x >> z >> yoff >> abs; | |||||
m->m_instance.ShearY(x, z, yoff, abs); | |||||
return 0; | |||||
} | |||||
static int ShearZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x, y, zoff(0.f, true); | |||||
LuaBool abs(true, true); | |||||
s >> m >> x >> y >> zoff >> abs; | |||||
m->m_instance.ShearZ(x, y, zoff, abs); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int StretchX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat y, z, xoff(0.f, true); | |||||
s >> m >> y >> z >> xoff; | |||||
m->m_instance.StretchX(y, z, xoff); | |||||
return 0; | |||||
} | |||||
static int StretchY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x, z, yoff(0.f, true); | |||||
s >> m >> x >> z >> yoff; | |||||
m->m_instance.StretchY(x, z, yoff); | |||||
return 0; | |||||
} | |||||
static int StretchZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat x, y, zoff(0.f, true); | |||||
s >> m >> x >> y >> zoff; | |||||
m->m_instance.StretchZ(x, y, zoff); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int BendXY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.BendXY(t, toff); | |||||
return 0; | |||||
} | |||||
static int BendXZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.BendXZ(t, toff); | |||||
return 0; | |||||
} | |||||
static int BendYX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.BendYX(t, toff); | |||||
return 0; | |||||
} | |||||
static int BendYZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.BendYZ(t, toff); | |||||
return 0; | |||||
} | |||||
static int BendZX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.BendZX(t, toff); | |||||
return 0; | |||||
} | |||||
static int BendZY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat t, toff(0.f, true); | |||||
s >> m >> t >> toff; | |||||
m->m_instance.BendZY(t, toff); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int MirrorX(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.MirrorX(); | |||||
return 0; | |||||
} | |||||
static int MirrorY(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.MirrorY(); | |||||
return 0; | |||||
} | |||||
static int MirrorZ(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.MirrorZ(); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int LoopStart(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 loopnb; | |||||
s >> m >> loopnb; | |||||
m->m_instance.LoopStart(loopnb); | |||||
return 0; | |||||
} | |||||
static int LoopEnd(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.LoopEnd(); | |||||
return 0; | |||||
} | |||||
static int OpenBrace(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.OpenBrace(); | |||||
return 0; | |||||
} | |||||
static int CloseBrace(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.CloseBrace(); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int ToggleScaleWinding(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.ToggleScaleWinding(); | |||||
return 0; | |||||
} | |||||
static int ToggleQuadWeighting(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.ToggleQuadWeighting(); | |||||
return 0; | |||||
} | |||||
static int TogglePostBuildNormal(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.TogglePostBuildNormal(); | |||||
return 0; | |||||
} | |||||
static int ToggleVerticeNoCleanup(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.ToggleVerticeNoCleanup(); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int VerticesMerge(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.VerticesMerge(); | |||||
return 0; | |||||
} | |||||
static int VerticesSeparate(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.VerticesSeparate(); | |||||
return 0; | |||||
} | |||||
static int VerticesCleanup(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
s >> m; | |||||
m->m_instance.VerticesCleanup(); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int Duplicate(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaVec3 ds(vec3(1.f)); | |||||
s >> m >> ds; | |||||
m->m_instance.DupAndScale(ds, true); | |||||
return 0; | |||||
} | |||||
static int Smooth(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 pass, split_per_pass, smooth_per_pass; | |||||
s >> m >> pass >> split_per_pass >> smooth_per_pass; | |||||
m->m_instance.SmoothMesh(pass, split_per_pass, smooth_per_pass); | |||||
return 0; | |||||
} | |||||
static int SplitTriangles(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaInt32 pass; | |||||
s >> m >> pass; | |||||
m->m_instance.SplitTriangles(pass); | |||||
return 0; | |||||
} | |||||
static int Chamfer(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaFloat f; | |||||
s >> m >> f; | |||||
m->m_instance.Chamfer(f); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------- | |||||
static int SetCurColor(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaColor c; | |||||
s >> m >> c; | |||||
m->m_instance.SetCurColor(c); | |||||
return 0; | |||||
} | |||||
static int SetCurColorA(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaColor c; | |||||
s >> m >> c; | |||||
m->m_instance.SetCurColorA(c); | |||||
return 0; | |||||
} | |||||
static int SetCurColorB(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaColor c; | |||||
m->m_instance.SetCurColorB(c); | |||||
return 0; | |||||
} | |||||
static int SetVertColor(lua_State* l) | |||||
{ | |||||
LuaStack s(l); | |||||
EzMeshPtr m; | |||||
LuaColor c; | |||||
s >> m >> c; | |||||
m->m_instance.SetVertColor(c); | |||||
return 0; | |||||
} | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendCylinder, EMLO, m_instance.AppendCylinder, Get<int32_t>(), Get<float>(), Get<float>(), Get<float>(), Get<bool>(false), Get<bool>(false), Get<bool>(false)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendSphere, EMLO, m_instance.AppendSphere, Get<int32_t>(), Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendCapsule, EMLO, m_instance.AppendCapsule, Get<int32_t>(), Get<float>(), Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendTorus, EMLO, m_instance.AppendTorus, Get<int32_t>(), Get<float>(), Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendBox, EMLO, m_instance.AppendBox, Get<vec3>(), Get<float>(0.f), Get<bool>(false)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendStar, EMLO, m_instance.AppendStar, Get<int32_t>(), Get<float>(), Get<float>(), Get<bool>(false), Get<bool>(false)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendExpandedStar, EMLO, m_instance.AppendExpandedStar, Get<int32_t>(), Get<float>(), Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendDisc, EMLO, m_instance.AppendDisc, Get<int32_t>(), Get<float>(), Get<bool>(false)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendSimpleTriangle, EMLO, m_instance.AppendSimpleTriangle, Get<float>(), Get<bool>(false)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendSimpleQuad, EMLO, m_instance.AppendSimpleQuad, Get<float>(), Get<bool>(false)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(AppendCog, EMLO, m_instance.AppendCog, Get<int32_t>(), Get<float>(), Get<vec2>(), Get<vec2>(), Get<vec2>(), Get<float>(0.f), Get<bool>(false)); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TranslateX, EMLO, m_instance.TranslateX, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TranslateY, EMLO, m_instance.TranslateY, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TranslateZ, EMLO, m_instance.TranslateZ, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(Translate, EMLO, m_instance.Translate, Get<vec3>()); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(RotateX, EMLO, m_instance.RotateX, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(RotateY, EMLO, m_instance.RotateY, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(RotateZ, EMLO, m_instance.RotateZ, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(Rotate, EMLO, m_instance.Rotate, Get<float>(), Get<vec3>()); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(ScaleX, EMLO, m_instance.ScaleX, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(ScaleY, EMLO, m_instance.ScaleY, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(ScaleZ, EMLO, m_instance.ScaleZ, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(Scale, EMLO, m_instance.Scale, Get<vec3>()); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(RadialJitter, EMLO, m_instance.RadialJitter, Get<float>()); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TaperX, EMLO, m_instance.TaperX, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TaperY, EMLO, m_instance.TaperY, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TaperZ, EMLO, m_instance.TaperZ, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true)); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TwistX, EMLO, m_instance.TwistX, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TwistY, EMLO, m_instance.TwistY, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(TwistZ, EMLO, m_instance.TwistZ, Get<float>(), Get<float>(0.f)); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(ShearX, EMLO, m_instance.ShearX, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(ShearY, EMLO, m_instance.ShearY, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(ShearZ, EMLO, m_instance.ShearZ, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true)); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(StretchX, EMLO, m_instance.StretchX, Get<float>(), Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(StretchY, EMLO, m_instance.StretchY, Get<float>(), Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(StretchZ, EMLO, m_instance.StretchZ, Get<float>(), Get<float>(), Get<float>(0.f)); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(BendXY, EMLO, m_instance.BendXY, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(BendXZ, EMLO, m_instance.BendXZ, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(BendYX, EMLO, m_instance.BendYX, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(BendYZ, EMLO, m_instance.BendYZ, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(BendZX, EMLO, m_instance.BendZX, Get<float>(), Get<float>(0.f)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(BendZY, EMLO, m_instance.BendZY, Get<float>(), Get<float>(0.f)); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(MirrorX, EMLO, m_instance.MirrorX); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(MirrorY, EMLO, m_instance.MirrorY); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(MirrorZ, EMLO, m_instance.MirrorZ); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(LoopStart, EMLO, m_instance.LoopStart, Get<int32_t>()); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(LoopEnd, EMLO, m_instance.LoopEnd); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(OpenBrace, EMLO, m_instance.OpenBrace, Get<float>()); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(CloseBrace, EMLO, m_instance.CloseBrace, Get<float>()); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(ToggleScaleWinding, EMLO, m_instance.ToggleScaleWinding); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(ToggleQuadWeighting, EMLO, m_instance.ToggleQuadWeighting); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(TogglePostBuildNormal, EMLO, m_instance.TogglePostBuildNormal); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(ToggleVerticeNoCleanup, EMLO, m_instance.ToggleVerticeNoCleanup); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(VerticesMerge, EMLO, m_instance.VerticesMerge); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(VerticesSeparate, EMLO, m_instance.VerticesSeparate); | |||||
LOLUA_DECLARE_VOID_METHOD_VOID(VerticesCleanup, EMLO, m_instance.VerticesCleanup); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(Duplicate, EMLO, m_instance.DupAndScale, Get<vec3>(vec3(1.f)), Get<bool>(true)); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(Smooth, EMLO, m_instance.SmoothMesh, Get<int32_t>(), Get<int32_t>(), Get<int32_t>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(SplitTriangles, EMLO, m_instance.SplitTriangles, Get<int32_t>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(Chamfer, EMLO, m_instance.Chamfer, Get<float>()); | |||||
//------------------------------------------------------------------------- | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(SetCurColor, EMLO, m_instance.SetCurColor, Get<vec4>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(SetCurColorA, EMLO, m_instance.SetCurColorA, Get<vec4>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(SetCurColorB, EMLO, m_instance.SetCurColorB, Get<vec4>()); | |||||
LOLUA_DECLARE_VOID_METHOD_ARGS(SetVertColor, EMLO, m_instance.SetVertColor, Get<vec4>()); | |||||
/* | /* | ||||
(csgu|csgunion) { return token::T_CSGUNION; } | (csgu|csgunion) { return token::T_CSGUNION; } | ||||
(csgs|CsgSub) { return token::T_CSGSUBSTRACT; } | (csgs|CsgSub) { return token::T_CSGSUBSTRACT; } | ||||
@@ -640,6 +120,7 @@ public: | |||||
(csgx|csgxor) { return token::T_CSGXOR; } | (csgx|csgxor) { return token::T_CSGXOR; } | ||||
*/ | */ | ||||
#undef EMLO | |||||
}; | }; | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -343,14 +345,14 @@ ivec2 Framebuffer::GetSize() const | |||||
return m_data->m_size; | return m_data->m_size; | ||||
} | } | ||||
Image Framebuffer::GetImage() const | |||||
image Framebuffer::GetImage() const | |||||
{ | { | ||||
Image ret(m_data->m_size); | |||||
image ret(m_data->m_size); | |||||
u8vec4 *buffer = ret.Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *buffer = ret.lock<PixelFormat::RGBA_8>(); | |||||
glReadPixels(0, 0, m_data->m_size.x, m_data->m_size.y, | glReadPixels(0, 0, m_data->m_size.x, m_data->m_size.y, | ||||
GL_RGBA, GL_UNSIGNED_BYTE, buffer); | GL_RGBA, GL_UNSIGNED_BYTE, buffer); | ||||
ret.Unlock(buffer); | |||||
ret.unlock(buffer); | |||||
return ret; | return ret; | ||||
} | } | ||||
@@ -59,6 +59,8 @@ private: | |||||
TrackedState<DepthMask> m_depth_mask; | TrackedState<DepthMask> m_depth_mask; | ||||
TrackedState<CullMode> m_cull_mode; | TrackedState<CullMode> m_cull_mode; | ||||
TrackedState<PolygonMode> m_polygon_mode; | TrackedState<PolygonMode> m_polygon_mode; | ||||
TrackedState<ScissorMode> m_scissor_mode; | |||||
TrackedState<vec4> m_scissor_rect; | |||||
}; | }; | ||||
/* | /* | ||||
@@ -101,6 +103,9 @@ RenderContext::~RenderContext() | |||||
if (m_data->m_polygon_mode.HasChanged()) | if (m_data->m_polygon_mode.HasChanged()) | ||||
Renderer::Get()->SetPolygonMode(m_data->m_polygon_mode.GetValue()); | Renderer::Get()->SetPolygonMode(m_data->m_polygon_mode.GetValue()); | ||||
if (m_data->m_scissor_mode.HasChanged()) | |||||
Renderer::Get()->SetScissorMode(m_data->m_scissor_mode.GetValue()); | |||||
delete m_data; | delete m_data; | ||||
} | } | ||||
@@ -255,5 +260,31 @@ PolygonMode RenderContext::GetPolygonMode() | |||||
return Renderer::Get()->GetPolygonMode(); | return Renderer::Get()->GetPolygonMode(); | ||||
} | } | ||||
void RenderContext::SetScissorMode(ScissorMode mode) | |||||
{ | |||||
if (!m_data->m_scissor_mode.HasChanged()) | |||||
m_data->m_scissor_mode.TrackValue(Renderer::Get()->GetScissorMode()); | |||||
Renderer::Get()->SetScissorMode(mode); | |||||
} | |||||
void RenderContext::SetScissorRect(vec4 rect) | |||||
{ | |||||
if (!m_data->m_scissor_rect.HasChanged()) | |||||
m_data->m_scissor_rect.TrackValue(Renderer::Get()->GetScissorRect()); | |||||
Renderer::Get()->SetScissorRect(rect); | |||||
} | |||||
ScissorMode RenderContext::GetScissorMode() | |||||
{ | |||||
return Renderer::Get()->GetScissorMode(); | |||||
} | |||||
vec4 RenderContext::GetScissorRect() | |||||
{ | |||||
return Renderer::Get()->GetScissorRect(); | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -54,6 +54,8 @@ private: | |||||
DepthMask m_depth_mask; | DepthMask m_depth_mask; | ||||
CullMode m_cull_mode; | CullMode m_cull_mode; | ||||
PolygonMode m_polygon_mode; | PolygonMode m_polygon_mode; | ||||
ScissorMode m_scissor_mode; | |||||
vec4 m_scissor_rect; | |||||
}; | }; | ||||
/* | /* | ||||
@@ -107,6 +109,9 @@ Renderer::Renderer(ivec2 size) | |||||
m_data->m_polygon_mode = PolygonMode::Point; | m_data->m_polygon_mode = PolygonMode::Point; | ||||
SetPolygonMode(PolygonMode::Fill); | SetPolygonMode(PolygonMode::Fill); | ||||
m_data->m_scissor_mode = ScissorMode::Disabled; | |||||
SetPolygonMode(PolygonMode::Fill); | |||||
/* Add some rendering states that we don't export to the user */ | /* Add some rendering states that we don't export to the user */ | ||||
#if defined HAVE_GL_2X && !defined __APPLE__ | #if defined HAVE_GL_2X && !defined __APPLE__ | ||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); | ||||
@@ -548,5 +553,42 @@ PolygonMode Renderer::GetPolygonMode() const | |||||
return m_data->m_polygon_mode; | return m_data->m_polygon_mode; | ||||
} | } | ||||
/* | |||||
* Scissor test mode | |||||
*/ | |||||
void Renderer::SetScissorMode(ScissorMode mode) | |||||
{ | |||||
if (m_data->m_scissor_mode == mode) | |||||
return; | |||||
if (mode == ScissorMode::Enabled) | |||||
glEnable(GL_SCISSOR_TEST); | |||||
else | |||||
glDisable(GL_SCISSOR_TEST); | |||||
m_data->m_scissor_mode = mode; | |||||
} | |||||
void Renderer::SetScissorRect(vec4 rect) | |||||
{ | |||||
m_data->m_scissor_rect = rect; | |||||
if (m_data->m_scissor_mode == ScissorMode::Enabled) | |||||
{ | |||||
glScissor((int)rect.x, (int)Video::GetSize().y - rect.w, (int)(rect.z - rect.x), (int)(rect.w - rect.y)); | |||||
//glScissor((int)rect.x, (int)rect.y, (int)(rect.z - rect.x), (int)(rect.w - rect.y)); | |||||
} | |||||
} | |||||
ScissorMode Renderer::GetScissorMode() const | |||||
{ | |||||
return m_data->m_scissor_mode; | |||||
} | |||||
vec4 Renderer::GetScissorRect() const | |||||
{ | |||||
return m_data->m_scissor_rect; | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -21,7 +21,7 @@ extern "C" { | |||||
#include <android_native_app_glue.h> | #include <android_native_app_glue.h> | ||||
} | } | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -32,12 +32,12 @@ extern ANativeActivity *g_activity; | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class AndroidImageCodec : public ImageCodec | |||||
class AndroidImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<AndroidImageCodec>"; } | virtual char const *GetName() { return "<AndroidImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
virtual bool Close(); | virtual bool Close(); | ||||
virtual uint8_t *GetData() const; | virtual uint8_t *GetData() const; | ||||
@@ -50,7 +50,7 @@ private: | |||||
DECLARE_IMAGE_CODEC(AndroidImageCodec, 100) | DECLARE_IMAGE_CODEC(AndroidImageCodec, 100) | ||||
bool AndroidImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* AndroidImageCodec::Load(char const *path) | |||||
{ | { | ||||
JNIEnv *env; | JNIEnv *env; | ||||
jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); | jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); | ||||
@@ -106,12 +106,12 @@ bool AndroidImageCodec::Load(Image *image, char const *path) | |||||
} | } | ||||
m_format = PixelFormat::RGBA_8; | m_format = PixelFormat::RGBA_8; | ||||
return true; | |||||
return new ResourceCodecData(); | |||||
} | } | ||||
bool AndroidImageCodec::Save(Image *image, char const *path) | |||||
bool AndroidImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
UNUSED(path); | |||||
UNUSED(path, data); | |||||
/* TODO: unimplemented */ | /* TODO: unimplemented */ | ||||
} | } | ||||
@@ -1,16 +1,18 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -19,12 +21,12 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class DummyImageCodec : public ImageCodec | |||||
class DummyImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<DummyImageCodec>"; } | virtual char const *GetName() { return "<DummyImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
}; | }; | ||||
//Priority 0 because it's supposed to be the last one | //Priority 0 because it's supposed to be the last one | ||||
@@ -34,12 +36,14 @@ DECLARE_IMAGE_CODEC(DummyImageCodec, 0) | |||||
* Public Image class | * Public Image class | ||||
*/ | */ | ||||
bool DummyImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* DummyImageCodec::Load(char const *path) | |||||
{ | { | ||||
UNUSED(path); | |||||
if (strcmp("DUMMY", path)) | |||||
return nullptr; | |||||
image->SetSize(ivec2(256)); | |||||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(), *tmp = pixels; | |||||
auto data = new ResourceImageData(new image(ivec2(256))); | |||||
auto image = data->m_image; | |||||
u8vec4 *pixels = image->lock<PixelFormat::RGBA_8>(), *tmp = pixels; | |||||
for (int j = 0; j < 256; j++) | for (int j = 0; j < 256; j++) | ||||
for (int i = 0; i < 256; i++) | for (int i = 0; i < 256; i++) | ||||
{ | { | ||||
@@ -49,15 +53,14 @@ bool DummyImageCodec::Load(Image *image, char const *path) | |||||
tmp->a = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; | tmp->a = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; | ||||
++tmp; | ++tmp; | ||||
} | } | ||||
image->Unlock(pixels); | |||||
image->unlock(pixels); | |||||
//return false, because we're not supposed to be here. | |||||
return false; | |||||
return data; | |||||
} | } | ||||
bool DummyImageCodec::Save(Image *image, char const *path) | |||||
bool DummyImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
UNUSED(path); | |||||
UNUSED(path, data); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -26,7 +26,7 @@ using std::max; | |||||
#if LOL_USE_GDIPLUS | #if LOL_USE_GDIPLUS | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -35,12 +35,12 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class GdiPlusImageCodec : public ImageCodec | |||||
class GdiPlusImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<GdiPlusImageCodec>"; } | virtual char const *GetName() { return "<GdiPlusImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
}; | }; | ||||
DECLARE_IMAGE_CODEC(GdiPlusImageCodec, 100) | DECLARE_IMAGE_CODEC(GdiPlusImageCodec, 100) | ||||
@@ -49,7 +49,7 @@ DECLARE_IMAGE_CODEC(GdiPlusImageCodec, 100) | |||||
* Public Image class | * Public Image class | ||||
*/ | */ | ||||
bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* GdiPlusImageCodec::Load(char const *path) | |||||
{ | { | ||||
Gdiplus::Status status; | Gdiplus::Status status; | ||||
ULONG_PTR token; | ULONG_PTR token; | ||||
@@ -58,7 +58,7 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||||
if (status != Gdiplus::Ok) | if (status != Gdiplus::Ok) | ||||
{ | { | ||||
msg::error("error %d while initialising GDI+\n", status); | msg::error("error %d while initialising GDI+\n", status); | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
array<String> pathlist = sys::get_path_list(path); | array<String> pathlist = sys::get_path_list(path); | ||||
@@ -99,7 +99,7 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||||
if (!bitmap) | if (!bitmap) | ||||
{ | { | ||||
msg::error("could not load %s\n", path); | msg::error("could not load %s\n", path); | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
ivec2 size(bitmap->GetWidth(), bitmap->GetHeight()); | ivec2 size(bitmap->GetWidth(), bitmap->GetHeight()); | ||||
@@ -110,27 +110,32 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||||
{ | { | ||||
msg::error("could not lock bits in %s\n", path); | msg::error("could not lock bits in %s\n", path); | ||||
delete bitmap; | delete bitmap; | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
/* FIXME: GDI+ doesn't know about RGBA, only ARGB. And OpenGL doesn't | /* FIXME: GDI+ doesn't know about RGBA, only ARGB. And OpenGL doesn't | ||||
* know about ARGB, only RGBA. So we swap bytes. We could also fix | * know about ARGB, only RGBA. So we swap bytes. We could also fix | ||||
* this in the shader. */ | * this in the shader. */ | ||||
image->SetSize(size); | |||||
u8vec4 *pdst = image->Lock<PixelFormat::RGBA_8>(); | |||||
auto data = new ResourceImageData(new image(ivec2(size))); | |||||
auto image = data->m_image; | |||||
u8vec4 *pdst = image->lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *psrc = static_cast<u8vec4 *>(bdata.Scan0); | u8vec4 *psrc = static_cast<u8vec4 *>(bdata.Scan0); | ||||
for (int n = 0; n < size.x * size.y; n++) | for (int n = 0; n < size.x * size.y; n++) | ||||
pdst[n] = psrc[n].bgra; | pdst[n] = psrc[n].bgra; | ||||
image->Unlock(pdst); | |||||
image->unlock(pdst); | |||||
bitmap->UnlockBits(&bdata); | bitmap->UnlockBits(&bdata); | ||||
delete bitmap; | delete bitmap; | ||||
return true; | |||||
return data; | |||||
} | } | ||||
bool GdiPlusImageCodec::Save(Image *image, char const *path) | |||||
bool GdiPlusImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||||
if (data_image == nullptr) | |||||
return false; | |||||
ULONG_PTR token; | ULONG_PTR token; | ||||
Gdiplus::GdiplusStartupInput input; | Gdiplus::GdiplusStartupInput input; | ||||
Gdiplus::GdiplusStartup(&token, &input, nullptr); | Gdiplus::GdiplusStartup(&token, &input, nullptr); | ||||
@@ -178,7 +183,8 @@ bool GdiPlusImageCodec::Save(Image *image, char const *path) | |||||
return false; | return false; | ||||
} | } | ||||
ivec2 size = image->GetSize(); | |||||
auto image = data_image->m_image; | |||||
ivec2 size = image->size(); | |||||
Gdiplus::Bitmap *b = new Gdiplus::Bitmap(size.x, size.y, | Gdiplus::Bitmap *b = new Gdiplus::Bitmap(size.x, size.y, | ||||
PixelFormat32bppARGB); | PixelFormat32bppARGB); | ||||
@@ -195,13 +201,13 @@ bool GdiPlusImageCodec::Save(Image *image, char const *path) | |||||
return false; | return false; | ||||
} | } | ||||
u8vec4 *psrc = image->Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *psrc = image->lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *psrc0 = psrc; | u8vec4 *psrc0 = psrc; | ||||
u8vec4 *pdst = static_cast<u8vec4 *>(bdata.Scan0); | u8vec4 *pdst = static_cast<u8vec4 *>(bdata.Scan0); | ||||
for (int y = 0; y < size.y; y++) | for (int y = 0; y < size.y; y++) | ||||
for (int x = 0; x < size.x; x++) | for (int x = 0; x < size.x; x++) | ||||
*pdst++ = (*psrc++).bgra; | *pdst++ = (*psrc++).bgra; | ||||
image->Unlock(psrc0); | |||||
image->unlock(psrc0); | |||||
b->UnlockBits(&bdata); | b->UnlockBits(&bdata); | ||||
if (b->Save(wpath, &clsid, nullptr) != Gdiplus::Ok) | if (b->Save(wpath, &clsid, nullptr) != Gdiplus::Ok) | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -22,7 +22,7 @@ static_assert(sizeof(DATA32) == sizeof(uint32_t), "Imlib2 type DATA32 is broken" | |||||
static_assert(sizeof(DATA16) == sizeof(uint16_t), "Imlib2 type DATA16 is broken"); | static_assert(sizeof(DATA16) == sizeof(uint16_t), "Imlib2 type DATA16 is broken"); | ||||
static_assert(sizeof(DATA8) == sizeof(uint8_t), "Imlib2 type DATA8 is broken"); | static_assert(sizeof(DATA8) == sizeof(uint8_t), "Imlib2 type DATA8 is broken"); | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -31,17 +31,18 @@ namespace lol | |||||
* Imlib2 image codec | * Imlib2 image codec | ||||
*/ | */ | ||||
class Imlib2ImageCodec : public ImageCodec | |||||
class Imlib2ImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual char const *GetName() { return "<Imlib2ImageCodec>"; } | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
}; | }; | ||||
/* Set priority higher than SDL because we can save in many formats. */ | /* Set priority higher than SDL because we can save in many formats. */ | ||||
DECLARE_IMAGE_CODEC(Imlib2ImageCodec, 70) | DECLARE_IMAGE_CODEC(Imlib2ImageCodec, 70) | ||||
bool Imlib2ImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData *Imlib2ImageCodec::Load(char const *path) | |||||
{ | { | ||||
Imlib_Image im = nullptr; | Imlib_Image im = nullptr; | ||||
@@ -57,7 +58,7 @@ bool Imlib2ImageCodec::Load(Image *image, char const *path) | |||||
#if !LOL_BUILD_RELEASE | #if !LOL_BUILD_RELEASE | ||||
msg::error("could not load image %s\n", path); | msg::error("could not load image %s\n", path); | ||||
#endif | #endif | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
imlib_context_set_image(im); | imlib_context_set_image(im); | ||||
@@ -69,13 +70,14 @@ bool Imlib2ImageCodec::Load(Image *image, char const *path) | |||||
#if !LOL_BUILD_RELEASE | #if !LOL_BUILD_RELEASE | ||||
msg::error("could not get image data for %s\n", path); | msg::error("could not get image data for %s\n", path); | ||||
#endif | #endif | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
ivec2 size(imlib_image_get_width(), imlib_image_get_height()); | ivec2 size(imlib_image_get_width(), imlib_image_get_height()); | ||||
image->SetSize(size); | |||||
auto data = new ResourceImageData(new image(size)); | |||||
auto image = data->m_image; | |||||
u8vec4 *dstdata = image->Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *dstdata = image->lock<PixelFormat::RGBA_8>(); | |||||
for (int i = 0; i < size.x * size.y; i++) | for (int i = 0; i < size.x * size.y; i++) | ||||
{ | { | ||||
@@ -84,22 +86,27 @@ bool Imlib2ImageCodec::Load(Image *image, char const *path) | |||||
else | else | ||||
dstdata[i] = srcdata[i].bgra; | dstdata[i] = srcdata[i].bgra; | ||||
} | } | ||||
image->Unlock(dstdata); | |||||
image->unlock(dstdata); | |||||
imlib_free_image(); | imlib_free_image(); | ||||
return true; | |||||
return data; | |||||
} | } | ||||
bool Imlib2ImageCodec::Save(Image *image, char const *path) | |||||
bool Imlib2ImageCodec::Save(char const *path, ResourceCodecData *data) | |||||
{ | { | ||||
ivec2 size = image->GetSize(); | |||||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||||
if (data_image == nullptr) | |||||
return false; | |||||
auto image = data_image->m_image; | |||||
ivec2 size = image->size(); | |||||
Imlib_Image priv = imlib_create_image(size.x, size.y); | Imlib_Image priv = imlib_create_image(size.x, size.y); | ||||
imlib_context_set_image(priv); | imlib_context_set_image(priv); | ||||
imlib_image_set_has_alpha(1); | imlib_image_set_has_alpha(1); | ||||
u8vec4 const *srcdata = image->Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 const *srcdata = image->lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *dstdata = (u8vec4 *)imlib_image_get_data(); | u8vec4 *dstdata = (u8vec4 *)imlib_image_get_data(); | ||||
for (int i = 0; i < size.x * size.y; i++) | for (int i = 0; i < size.x * size.y; i++) | ||||
@@ -111,7 +118,7 @@ bool Imlib2ImageCodec::Save(Image *image, char const *path) | |||||
} | } | ||||
imlib_image_put_back_data((DATA32 *)dstdata); | imlib_image_put_back_data((DATA32 *)dstdata); | ||||
image->Unlock(srcdata); | |||||
image->unlock(srcdata); | |||||
imlib_save_image(path); | imlib_save_image(path); | ||||
imlib_free_image(); | imlib_free_image(); | ||||
@@ -16,7 +16,7 @@ | |||||
#import <UIKit/UIKit.h> | #import <UIKit/UIKit.h> | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -25,12 +25,12 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class IosImageCodec : public ImageCodec | |||||
class IosImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<IosImageCodec>"; } | virtual char const *GetName() { return "<IosImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
}; | }; | ||||
DECLARE_IMAGE_CODEC(IosImageCodec, 100) | DECLARE_IMAGE_CODEC(IosImageCodec, 100) | ||||
@@ -39,7 +39,7 @@ DECLARE_IMAGE_CODEC(IosImageCodec, 100) | |||||
* Public Image class | * Public Image class | ||||
*/ | */ | ||||
bool IosImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* IosImageCodec::Load(char const *path) | |||||
{ | { | ||||
NSString *fullpath = [NSString stringWithUTF8String:path]; | NSString *fullpath = [NSString stringWithUTF8String:path]; | ||||
NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; | NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; | ||||
@@ -54,7 +54,7 @@ bool IosImageCodec::Load(Image *image, char const *path) | |||||
#if !LOL_BUILD_RELEASE | #if !LOL_BUILD_RELEASE | ||||
msg::error("could not load %s\n", path); | msg::error("could not load %s\n", path); | ||||
#endif | #endif | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
int w = CGImageGetWidth(image.CGImage); | int w = CGImageGetWidth(image.CGImage); | ||||
@@ -75,12 +75,12 @@ bool IosImageCodec::Load(Image *image, char const *path) | |||||
[image release]; | [image release]; | ||||
[pngdata release]; | [pngdata release]; | ||||
return true; | |||||
return new ResourceCodecData(); | |||||
} | } | ||||
bool IosImageCodec::Save(Image *image, char const *path) | |||||
bool IosImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
UNUSED(path); | |||||
UNUSED(path, data); | |||||
/* TODO: unimplemented */ | /* TODO: unimplemented */ | ||||
return true; | return true; | ||||
@@ -1,18 +1,20 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
#include <cctype> | #include <cctype> | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -27,16 +29,16 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class OricImageCodec : public ImageCodec | |||||
class OricImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<OricImageCodec>"; } | virtual char const *GetName() { return "<OricImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
private: | private: | ||||
static String ReadScreen(char const *name); | static String ReadScreen(char const *name); | ||||
static void WriteScreen(Image &image, array<uint8_t> &result); | |||||
static void WriteScreen(image &image, array<uint8_t> &result); | |||||
}; | }; | ||||
DECLARE_IMAGE_CODEC(OricImageCodec, 100) | DECLARE_IMAGE_CODEC(OricImageCodec, 100) | ||||
@@ -45,7 +47,7 @@ DECLARE_IMAGE_CODEC(OricImageCodec, 100) | |||||
* Public Image class | * Public Image class | ||||
*/ | */ | ||||
bool OricImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* OricImageCodec::Load(char const *path) | |||||
{ | { | ||||
static u8vec4 const pal[8] = | static u8vec4 const pal[8] = | ||||
{ | { | ||||
@@ -61,13 +63,14 @@ bool OricImageCodec::Load(Image *image, char const *path) | |||||
String screen = ReadScreen(path); | String screen = ReadScreen(path); | ||||
if (screen.count() == 0) | if (screen.count() == 0) | ||||
return false; | |||||
return nullptr; | |||||
image->SetSize(ivec2(WIDTH, screen.count() * 6 / WIDTH)); | |||||
auto data = new ResourceImageData(new image(ivec2(WIDTH, screen.count() * 6 / WIDTH))); | |||||
auto img = data->m_image; | |||||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *pixels = img->lock<PixelFormat::RGBA_8>(); | |||||
for (int y = 0; y < image->GetSize().y; y++) | |||||
for (int y = 0; y < img->size().y; y++) | |||||
{ | { | ||||
u8vec2 bgfg(0, 7); | u8vec2 bgfg(0, 7); | ||||
@@ -100,14 +103,18 @@ bool OricImageCodec::Load(Image *image, char const *path) | |||||
} | } | ||||
} | } | ||||
image->Unlock(pixels); | |||||
img->unlock(pixels); | |||||
return true; | |||||
return data; | |||||
} | } | ||||
bool OricImageCodec::Save(Image *image, char const *path) | |||||
bool OricImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
int len = strlen(path); | |||||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||||
if (data_image == nullptr) | |||||
return false; | |||||
int len = (int)strlen(path); | |||||
if (len < 4 || path[len - 4] != '.' | if (len < 4 || path[len - 4] != '.' | ||||
|| toupper(path[len - 3]) != 'T' | || toupper(path[len - 3]) != 'T' | ||||
|| toupper(path[len - 2]) != 'A' | || toupper(path[len - 2]) != 'A' | ||||
@@ -124,17 +131,18 @@ bool OricImageCodec::Save(Image *image, char const *path) | |||||
result << (uint8_t)name[0]; | result << (uint8_t)name[0]; | ||||
result << 0; | result << 0; | ||||
Image tmp; | |||||
ivec2 size = image->GetSize(); | |||||
auto img = data_image->m_image; | |||||
image tmp; | |||||
ivec2 size = img->size(); | |||||
if (size.x != WIDTH) | if (size.x != WIDTH) | ||||
{ | { | ||||
size.y = (int)((float)size.y * WIDTH / size.x); | size.y = (int)((float)size.y * WIDTH / size.x); | ||||
size.x = WIDTH; | size.x = WIDTH; | ||||
tmp = image->Resize(size, ResampleAlgorithm::Bresenham); | |||||
image = &tmp; | |||||
tmp = img->Resize(size, ResampleAlgorithm::Bresenham); | |||||
img = &tmp; | |||||
} | } | ||||
WriteScreen(*image, result); | |||||
WriteScreen(*img, result); | |||||
File f; | File f; | ||||
f.Open(path, FileAccess::Write); | f.Open(path, FileAccess::Write); | ||||
@@ -463,10 +471,10 @@ static uint8_t bestmove(ivec3 const *in, u8vec2 bgfg, | |||||
return bestcommand; | return bestcommand; | ||||
} | } | ||||
void OricImageCodec::WriteScreen(Image &image, array<uint8_t> &result) | |||||
void OricImageCodec::WriteScreen(image &img, array<uint8_t> &result) | |||||
{ | { | ||||
ivec2 size = image.GetSize(); | |||||
vec4 *pixels = image.Lock<PixelFormat::RGBA_F32>(); | |||||
ivec2 size = img.size(); | |||||
vec4 *pixels = img.lock<PixelFormat::RGBA_F32>(); | |||||
int stride = (size.x + 1); | int stride = (size.x + 1); | ||||
@@ -481,7 +489,7 @@ void OricImageCodec::WriteScreen(Image &image, array<uint8_t> &result) | |||||
for (int y = 0; y < size.y; y++) | for (int y = 0; y < size.y; y++) | ||||
for (int x = 0; x < size.x; x++) | for (int x = 0; x < size.x; x++) | ||||
for (int c = 0; c < 3; c++) | for (int c = 0; c < 3; c++) | ||||
src[x][y][c] = 0xffff * pixels[y * size.x + x][2 - c]; | |||||
src[x][y][c] = 0xffff * (int32_t)pixels[y * size.x + x][2 - c]; | |||||
/* Let the fun begin */ | /* Let the fun begin */ | ||||
for (int y = 0; y < size.y; y++) | for (int y = 0; y < size.y; y++) | ||||
@@ -520,7 +528,7 @@ void OricImageCodec::WriteScreen(Image &image, array<uint8_t> &result) | |||||
} | } | ||||
} | } | ||||
image.Unlock(pixels); | |||||
img.unlock(pixels); | |||||
//fprintf(stderr, " done.\n"); | //fprintf(stderr, " done.\n"); | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -25,7 +25,7 @@ | |||||
# include <SDL_image.h> | # include <SDL_image.h> | ||||
#endif | #endif | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -34,19 +34,19 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class SdlImageCodec : public ImageCodec | |||||
class SdlImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<SdlImageCodec>"; } | virtual char const *GetName() { return "<SdlImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
static SDL_Surface *Create32BppSurface(ivec2 size); | static SDL_Surface *Create32BppSurface(ivec2 size); | ||||
}; | }; | ||||
DECLARE_IMAGE_CODEC(SdlImageCodec, 50) | DECLARE_IMAGE_CODEC(SdlImageCodec, 50) | ||||
bool SdlImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* SdlImageCodec::Load(char const *path) | |||||
{ | { | ||||
SDL_Surface *surface = nullptr; | SDL_Surface *surface = nullptr; | ||||
@@ -62,7 +62,7 @@ bool SdlImageCodec::Load(Image *image, char const *path) | |||||
#if !LOL_BUILD_RELEASE | #if !LOL_BUILD_RELEASE | ||||
msg::error("could not load image %s\n", path); | msg::error("could not load image %s\n", path); | ||||
#endif | #endif | ||||
return false; | |||||
return nullptr; | |||||
} | } | ||||
ivec2 size(surface->w, surface->h); | ivec2 size(surface->w, surface->h); | ||||
@@ -75,24 +75,30 @@ bool SdlImageCodec::Load(Image *image, char const *path) | |||||
surface = tmp; | surface = tmp; | ||||
} | } | ||||
image->SetSize(size); | |||||
u8vec4 *data = image->Lock<PixelFormat::RGBA_8>(); | |||||
memcpy(data, surface->pixels, 4 * size.x * size.y); | |||||
image->Unlock(data); | |||||
auto data = new ResourceImageData(new image(size)); | |||||
auto image = data->m_image; | |||||
u8vec4 *pixel_data = image->lock<PixelFormat::RGBA_8>(); | |||||
memcpy(pixel_data, surface->pixels, 4 * size.x * size.y); | |||||
image->unlock(pixel_data); | |||||
SDL_FreeSurface(surface); | SDL_FreeSurface(surface); | ||||
return true; | |||||
return data; | |||||
} | } | ||||
bool SdlImageCodec::Save(Image *image, char const *path) | |||||
bool SdlImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
ivec2 size = image->GetSize(); | |||||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||||
if (data_image == nullptr) | |||||
return false; | |||||
auto image = data_image->m_image; | |||||
ivec2 size = image->size(); | |||||
SDL_Surface *surface = Create32BppSurface(size); | SDL_Surface *surface = Create32BppSurface(size); | ||||
u8vec4 *data = image->Lock<PixelFormat::RGBA_8>(); | |||||
memcpy(surface->pixels, data, 4 * size.x * size.y); | |||||
image->Unlock(data); | |||||
u8vec4 *pixel_data = image->lock<PixelFormat::RGBA_8>(); | |||||
memcpy(surface->pixels, pixel_data, 4 * size.x * size.y); | |||||
image->unlock(pixel_data); | |||||
int ret = SDL_SaveBMP(surface, path); | int ret = SDL_SaveBMP(surface, path); | ||||
SDL_FreeSurface(surface); | SDL_FreeSurface(surface); | ||||
@@ -1,17 +1,19 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2014 Benjamin Huet <huet.benjamin@gmail.com> | |||||
// 2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// 2014 Benjamin Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -20,24 +22,12 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class ZedImageCodec : public ImageCodec | |||||
class ZedImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<ZedImageCodec>"; } | virtual char const *GetName() { return "<ZedImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual bool RetrieveTiles(array<ivec2, ivec2>& tiles) | |||||
{ | |||||
bool result = m_tiles.count() > 0; | |||||
tiles += m_tiles; | |||||
m_tiles.empty(); | |||||
return result; | |||||
} | |||||
private: | |||||
//<Pos, Size> | |||||
array<ivec2, ivec2> m_tiles; | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
}; | }; | ||||
DECLARE_IMAGE_CODEC(ZedImageCodec, 10) | DECLARE_IMAGE_CODEC(ZedImageCodec, 10) | ||||
@@ -46,17 +36,17 @@ DECLARE_IMAGE_CODEC(ZedImageCodec, 10) | |||||
* Public Image class | * Public Image class | ||||
*/ | */ | ||||
bool ZedImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* ZedImageCodec::Load(char const *path) | |||||
{ | { | ||||
if (!lol::String(path).ends_with(".RSC")) | if (!lol::String(path).ends_with(".RSC")) | ||||
return false; | |||||
return nullptr; | |||||
// Compacter definition | // Compacter definition | ||||
struct CompactSecondary | struct CompactSecondary | ||||
{ | { | ||||
CompactSecondary(int32_t size) { m_size = size; } | CompactSecondary(int32_t size) { m_size = size; } | ||||
int32_t m_size; | |||||
array<int32_t> m_tiles; | |||||
int32_t m_size; | |||||
array<int32_t> m_tiles; | |||||
}; | }; | ||||
struct CompactMain | struct CompactMain | ||||
{ | { | ||||
@@ -120,7 +110,7 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
file.Open(path, FileAccess::Read, true); | file.Open(path, FileAccess::Read, true); | ||||
//Put file in memory | //Put file in memory | ||||
long file_size = file.GetSize(); | |||||
long file_size = file.size(); | |||||
array<uint8_t> file_buffer; | array<uint8_t> file_buffer; | ||||
file_buffer.resize(file_size); | file_buffer.resize(file_size); | ||||
file.Read((uint8_t*)&file_buffer[0], file_size); | file.Read((uint8_t*)&file_buffer[0], file_size); | ||||
@@ -142,7 +132,9 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
} | } | ||||
file_offset << file_size; | file_offset << file_size; | ||||
m_tiles.reserve(file_count); | |||||
//<Pos, Size> | |||||
array<ivec2, ivec2> tiles; | |||||
tiles.reserve(file_count); | |||||
Compacter2d compacter; | Compacter2d compacter; | ||||
compacter.StepSetup(8, 8, 10); | compacter.StepSetup(8, 8, 10); | ||||
@@ -151,6 +143,7 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
array<uint8_t> file_convert; | array<uint8_t> file_convert; | ||||
file_convert.reserve(file_size); | file_convert.reserve(file_size); | ||||
array<ivec2> available_sizes; | array<ivec2> available_sizes; | ||||
//got through all the files and store them | |||||
for (int i = 0; i < file_count; i++) | for (int i = 0; i < file_count; i++) | ||||
{ | { | ||||
file_pos = file_offset[i]; | file_pos = file_offset[i]; | ||||
@@ -187,8 +180,10 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
//Prepare buffer and tiles infos | //Prepare buffer and tiles infos | ||||
int32_t convert_pos = file_convert.count(); | int32_t convert_pos = file_convert.count(); | ||||
ivec2 size = ivec2(size_x, size_y); | ivec2 size = ivec2(size_x, size_y); | ||||
compacter.Store(m_tiles.count(), ivec2(size_x, size_y)); | |||||
m_tiles.push(ivec2(file_convert.count(), data_length), ivec2(size_x, size_y)); | |||||
//store tile in compacter | |||||
compacter.Store(tiles.count(), ivec2(size_x, size_y)); | |||||
//push tile on the stack | |||||
tiles.push(ivec2(file_convert.count(), data_length), ivec2(size_x, size_y)); | |||||
file_convert.resize(convert_pos + data_length); | file_convert.resize(convert_pos + data_length); | ||||
//Retrieve actual datas | //Retrieve actual datas | ||||
@@ -233,9 +228,10 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
while (tex_size < tex_sqrt) | while (tex_size < tex_sqrt) | ||||
tex_size <<= 1; | tex_size <<= 1; | ||||
//Prepare final imqge | |||||
image->SetSize(ivec2(tex_size)); | |||||
uint8_t *pixels = image->Lock<PixelFormat::Y_8>(); | |||||
//Prepare final image | |||||
auto data = new ResourceTilesetData(new image(ivec2(tex_size))); | |||||
auto image = data->m_image; | |||||
uint8_t *pixels = image->lock<PixelFormat::Y_8>(); | |||||
//Data refactor stage | //Data refactor stage | ||||
ivec2 pos = ivec2(0); | ivec2 pos = ivec2(0); | ||||
@@ -255,8 +251,8 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
compacter.m_primary[j].m_count--; | compacter.m_primary[j].m_count--; | ||||
int i = compacter.m_primary[j].m_secondary[k].m_tiles.pop(); | int i = compacter.m_primary[j].m_secondary[k].m_tiles.pop(); | ||||
int32_t file_off = m_tiles[i].m1[0]; | |||||
ivec2 t_size = m_tiles[i].m2; | |||||
int32_t file_off = tiles[i].m1[0]; | |||||
ivec2 t_size = tiles[i].m2; | |||||
ASSERT(pos.y + t_size.y < tex_size); | ASSERT(pos.y + t_size.y < tex_size); | ||||
@@ -277,7 +273,7 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
} | } | ||||
//Register new pos and move to next | //Register new pos and move to next | ||||
m_tiles[i].m1 = pos; | |||||
tiles[i].m1 = pos; | |||||
pos.x += t_size.x; | pos.x += t_size.x; | ||||
} | } | ||||
} | } | ||||
@@ -290,14 +286,16 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||||
j++; | j++; | ||||
} | } | ||||
} | } | ||||
image->Unlock(pixels); | |||||
image->unlock(pixels); | |||||
return true; | |||||
data->m_tiles = tiles; | |||||
return data; | |||||
} | } | ||||
bool ZedImageCodec::Save(Image *image, char const *path) | |||||
bool ZedImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
UNUSED(path); | |||||
UNUSED(path, data); | |||||
/* FIXME: do we need to implement this? */ | /* FIXME: do we need to implement this? */ | ||||
return true; | return true; | ||||
} | } | ||||
@@ -1,16 +1,19 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// 2014 Benjamin Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
#include "../../image/image-private.h" | |||||
#include "../../image/resource-private.h" | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -19,12 +22,12 @@ namespace lol | |||||
* Image implementation class | * Image implementation class | ||||
*/ | */ | ||||
class ZedPaletteImageCodec : public ImageCodec | |||||
class ZedPaletteImageCodec : public ResourceCodec | |||||
{ | { | ||||
public: | public: | ||||
virtual char const *GetName() { return "<ZedPaletteImageCodec>"; } | virtual char const *GetName() { return "<ZedPaletteImageCodec>"; } | ||||
virtual bool Load(Image *image, char const *path); | |||||
virtual bool Save(Image *image, char const *path); | |||||
virtual ResourceCodecData* Load(char const *path); | |||||
virtual bool Save(char const *path, ResourceCodecData* data); | |||||
}; | }; | ||||
DECLARE_IMAGE_CODEC(ZedPaletteImageCodec, 10) | DECLARE_IMAGE_CODEC(ZedPaletteImageCodec, 10) | ||||
@@ -33,16 +36,16 @@ DECLARE_IMAGE_CODEC(ZedPaletteImageCodec, 10) | |||||
* Public Image class | * Public Image class | ||||
*/ | */ | ||||
bool ZedPaletteImageCodec::Load(Image *image, char const *path) | |||||
ResourceCodecData* ZedPaletteImageCodec::Load(char const *path) | |||||
{ | { | ||||
if (!lol::String(path).ends_with(".pal")) | if (!lol::String(path).ends_with(".pal")) | ||||
return false; | |||||
return nullptr; | |||||
File file; | File file; | ||||
file.Open(path, FileAccess::Read, true); | file.Open(path, FileAccess::Read, true); | ||||
//Put file in memory | |||||
long file_size = file.GetSize(); | |||||
// Put file in memory | |||||
long file_size = file.size(); | |||||
array<uint8_t> file_buffer; | array<uint8_t> file_buffer; | ||||
file_buffer.resize(file_size); | file_buffer.resize(file_size); | ||||
file.Read((uint8_t*)&file_buffer[0], file_size); | file.Read((uint8_t*)&file_buffer[0], file_size); | ||||
@@ -53,16 +56,18 @@ bool ZedPaletteImageCodec::Load(Image *image, char const *path) | |||||
int32_t tex_size = 2; | int32_t tex_size = 2; | ||||
while (tex_size < tex_sqrt) | while (tex_size < tex_sqrt) | ||||
tex_size <<= 1; | tex_size <<= 1; | ||||
image->m_data->m_size = ivec2(tex_size); | |||||
auto data = new ResourceImageData(new image(ivec2(tex_size))); | |||||
auto image = data->m_image; | |||||
#else | #else | ||||
int32_t tex_sqrt = file_size / 3; | int32_t tex_sqrt = file_size / 3; | ||||
int32_t tex_size = 2; | int32_t tex_size = 2; | ||||
while (tex_size < tex_sqrt) | while (tex_size < tex_sqrt) | ||||
tex_size <<= 1; | tex_size <<= 1; | ||||
image->SetSize(ivec2(tex_size, 1)); | |||||
auto data = new ResourceImageData(new image(ivec2(tex_size, 1))); | |||||
auto image = data->m_image; | |||||
#endif | #endif | ||||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *pixels = image->lock<PixelFormat::RGBA_8>(); | |||||
for (int i = 0; i < file_buffer.count();) | for (int i = 0; i < file_buffer.count();) | ||||
{ | { | ||||
pixels->r = file_buffer[i++]; | pixels->r = file_buffer[i++]; | ||||
@@ -71,14 +76,14 @@ bool ZedPaletteImageCodec::Load(Image *image, char const *path) | |||||
pixels->a = (i == 0) ? 0 : 255; | pixels->a = (i == 0) ? 0 : 255; | ||||
++pixels; | ++pixels; | ||||
} | } | ||||
image->Unlock(pixels); | |||||
image->unlock(pixels); | |||||
return true; | |||||
return data; | |||||
} | } | ||||
bool ZedPaletteImageCodec::Save(Image *image, char const *path) | |||||
bool ZedPaletteImageCodec::Save(char const *path, ResourceCodecData* data) | |||||
{ | { | ||||
UNUSED(path); | |||||
UNUSED(path, data); | |||||
/* FIXME: do we need to implement this? */ | /* FIXME: do we need to implement this? */ | ||||
return true; | return true; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -33,18 +35,18 @@ enum class MergeMode | |||||
}; | }; | ||||
template<PixelFormat FORMAT, MergeMode MODE> | template<PixelFormat FORMAT, MergeMode MODE> | ||||
static Image GenericMerge(Image &src1, Image &src2, float alpha) | |||||
static image generic_merge(image &src1, image &src2, float alpha) | |||||
{ | { | ||||
typedef typename PixelType<FORMAT>::type pixel_t; | typedef typename PixelType<FORMAT>::type pixel_t; | ||||
ASSERT(src1.GetSize() == src2.GetSize()); | |||||
int const count = src1.GetSize().x * src2.GetSize().y; | |||||
ASSERT(src1.size() == src2.size()); | |||||
int const count = src1.size().x * src2.size().y; | |||||
Image dst(src1.GetSize()); | |||||
image dst(src1.size()); | |||||
pixel_t const *src1p = src1.Lock<FORMAT>(); | |||||
pixel_t const *src2p = src2.Lock<FORMAT>(); | |||||
pixel_t *dstp = dst.Lock<FORMAT>(); | |||||
pixel_t const *src1p = src1.lock<FORMAT>(); | |||||
pixel_t const *src2p = src2.lock<FORMAT>(); | |||||
pixel_t *dstp = dst.lock<FORMAT>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
{ | { | ||||
@@ -71,80 +73,80 @@ static Image GenericMerge(Image &src1, Image &src2, float alpha) | |||||
dstp[n] = lol::abs(src1p[n] - src2p[n]); | dstp[n] = lol::abs(src1p[n] - src2p[n]); | ||||
} | } | ||||
src1.Unlock(src1p); | |||||
src2.Unlock(src2p); | |||||
dst.Unlock(dstp); | |||||
src1.unlock(src1p); | |||||
src2.unlock(src2p); | |||||
dst.unlock(dstp); | |||||
return dst; | return dst; | ||||
} | } | ||||
template<MergeMode MODE> | template<MergeMode MODE> | ||||
static Image GenericMerge(Image &src1, Image &src2, float alpha) | |||||
static image generic_merge(image &src1, image &src2, float alpha) | |||||
{ | { | ||||
bool gray1 = src1.GetFormat() == PixelFormat::Y_8 | |||||
|| src1.GetFormat() == PixelFormat::Y_F32; | |||||
bool gray2 = src2.GetFormat() == PixelFormat::Y_8 | |||||
|| src2.GetFormat() == PixelFormat::Y_F32; | |||||
bool gray1 = src1.format() == PixelFormat::Y_8 | |||||
|| src1.format() == PixelFormat::Y_F32; | |||||
bool gray2 = src2.format() == PixelFormat::Y_8 | |||||
|| src2.format() == PixelFormat::Y_F32; | |||||
if (gray1 && gray2) | if (gray1 && gray2) | ||||
return GenericMerge<PixelFormat::Y_F32, MODE>(src1, src2, alpha); | |||||
return generic_merge<PixelFormat::Y_F32, MODE>(src1, src2, alpha); | |||||
else | else | ||||
return GenericMerge<PixelFormat::RGBA_F32, MODE>(src1, src2, alpha); | |||||
return generic_merge<PixelFormat::RGBA_F32, MODE>(src1, src2, alpha); | |||||
} | } | ||||
Image Image::Merge(Image &src1, Image &src2, float alpha) | |||||
image image::Merge(image &src1, image &src2, float alpha) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Mix>(src1, src2, alpha); | |||||
return generic_merge<MergeMode::Mix>(src1, src2, alpha); | |||||
} | } | ||||
Image Image::Mean(Image &src1, Image &src2) | |||||
image image::Mean(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Mix>(src1, src2, 0.5f); | |||||
return generic_merge<MergeMode::Mix>(src1, src2, 0.5f); | |||||
} | } | ||||
Image Image::Min(Image &src1, Image &src2) | |||||
image image::Min(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Min>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Min>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Max(Image &src1, Image &src2) | |||||
image image::Max(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Max>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Max>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Overlay(Image &src1, Image &src2) | |||||
image image::Overlay(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Overlay>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Overlay>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Screen(Image &src1, Image &src2) | |||||
image image::Screen(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Screen>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Screen>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Divide(Image &src1, Image &src2) | |||||
image image::Divide(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Divide>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Divide>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Multiply(Image &src1, Image &src2) | |||||
image image::Multiply(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Multiply>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Multiply>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Add(Image &src1, Image &src2) | |||||
image image::Add(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Add>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Add>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Sub(Image &src1, Image &src2) | |||||
image image::Sub(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Sub>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Sub>(src1, src2, 0.0f); | |||||
} | } | ||||
Image Image::Difference(Image &src1, Image &src2) | |||||
image image::Difference(image &src1, image &src2) | |||||
{ | { | ||||
return GenericMerge<MergeMode::Difference>(src1, src2, 0.0f); | |||||
return generic_merge<MergeMode::Difference>(src1, src2, 0.0f); | |||||
} | } | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -19,20 +21,20 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
Image Image::Crop(ibox2 box) const | |||||
image image::Crop(ibox2 box) const | |||||
{ | { | ||||
ivec2 const srcsize = GetSize(); | |||||
ivec2 const srcsize = size(); | |||||
ivec2 const dstsize = box.extent(); | ivec2 const dstsize = box.extent(); | ||||
Image dst(dstsize); | |||||
PixelFormat format = GetFormat(); | |||||
image dst(dstsize); | |||||
PixelFormat fmt = format(); | |||||
if (format != PixelFormat::Unknown) | |||||
if (fmt != PixelFormat::Unknown) | |||||
{ | { | ||||
dst.SetFormat(format); | |||||
uint8_t const *srcp = (uint8_t const *)m_data->m_pixels[(int)format]; | |||||
uint8_t *dstp = (uint8_t *)dst.m_data->m_pixels[(int)format]; | |||||
uint8_t bpp = BytesPerPixel(format); | |||||
dst.set_format(fmt); | |||||
uint8_t const *srcp = (uint8_t const *)m_data->m_pixels[(int)fmt]; | |||||
uint8_t *dstp = (uint8_t *)dst.m_data->m_pixels[(int)fmt]; | |||||
uint8_t bpp = BytesPerPixel(fmt); | |||||
int len = dstsize.x; | int len = dstsize.x; | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2015 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -24,44 +26,44 @@ namespace lol | |||||
/* FIXME: though the algorithm is supposed to stop, we do not have a real, | /* FIXME: though the algorithm is supposed to stop, we do not have a real, | ||||
* guaranteed stop condition here. */ | * guaranteed stop condition here. */ | ||||
Image Image::DitherDbs() const | |||||
image image::dither_dbs() const | |||||
{ | { | ||||
ivec2 size = GetSize(); | |||||
ivec2 isize = size(); | |||||
/* Build our human visual system kernel. */ | /* Build our human visual system kernel. */ | ||||
array2d<float> kernel; | |||||
kernel.resize(ivec2(NN, NN)); | |||||
array2d<float> ker; | |||||
ker.resize(ivec2(NN, NN)); | |||||
float t = 0.f; | float t = 0.f; | ||||
for (int j = 0; j < NN; j++) | for (int j = 0; j < NN; j++) | ||||
for (int i = 0; i < NN; i++) | for (int i = 0; i < NN; i++) | ||||
{ | { | ||||
vec2 v = vec2(i - N, j - N); | vec2 v = vec2(i - N, j - N); | ||||
kernel[i][j] = exp(-sqlength(v / 1.6f) / 2.f) | |||||
+ exp(-sqlength(v / 0.6f) / 2.f); | |||||
t += kernel[i][j]; | |||||
ker[i][j] = exp(-sqlength(v / 1.6f) / 2.f) | |||||
+ exp(-sqlength(v / 0.6f) / 2.f); | |||||
t += ker[i][j]; | |||||
} | } | ||||
for (int j = 0; j < NN; j++) | for (int j = 0; j < NN; j++) | ||||
for (int i = 0; i < NN; i++) | for (int i = 0; i < NN; i++) | ||||
kernel[i][j] /= t; | |||||
ker[i][j] /= t; | |||||
/* A list of cells in our picture. If no change is done to a cell | /* A list of cells in our picture. If no change is done to a cell | ||||
* for two iterations, we stop considering changes to it. */ | * for two iterations, we stop considering changes to it. */ | ||||
ivec2 const csize = (size + ivec2(CELL - 1)) / CELL; | |||||
ivec2 const csize = (isize + ivec2(CELL - 1)) / CELL; | |||||
array2d<int> changelist(csize); | array2d<int> changelist(csize); | ||||
memset(changelist.data(), 0, changelist.bytes()); | memset(changelist.data(), 0, changelist.bytes()); | ||||
Image dst = *this; | |||||
dst.SetFormat(PixelFormat::Y_F32); | |||||
image dst = *this; | |||||
dst.set_format(PixelFormat::Y_F32); | |||||
Image tmp1 = dst.Convolution(kernel); | |||||
array2d<float> &tmp1data = tmp1.Lock2D<PixelFormat::Y_F32>(); | |||||
image tmp1 = dst.Convolution(ker); | |||||
array2d<float> &tmp1data = tmp1.lock2d<PixelFormat::Y_F32>(); | |||||
dst = dst.DitherRandom(); | |||||
array2d<float> &dstdata = dst.Lock2D<PixelFormat::Y_F32>(); | |||||
dst = dst.dither_random(); | |||||
array2d<float> &dstdata = dst.lock2d<PixelFormat::Y_F32>(); | |||||
Image tmp2 = dst.Convolution(kernel); | |||||
array2d<float> &tmp2data = tmp2.Lock2D<PixelFormat::Y_F32>(); | |||||
image tmp2 = dst.Convolution(ker); | |||||
array2d<float> &tmp2data = tmp2.lock2d<PixelFormat::Y_F32>(); | |||||
for (int run = 0, last_change = 0; ; ++run) | for (int run = 0, last_change = 0; ; ++run) | ||||
{ | { | ||||
@@ -84,7 +86,7 @@ Image Image::DitherDbs() const | |||||
ivec2 const pos(cx * CELL + pixel % CELL, | ivec2 const pos(cx * CELL + pixel % CELL, | ||||
cy * CELL + pixel / CELL); | cy * CELL + pixel / CELL); | ||||
if (!(pos >= ivec2(0)) || !(pos < size)) | |||||
if (!(pos >= ivec2(0)) || !(pos < isize)) | |||||
continue; | continue; | ||||
/* The best operation we can do */ | /* The best operation we can do */ | ||||
@@ -103,7 +105,7 @@ Image Image::DitherDbs() const | |||||
for (ivec2 const op : op_list) | for (ivec2 const op : op_list) | ||||
{ | { | ||||
if (!(pos + op >= ivec2(0)) || !(pos + op < size)) | |||||
if (!(pos + op >= ivec2(0)) || !(pos + op < isize)) | |||||
continue; | continue; | ||||
bool flip = (op == ivec2(0)); | bool flip = (op == ivec2(0)); | ||||
@@ -115,9 +117,9 @@ Image Image::DitherDbs() const | |||||
/* TODO: implement min/max for 3+ arguments */ | /* TODO: implement min/max for 3+ arguments */ | ||||
int imin = max(max(-N, op.x - N), -pos.x); | int imin = max(max(-N, op.x - N), -pos.x); | ||||
int imax = min(min(N + 1, op.x + NN - N), size.x - pos.x); | |||||
int imax = min(min(N + 1, op.x + NN - N), isize.x - pos.x); | |||||
int jmin = max(max(-N, op.y - N), -pos.y); | int jmin = max(max(-N, op.y - N), -pos.y); | ||||
int jmax = min(min(N + 1, op.y + NN - N), size.y - pos.y); | |||||
int jmax = min(min(N + 1, op.y + NN - N), isize.y - pos.y); | |||||
float error = 0.f; | float error = 0.f; | ||||
for (int j = jmin; j < jmax; j++) | for (int j = jmin; j < jmax; j++) | ||||
@@ -125,9 +127,9 @@ Image Image::DitherDbs() const | |||||
{ | { | ||||
ivec2 pos2 = pos + ivec2(i, j); | ivec2 pos2 = pos + ivec2(i, j); | ||||
float m = kernel[i + N][j + N]; | |||||
float m = ker[i + N][j + N]; | |||||
if (!flip) | if (!flip) | ||||
m -= kernel[i - op.x + N][j - op.y + N]; | |||||
m -= ker[i - op.x + N][j - op.y + N]; | |||||
float p = tmp1data[pos2]; | float p = tmp1data[pos2]; | ||||
float q1 = tmp2data[pos2]; | float q1 = tmp2data[pos2]; | ||||
float q2 = q1 + m * (d2 - d); | float q2 = q1 + m * (d2 - d); | ||||
@@ -154,13 +156,13 @@ Image Image::DitherDbs() const | |||||
for (int i = -N; i <= N; i++) | for (int i = -N; i <= N; i++) | ||||
{ | { | ||||
ivec2 off(i, j); | ivec2 off(i, j); | ||||
float delta = (d2 - d) * kernel[i + N][j + N]; | |||||
float delta = (d2 - d) * ker[i + N][j + N]; | |||||
if (pos + off >= ivec2(0) && pos + off < size) | |||||
if (pos + off >= ivec2(0) && pos + off < isize) | |||||
tmp2data[pos + off] += delta; | tmp2data[pos + off] += delta; | ||||
if (!flip && pos + off + best_op >= ivec2(0) | if (!flip && pos + off + best_op >= ivec2(0) | ||||
&& pos + off + best_op < size) | |||||
&& pos + off + best_op < isize) | |||||
tmp2data[pos + off + best_op] -= delta; | tmp2data[pos + off + best_op] -= delta; | ||||
} | } | ||||
@@ -173,9 +175,9 @@ Image Image::DitherDbs() const | |||||
++changelist[cx][cy]; | ++changelist[cx][cy]; | ||||
} | } | ||||
tmp1.Unlock2D(tmp1data); | |||||
tmp2.Unlock2D(tmp2data); | |||||
dst.Unlock2D(dstdata); | |||||
tmp1.unlock2d(tmp1data); | |||||
tmp2.unlock2d(tmp2data); | |||||
dst.unlock2d(dstdata); | |||||
return dst; | return dst; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -23,49 +25,49 @@ namespace lol | |||||
* Making the matrix generic is not terribly slower: the performance | * Making the matrix generic is not terribly slower: the performance | ||||
* hit is around 4% for Floyd-Steinberg and 13% for JaJuNi, with the | * hit is around 4% for Floyd-Steinberg and 13% for JaJuNi, with the | ||||
* benefit of a lot less code. */ | * benefit of a lot less code. */ | ||||
Image Image::DitherEdiff(array2d<float> const &kernel, ScanMode scan) const | |||||
image image::dither_ediff(array2d<float> const &ker, ScanMode scan) const | |||||
{ | { | ||||
Image dst = *this; | |||||
image dst = *this; | |||||
ivec2 size = dst.GetSize(); | |||||
ivec2 ksize = kernel.size(); | |||||
ivec2 isize = dst.size(); | |||||
ivec2 ksize = ker.size(); | |||||
int kx; | int kx; | ||||
for (kx = 0; kx < ksize.x; kx++) | for (kx = 0; kx < ksize.x; kx++) | ||||
if (kernel[kx][0] > 0.f) | |||||
if (ker[kx][0] > 0.f) | |||||
break; | break; | ||||
float *pixels = dst.Lock<PixelFormat::Y_F32>(); | |||||
for (int y = 0; y < size.y; y++) | |||||
float *pixels = dst.lock<PixelFormat::Y_F32>(); | |||||
for (int y = 0; y < isize.y; y++) | |||||
{ | { | ||||
bool reverse = (y & 1) && (scan == ScanMode::Serpentine); | bool reverse = (y & 1) && (scan == ScanMode::Serpentine); | ||||
for (int x = 0; x < size.x; x++) | |||||
for (int x = 0; x < isize.x; x++) | |||||
{ | { | ||||
int x2 = reverse ? size.x - 1 - x : x; | |||||
int x2 = reverse ? isize.x - 1 - x : x; | |||||
int s = reverse ? -1 : 1; | int s = reverse ? -1 : 1; | ||||
float p = pixels[y * size.x + x2]; | |||||
float p = pixels[y * isize.x + x2]; | |||||
float q = p < 0.5f ? 0.f : 1.f; | float q = p < 0.5f ? 0.f : 1.f; | ||||
pixels[y * size.x + x2] = q; | |||||
pixels[y * isize.x + x2] = q; | |||||
float e = (p - q); | float e = (p - q); | ||||
for (int j = 0; j < ksize.y && y < size.y - j; j++) | |||||
for (int j = 0; j < ksize.y && y < isize.y - j; j++) | |||||
for (int i = 0; i < ksize.x; i++) | for (int i = 0; i < ksize.x; i++) | ||||
{ | { | ||||
if (j == 0 && i <= kx) | if (j == 0 && i <= kx) | ||||
continue; | continue; | ||||
if (x + i - kx < 0 || x + i - kx >= size.x) | |||||
if (x + i - kx < 0 || x + i - kx >= isize.x) | |||||
continue; | continue; | ||||
pixels[(y + j) * size.x + x2 + (i - kx) * s] | |||||
+= e * kernel[i][j]; | |||||
pixels[(y + j) * isize.x + x2 + (i - kx) * s] | |||||
+= e * ker[i][j]; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
dst.Unlock(pixels); | |||||
dst.unlock(pixels); | |||||
return dst; | return dst; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,51 +19,51 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
static Image DitherHelper(Image const &image, array2d<float> const &kernel, | |||||
float scale, float angle); | |||||
static image dither_helper(image const &img, array2d<float> const &ker, | |||||
float scale, float angle); | |||||
Image Image::DitherOrdered(array2d<float> const &kernel) const | |||||
image image::dither_ordered(array2d<float> const &ker) const | |||||
{ | { | ||||
return DitherHelper(*this, kernel, 1.0f, 0.0f); | |||||
return dither_helper(*this, ker, 1.0f, 0.0f); | |||||
} | } | ||||
Image Image::DitherHalftone(float radius, float angle) const | |||||
image image::dither_halftone(float radius, float angle) const | |||||
{ | { | ||||
/* Increasing the precision is necessary or the rotation will look | /* Increasing the precision is necessary or the rotation will look | ||||
* like crap. So we create a kernel PRECISION times larger, and ask | * like crap. So we create a kernel PRECISION times larger, and ask | ||||
* the ditherer to scale it by 1/PRECISION. */ | * the ditherer to scale it by 1/PRECISION. */ | ||||
float const PRECISION = 4.f; | float const PRECISION = 4.f; | ||||
int k = (radius * PRECISION * lol::sqrt(2.f) + 0.5f); | int k = (radius * PRECISION * lol::sqrt(2.f) + 0.5f); | ||||
array2d<float> kernel = Image::HalftoneKernel(ivec2(k, k)); | |||||
array2d<float> ker = image::kernel::halftone(ivec2(k, k)); | |||||
return DitherHelper(*this, kernel, 1.f / PRECISION, angle + F_PI / 4.f); | |||||
return dither_helper(*this, ker, 1.f / PRECISION, angle + F_PI / 4.f); | |||||
} | } | ||||
static Image DitherHelper(Image const &image, array2d<float> const &kernel, | |||||
float scale, float angle) | |||||
static image dither_helper(image const &img, array2d<float> const &ker, | |||||
float scale, float angle) | |||||
{ | { | ||||
ivec2 size = image.GetSize(); | |||||
ivec2 ksize = kernel.size(); | |||||
ivec2 isize = img.size(); | |||||
ivec2 ksize = ker.size(); | |||||
float cost = lol::cos(angle); | float cost = lol::cos(angle); | ||||
float sint = lol::sin(angle); | float sint = lol::sin(angle); | ||||
Image ret = image; | |||||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||||
image ret = img; | |||||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int y = 0; y < size.y; y++) | |||||
for (int y = 0; y < isize.y; y++) | |||||
{ | { | ||||
for (int x = 0; x < size.x; x++) | |||||
for (int x = 0; x < isize.x; x++) | |||||
{ | { | ||||
int kx = (int)((cost * x - sint * y + 2 * size.x * size.y) / scale) % ksize.x; | |||||
int ky = (int)((cost * y + sint * x + 2 * size.x * size.y) / scale) % ksize.y; | |||||
int kx = (int)((cost * x - sint * y + 2 * isize.x * isize.y) / scale) % ksize.x; | |||||
int ky = (int)((cost * y + sint * x + 2 * isize.x * isize.y) / scale) % ksize.y; | |||||
float p = dstp[y * size.x + x]; | |||||
dstp[y * size.x + x] = (p > kernel[kx][ky]) ? 1.f : 0.f; | |||||
float p = dstp[y * isize.x + x]; | |||||
dstp[y * isize.x + x] = (p > ker[kx][ky]) ? 1.f : 0.f; | |||||
} | } | ||||
} | } | ||||
ret.Unlock(dstp); | |||||
ret.unlock(dstp); | |||||
return ret; | return ret; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -69,13 +71,13 @@ static inline vec3 GetDiffusion(float v) | |||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::DitherOstromoukhov(ScanMode scan) const | |||||
image image::dither_ostromoukhov(ScanMode scan) const | |||||
{ | { | ||||
Image dst = *this; | |||||
image dst = *this; | |||||
float *pixels = dst.Lock<PixelFormat::Y_F32>(); | |||||
int w = dst.GetSize().x; | |||||
int h = dst.GetSize().y; | |||||
float *pixels = dst.lock<PixelFormat::Y_F32>(); | |||||
int w = dst.size().x; | |||||
int h = dst.size().y; | |||||
for (int y = 0; y < h; y++) | for (int y = 0; y < h; y++) | ||||
{ | { | ||||
@@ -103,7 +105,7 @@ Image Image::DitherOstromoukhov(ScanMode scan) const | |||||
} | } | ||||
} | } | ||||
dst.Unlock(pixels); | |||||
dst.unlock(pixels); | |||||
return dst; | return dst; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,19 +19,19 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
Image Image::DitherRandom() const | |||||
image image::dither_random() const | |||||
{ | { | ||||
Image dst = *this; | |||||
image dst = *this; | |||||
float *pixels = dst.Lock<PixelFormat::Y_F32>(); | |||||
int count = GetSize().x * GetSize().y; | |||||
float *pixels = dst.lock<PixelFormat::Y_F32>(); | |||||
int count = size().x * size().y; | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
{ | { | ||||
pixels[n] = (pixels[n] > lol::rand(0.5f)) ? 1.f : 0.f; | pixels[n] = (pixels[n] > lol::rand(0.5f)) ? 1.f : 0.f; | ||||
} | } | ||||
dst.Unlock(pixels); | |||||
dst.unlock(pixels); | |||||
return dst; | return dst; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,34 +19,34 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
Image Image::Brightness(float val) const | |||||
image image::Brightness(float val) const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = lol::clamp(pixels[n] + val, 0.f, 1.f); | pixels[n] = lol::clamp(pixels[n] + val, 0.f, 1.f); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = vec4(lol::clamp(pixels[n].rgb + vec3(val), 0.f, 1.f), | pixels[n] = vec4(lol::clamp(pixels[n].rgb + vec3(val), 0.f, 1.f), | ||||
pixels[n].a); | pixels[n].a); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::Contrast(float val) const | |||||
image image::Contrast(float val) const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
if (val >= 0.f) | if (val >= 0.f) | ||||
{ | { | ||||
@@ -58,22 +60,22 @@ Image Image::Contrast(float val) const | |||||
val = lol::clamp(1.f + val, 0.f, 1.f); | val = lol::clamp(1.f + val, 0.f, 1.f); | ||||
} | } | ||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
float add = -0.5f * val + 0.5f; | float add = -0.5f * val + 0.5f; | ||||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = lol::clamp(pixels[n] * val + add, 0.f, 1.f); | pixels[n] = lol::clamp(pixels[n] * val + add, 0.f, 1.f); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
vec3 add = vec3(-0.5f * val + 0.5f); | vec3 add = vec3(-0.5f * val + 0.5f); | ||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = vec4(lol::clamp(pixels[n].rgb * val + add, 0.f, 1.f), | pixels[n] = vec4(lol::clamp(pixels[n].rgb * val + add, 0.f, 1.f), | ||||
pixels[n].a); | pixels[n].a); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
return ret; | return ret; | ||||
@@ -83,16 +85,16 @@ Image Image::Contrast(float val) const | |||||
* TODO: the current approach is naive; we should use the histogram in order | * TODO: the current approach is naive; we should use the histogram in order | ||||
* to decide how to change the contrast. | * to decide how to change the contrast. | ||||
*/ | */ | ||||
Image Image::AutoContrast() const | |||||
image image::AutoContrast() const | |||||
{ | { | ||||
Image ret = *this; | |||||
image ret = *this; | |||||
float min_val = 1.f, max_val = 0.f; | float min_val = 1.f, max_val = 0.f; | ||||
int count = GetSize().x * GetSize().y; | |||||
int count = size().x * size().y; | |||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
{ | { | ||||
min_val = lol::min(min_val, pixels[n]); | min_val = lol::min(min_val, pixels[n]); | ||||
@@ -103,11 +105,11 @@ Image Image::AutoContrast() const | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = (pixels[n] - min_val) * t; | pixels[n] = (pixels[n] - min_val) * t; | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
{ | { | ||||
min_val = lol::min(min_val, pixels[n].r); | min_val = lol::min(min_val, pixels[n].r); | ||||
@@ -125,60 +127,60 @@ Image Image::AutoContrast() const | |||||
(pixels[n].b - min_val) * t, | (pixels[n].b - min_val) * t, | ||||
pixels[n].a);; | pixels[n].a);; | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::Invert() const | |||||
image image::Invert() const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = 1.f - pixels[n]; | pixels[n] = 1.f - pixels[n]; | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = vec4(vec3(1.f) -pixels[n].rgb, pixels[n].a); | pixels[n] = vec4(vec3(1.f) -pixels[n].rgb, pixels[n].a); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::Threshold(float val) const | |||||
image image::Threshold(float val) const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
float *pixels = ret.Lock<PixelFormat::Y_F32>(); | |||||
float *pixels = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = pixels[n] > val ? 1.f : 0.f; | pixels[n] = pixels[n] > val ? 1.f : 0.f; | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::Threshold(vec3 val) const | |||||
image image::Threshold(vec3 val) const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = vec4(pixels[n].r > val.r ? 1.f : 0.f, | pixels[n] = vec4(pixels[n].r > val.r ? 1.f : 0.f, | ||||
pixels[n].g > val.g ? 1.f : 0.f, | pixels[n].g > val.g ? 1.f : 0.f, | ||||
pixels[n].b > val.b ? 1.f : 0.f, | pixels[n].b > val.b ? 1.f : 0.f, | ||||
pixels[n].a); | pixels[n].a); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
return ret; | return ret; | ||||
} | } | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,21 +19,21 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
static Image SepConv(Image &src, array<float> const &hvec, | |||||
static image SepConv(image &src, array<float> const &hvec, | |||||
array<float> const &vvec); | array<float> const &vvec); | ||||
static Image NonSepConv(Image &src, array2d<float> const &kernel); | |||||
static image NonSepConv(image &src, array2d<float> const &in_kernel); | |||||
Image Image::Convolution(array2d<float> const &kernel) | |||||
image image::Convolution(array2d<float> const &in_kernel) | |||||
{ | { | ||||
/* Find the cell with the largest value */ | /* Find the cell with the largest value */ | ||||
ivec2 ksize = kernel.size(); | |||||
ivec2 ksize = in_kernel.size(); | |||||
int bestx = -1, besty = -1; | int bestx = -1, besty = -1; | ||||
float tmp = 0.f; | float tmp = 0.f; | ||||
for (int dy = 0; dy < ksize.y; ++dy) | for (int dy = 0; dy < ksize.y; ++dy) | ||||
for (int dx = 0; dx < ksize.x; ++dx) | for (int dx = 0; dx < ksize.x; ++dx) | ||||
if (lol::sq(kernel[dx][dy]) > tmp) | |||||
if (lol::sq(in_kernel[dx][dy]) > tmp) | |||||
{ | { | ||||
tmp = sq(kernel[dx][dy]); | |||||
tmp = sq(in_kernel[dx][dy]); | |||||
bestx = dx; | bestx = dx; | ||||
besty = dy; | besty = dy; | ||||
} | } | ||||
@@ -52,8 +54,8 @@ Image Image::Convolution(array2d<float> const &kernel) | |||||
if (dx == bestx) | if (dx == bestx) | ||||
continue; | continue; | ||||
float p = kernel[dx][dy] * kernel[bestx][besty]; | |||||
float q = kernel[dx][besty] * kernel[bestx][dy]; | |||||
float p = in_kernel[dx][dy] * in_kernel[bestx][besty]; | |||||
float q = in_kernel[dx][besty] * in_kernel[bestx][dy]; | |||||
if (lol::abs(p - q) > 1.0e-8f) | if (lol::abs(p - q) > 1.0e-8f) | ||||
separable = false; | separable = false; | ||||
@@ -65,29 +67,29 @@ Image Image::Convolution(array2d<float> const &kernel) | |||||
/* Matrix rank is 1! Separate the filter. */ | /* Matrix rank is 1! Separate the filter. */ | ||||
array<float> hvec, vvec; | array<float> hvec, vvec; | ||||
float norm = 1.0f / lol::sqrt(lol::abs(kernel[bestx][besty])); | |||||
float norm = 1.0f / lol::sqrt(lol::abs(in_kernel[bestx][besty])); | |||||
for (int dx = 0; dx < ksize.x; dx++) | for (int dx = 0; dx < ksize.x; dx++) | ||||
hvec << norm * kernel[dx][besty]; | |||||
hvec << norm * in_kernel[dx][besty]; | |||||
for (int dy = 0; dy < ksize.y; dy++) | for (int dy = 0; dy < ksize.y; dy++) | ||||
vvec << norm * kernel[bestx][dy]; | |||||
vvec << norm * in_kernel[bestx][dy]; | |||||
return SepConv(*this, hvec, vvec); | return SepConv(*this, hvec, vvec); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
return NonSepConv(*this, kernel); | |||||
return NonSepConv(*this, in_kernel); | |||||
} | } | ||||
} | } | ||||
Image Image::Sharpen(array2d<float> const &kernel) | |||||
image image::Sharpen(array2d<float> const &in_kernel) | |||||
{ | { | ||||
ivec2 ksize = kernel.size(); | |||||
ivec2 ksize = in_kernel.size(); | |||||
array2d<float> newkernel(ksize); | array2d<float> newkernel(ksize); | ||||
for (int dy = 0; dy < ksize.y; ++dy) | for (int dy = 0; dy < ksize.y; ++dy) | ||||
for (int dx = 0; dx < ksize.x; ++dx) | for (int dx = 0; dx < ksize.x; ++dx) | ||||
{ | { | ||||
newkernel[dx][dy] = - kernel[dx][dy]; | |||||
newkernel[dx][dy] = - in_kernel[dx][dy]; | |||||
if (dx == ksize.x / 2 && dy == ksize.y / 2) | if (dx == ksize.x / 2 && dy == ksize.y / 2) | ||||
newkernel[dx][dy] += 2.f; | newkernel[dx][dy] += 2.f; | ||||
} | } | ||||
@@ -96,16 +98,16 @@ Image Image::Sharpen(array2d<float> const &kernel) | |||||
} | } | ||||
template<PixelFormat FORMAT, int WRAP_X, int WRAP_Y> | template<PixelFormat FORMAT, int WRAP_X, int WRAP_Y> | ||||
static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||||
static image NonSepConv(image &src, array2d<float> const &in_kernel) | |||||
{ | { | ||||
typedef typename PixelType<FORMAT>::type pixel_t; | typedef typename PixelType<FORMAT>::type pixel_t; | ||||
ivec2 const size = src.GetSize(); | |||||
ivec2 const ksize = kernel.size(); | |||||
Image dst(size); | |||||
ivec2 const size = src.size(); | |||||
ivec2 const ksize = in_kernel.size(); | |||||
image dst(size); | |||||
array2d<pixel_t> const &srcp = src.Lock2D<FORMAT>(); | |||||
array2d<pixel_t> &dstp = dst.Lock2D<FORMAT>(); | |||||
array2d<pixel_t> const &srcp = src.lock2d<FORMAT>(); | |||||
array2d<pixel_t> &dstp = dst.lock2d<FORMAT>(); | |||||
for (int y = 0; y < size.y; y++) | for (int y = 0; y < size.y; y++) | ||||
{ | { | ||||
@@ -123,7 +125,7 @@ static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||||
for (int dx = 0; dx < ksize.x; dx++) | for (int dx = 0; dx < ksize.x; dx++) | ||||
{ | { | ||||
float f = kernel[dx][dy]; | |||||
float f = in_kernel[dx][dy]; | |||||
int x2 = x + dx - ksize.x / 2; | int x2 = x + dx - ksize.x / 2; | ||||
if (x2 < 0) | if (x2 < 0) | ||||
@@ -139,33 +141,33 @@ static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||||
} | } | ||||
} | } | ||||
src.Unlock2D(srcp); | |||||
dst.Unlock2D(dstp); | |||||
src.unlock2d(srcp); | |||||
dst.unlock2d(dstp); | |||||
return dst; | return dst; | ||||
} | } | ||||
static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||||
static image NonSepConv(image &src, array2d<float> const &in_kernel) | |||||
{ | { | ||||
bool const wrap_x = src.GetWrapX() == WrapMode::Repeat; | bool const wrap_x = src.GetWrapX() == WrapMode::Repeat; | ||||
bool const wrap_y = src.GetWrapY() == WrapMode::Repeat; | bool const wrap_y = src.GetWrapY() == WrapMode::Repeat; | ||||
if (src.GetFormat() == PixelFormat::Y_8 | |||||
|| src.GetFormat() == PixelFormat::Y_F32) | |||||
if (src.format() == PixelFormat::Y_8 | |||||
|| src.format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
if (wrap_x) | if (wrap_x) | ||||
{ | { | ||||
if (wrap_y) | if (wrap_y) | ||||
return NonSepConv<PixelFormat::Y_F32, 1, 1>(src, kernel); | |||||
return NonSepConv<PixelFormat::Y_F32, 1, 1>(src, in_kernel); | |||||
else | else | ||||
return NonSepConv<PixelFormat::Y_F32, 1, 0>(src, kernel); | |||||
return NonSepConv<PixelFormat::Y_F32, 1, 0>(src, in_kernel); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (wrap_y) | if (wrap_y) | ||||
return NonSepConv<PixelFormat::Y_F32, 0, 1>(src, kernel); | |||||
return NonSepConv<PixelFormat::Y_F32, 0, 1>(src, in_kernel); | |||||
else | else | ||||
return NonSepConv<PixelFormat::Y_F32, 0, 0>(src, kernel); | |||||
return NonSepConv<PixelFormat::Y_F32, 0, 0>(src, in_kernel); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
@@ -173,32 +175,32 @@ static Image NonSepConv(Image &src, array2d<float> const &kernel) | |||||
if (wrap_x) | if (wrap_x) | ||||
{ | { | ||||
if (wrap_y) | if (wrap_y) | ||||
return NonSepConv<PixelFormat::RGBA_F32, 1, 1>(src, kernel); | |||||
return NonSepConv<PixelFormat::RGBA_F32, 1, 1>(src, in_kernel); | |||||
else | else | ||||
return NonSepConv<PixelFormat::RGBA_F32, 1, 0>(src, kernel); | |||||
return NonSepConv<PixelFormat::RGBA_F32, 1, 0>(src, in_kernel); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (wrap_y) | if (wrap_y) | ||||
return NonSepConv<PixelFormat::RGBA_F32, 0, 1>(src, kernel); | |||||
return NonSepConv<PixelFormat::RGBA_F32, 0, 1>(src, in_kernel); | |||||
else | else | ||||
return NonSepConv<PixelFormat::RGBA_F32, 0, 0>(src, kernel); | |||||
return NonSepConv<PixelFormat::RGBA_F32, 0, 0>(src, in_kernel); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
template<PixelFormat FORMAT, int WRAP_X, int WRAP_Y> | template<PixelFormat FORMAT, int WRAP_X, int WRAP_Y> | ||||
static Image SepConv(Image &src, array<float> const &hvec, | |||||
static image SepConv(image &src, array<float> const &hvec, | |||||
array<float> const &vvec) | array<float> const &vvec) | ||||
{ | { | ||||
typedef typename PixelType<FORMAT>::type pixel_t; | typedef typename PixelType<FORMAT>::type pixel_t; | ||||
ivec2 const size = src.GetSize(); | |||||
ivec2 const size = src.size(); | |||||
ivec2 const ksize(hvec.count(), vvec.count()); | ivec2 const ksize(hvec.count(), vvec.count()); | ||||
Image dst(size); | |||||
image dst(size); | |||||
array2d<pixel_t> const &srcp = src.Lock2D<FORMAT>(); | |||||
array2d<pixel_t> &dstp = dst.Lock2D<FORMAT>(); | |||||
array2d<pixel_t> const &srcp = src.lock2d<FORMAT>(); | |||||
array2d<pixel_t> &dstp = dst.lock2d<FORMAT>(); | |||||
array2d<pixel_t> tmp(size); | array2d<pixel_t> tmp(size); | ||||
@@ -244,20 +246,20 @@ static Image SepConv(Image &src, array<float> const &hvec, | |||||
} | } | ||||
} | } | ||||
src.Unlock2D(srcp); | |||||
dst.Unlock2D(dstp); | |||||
src.unlock2d(srcp); | |||||
dst.unlock2d(dstp); | |||||
return dst; | return dst; | ||||
} | } | ||||
static Image SepConv(Image &src, array<float> const &hvec, | |||||
static image SepConv(image &src, array<float> const &hvec, | |||||
array<float> const &vvec) | array<float> const &vvec) | ||||
{ | { | ||||
bool const wrap_x = src.GetWrapX() == WrapMode::Repeat; | bool const wrap_x = src.GetWrapX() == WrapMode::Repeat; | ||||
bool const wrap_y = src.GetWrapY() == WrapMode::Repeat; | bool const wrap_y = src.GetWrapY() == WrapMode::Repeat; | ||||
if (src.GetFormat() == PixelFormat::Y_8 | |||||
|| src.GetFormat() == PixelFormat::Y_F32) | |||||
if (src.format() == PixelFormat::Y_8 | |||||
|| src.format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
if (wrap_x) | if (wrap_x) | ||||
{ | { | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -22,115 +24,115 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
Image Image::Dilate() | |||||
image image::Dilate() | |||||
{ | { | ||||
ivec2 const size = GetSize(); | |||||
Image ret(size); | |||||
ivec2 isize = size(); | |||||
image ret(isize); | |||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
float const *srcp = Lock<PixelFormat::Y_F32>(); | |||||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||||
float const *srcp = lock<PixelFormat::Y_F32>(); | |||||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int y = 0; y < size.y; ++y) | |||||
for (int x = 0; x < size.x; ++x) | |||||
for (int y = 0; y < isize.y; ++y) | |||||
for (int x = 0; x < isize.x; ++x) | |||||
{ | { | ||||
int y2 = lol::max(y - 1, 0); | int y2 = lol::max(y - 1, 0); | ||||
int x2 = lol::max(x - 1, 0); | int x2 = lol::max(x - 1, 0); | ||||
int y3 = lol::min(y + 1, size.y - 1); | |||||
int x3 = lol::min(x + 1, size.x - 1); | |||||
float t = srcp[y * size.x + x]; | |||||
t = lol::max(t, srcp[y * size.x + x2]); | |||||
t = lol::max(t, srcp[y * size.x + x3]); | |||||
t = lol::max(t, srcp[y2 * size.x + x]); | |||||
t = lol::max(t, srcp[y3 * size.x + x]); | |||||
dstp[y * size.x + x] = t; | |||||
int y3 = lol::min(y + 1, isize.y - 1); | |||||
int x3 = lol::min(x + 1, isize.x - 1); | |||||
float t = srcp[y * isize.x + x]; | |||||
t = lol::max(t, srcp[y * isize.x + x2]); | |||||
t = lol::max(t, srcp[y * isize.x + x3]); | |||||
t = lol::max(t, srcp[y2 * isize.x + x]); | |||||
t = lol::max(t, srcp[y3 * isize.x + x]); | |||||
dstp[y * isize.x + x] = t; | |||||
} | } | ||||
Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
vec4 const *srcp = Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 const *srcp = lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int y = 0; y < size.y; ++y) | |||||
for (int x = 0; x < size.x; ++x) | |||||
for (int y = 0; y < isize.y; ++y) | |||||
for (int x = 0; x < isize.x; ++x) | |||||
{ | { | ||||
int y2 = lol::max(y - 1, 0); | int y2 = lol::max(y - 1, 0); | ||||
int x2 = lol::max(x - 1, 0); | int x2 = lol::max(x - 1, 0); | ||||
int y3 = lol::min(y + 1, size.y - 1); | |||||
int x3 = lol::min(x + 1, size.x - 1); | |||||
vec3 t = srcp[y * size.x + x].rgb; | |||||
t = lol::max(t, srcp[y * size.x + x2].rgb); | |||||
t = lol::max(t, srcp[y * size.x + x3].rgb); | |||||
t = lol::max(t, srcp[y2 * size.x + x].rgb); | |||||
t = lol::max(t, srcp[y3 * size.x + x].rgb); | |||||
dstp[y * size.x + x] = vec4(t, srcp[y * size.x + x].a); | |||||
int y3 = lol::min(y + 1, isize.y - 1); | |||||
int x3 = lol::min(x + 1, isize.x - 1); | |||||
vec3 t = srcp[y * isize.x + x].rgb; | |||||
t = lol::max(t, srcp[y * isize.x + x2].rgb); | |||||
t = lol::max(t, srcp[y * isize.x + x3].rgb); | |||||
t = lol::max(t, srcp[y2 * isize.x + x].rgb); | |||||
t = lol::max(t, srcp[y3 * isize.x + x].rgb); | |||||
dstp[y * isize.x + x] = vec4(t, srcp[y * isize.x + x].a); | |||||
} | } | ||||
Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::Erode() | |||||
image image::Erode() | |||||
{ | { | ||||
ivec2 const size = GetSize(); | |||||
Image ret(size); | |||||
ivec2 isize = size(); | |||||
image ret(isize); | |||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
float const *srcp = Lock<PixelFormat::Y_F32>(); | |||||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||||
float const *srcp = lock<PixelFormat::Y_F32>(); | |||||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int y = 0; y < size.y; ++y) | |||||
for (int x = 0; x < size.x; ++x) | |||||
for (int y = 0; y < isize.y; ++y) | |||||
for (int x = 0; x < isize.x; ++x) | |||||
{ | { | ||||
int y2 = lol::max(y - 1, 0); | int y2 = lol::max(y - 1, 0); | ||||
int x2 = lol::max(x - 1, 0); | int x2 = lol::max(x - 1, 0); | ||||
int y3 = lol::min(y + 1, size.y - 1); | |||||
int x3 = lol::min(x + 1, size.x - 1); | |||||
float t = srcp[y * size.x + x]; | |||||
t = lol::max(t, srcp[y * size.x + x2]); | |||||
t = lol::max(t, srcp[y * size.x + x3]); | |||||
t = lol::max(t, srcp[y2 * size.x + x]); | |||||
t = lol::max(t, srcp[y3 * size.x + x]); | |||||
dstp[y * size.x + x] = t; | |||||
int y3 = lol::min(y + 1, isize.y - 1); | |||||
int x3 = lol::min(x + 1, isize.x - 1); | |||||
float t = srcp[y * isize.x + x]; | |||||
t = lol::max(t, srcp[y * isize.x + x2]); | |||||
t = lol::max(t, srcp[y * isize.x + x3]); | |||||
t = lol::max(t, srcp[y2 * isize.x + x]); | |||||
t = lol::max(t, srcp[y3 * isize.x + x]); | |||||
dstp[y * isize.x + x] = t; | |||||
} | } | ||||
Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
vec4 const *srcp = Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 const *srcp = lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int y = 0; y < size.y; ++y) | |||||
for (int x = 0; x < size.x; ++x) | |||||
for (int y = 0; y < isize.y; ++y) | |||||
for (int x = 0; x < isize.x; ++x) | |||||
{ | { | ||||
int y2 = lol::max(y - 1, 0); | int y2 = lol::max(y - 1, 0); | ||||
int x2 = lol::max(x - 1, 0); | int x2 = lol::max(x - 1, 0); | ||||
int y3 = lol::min(y + 1, size.y - 1); | |||||
int x3 = lol::min(x + 1, size.x - 1); | |||||
vec3 t = srcp[y * size.x + x].rgb; | |||||
t = lol::min(t, srcp[y * size.x + x2].rgb); | |||||
t = lol::min(t, srcp[y * size.x + x3].rgb); | |||||
t = lol::min(t, srcp[y2 * size.x + x].rgb); | |||||
t = lol::min(t, srcp[y3 * size.x + x].rgb); | |||||
dstp[y * size.x + x] = vec4(t, srcp[y * size.x + x].a); | |||||
int y3 = lol::min(y + 1, isize.y - 1); | |||||
int x3 = lol::min(x + 1, isize.x - 1); | |||||
vec3 t = srcp[y * isize.x + x].rgb; | |||||
t = lol::min(t, srcp[y * isize.x + x2].rgb); | |||||
t = lol::min(t, srcp[y * isize.x + x3].rgb); | |||||
t = lol::min(t, srcp[y2 * isize.x + x].rgb); | |||||
t = lol::min(t, srcp[y3 * isize.x + x].rgb); | |||||
dstp[y * isize.x + x] = vec4(t, srcp[y * isize.x + x].a); | |||||
} | } | ||||
Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
return ret; | return ret; | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -33,38 +35,38 @@ static int cmpfloat(void const *i1, void const *i2) | |||||
return (a > b) - (a < b); | return (a > b) - (a < b); | ||||
} | } | ||||
Image Image::Median(ivec2 ksize) const | |||||
image image::Median(ivec2 ksize) const | |||||
{ | { | ||||
ivec2 const size = GetSize(); | |||||
Image tmp = *this; | |||||
Image ret(size); | |||||
ivec2 const isize = size(); | |||||
image tmp = *this; | |||||
image ret(isize); | |||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
ivec2 const lsize = 2 * ksize + ivec2(1); | ivec2 const lsize = 2 * ksize + ivec2(1); | ||||
array2d<float> list(lsize); | array2d<float> list(lsize); | ||||
float *srcp = tmp.Lock<PixelFormat::Y_F32>(); | |||||
float *dstp = ret.Lock<PixelFormat::Y_F32>(); | |||||
float *srcp = tmp.lock<PixelFormat::Y_F32>(); | |||||
float *dstp = ret.lock<PixelFormat::Y_F32>(); | |||||
for (int y = 0; y < size.y; y++) | |||||
for (int y = 0; y < isize.y; y++) | |||||
{ | { | ||||
for (int x = 0; x < size.x; x++) | |||||
for (int x = 0; x < isize.x; x++) | |||||
{ | { | ||||
/* Make a list of neighbours */ | /* Make a list of neighbours */ | ||||
for (int j = -ksize.y; j <= ksize.y; j++) | for (int j = -ksize.y; j <= ksize.y; j++) | ||||
{ | { | ||||
int y2 = y + j; | int y2 = y + j; | ||||
if (y2 < 0) y2 = size.y - 1 - ((-y2 - 1) % size.y); | |||||
else if (y2 > 0) y2 = y2 % size.y; | |||||
if (y2 < 0) y2 = isize.y - 1 - ((-y2 - 1) % isize.y); | |||||
else if (y2 > 0) y2 = y2 % isize.y; | |||||
for (int i = -ksize.x; i <= ksize.x; i++) | for (int i = -ksize.x; i <= ksize.x; i++) | ||||
{ | { | ||||
int x2 = x + i; | int x2 = x + i; | ||||
if (x2 < 0) x2 = size.x - 1 - ((-x2 - 1) % size.x); | |||||
else if (x2 > 0) x2 = x2 % size.x; | |||||
if (x2 < 0) x2 = isize.x - 1 - ((-x2 - 1) % isize.x); | |||||
else if (x2 > 0) x2 = x2 % isize.x; | |||||
list[i + ksize.x][j + ksize.y] = srcp[y2 * size.x + x2]; | |||||
list[i + ksize.x][j + ksize.y] = srcp[y2 * isize.x + x2]; | |||||
} | } | ||||
} | } | ||||
@@ -72,39 +74,39 @@ Image Image::Median(ivec2 ksize) const | |||||
qsort(&list[0][0], lsize.x * lsize.y, sizeof(float), cmpfloat); | qsort(&list[0][0], lsize.x * lsize.y, sizeof(float), cmpfloat); | ||||
/* Store the median value */ | /* Store the median value */ | ||||
dstp[y * size.x + x] = *(&list[0][0] + lsize.x * lsize.y / 2); | |||||
dstp[y * isize.x + x] = *(&list[0][0] + lsize.x * lsize.y / 2); | |||||
} | } | ||||
} | } | ||||
tmp.Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
tmp.unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
ivec2 const lsize = 2 * ksize + ivec2(1); | ivec2 const lsize = 2 * ksize + ivec2(1); | ||||
array2d<vec3> list(lsize); | array2d<vec3> list(lsize); | ||||
vec4 *srcp = tmp.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *srcp = tmp.lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int y = 0; y < size.y; y++) | |||||
for (int y = 0; y < isize.y; y++) | |||||
{ | { | ||||
for (int x = 0; x < size.x; x++) | |||||
for (int x = 0; x < isize.x; x++) | |||||
{ | { | ||||
/* Make a list of neighbours */ | /* Make a list of neighbours */ | ||||
for (int j = -ksize.y; j <= ksize.y; j++) | for (int j = -ksize.y; j <= ksize.y; j++) | ||||
{ | { | ||||
int y2 = y + j; | int y2 = y + j; | ||||
if (y2 < 0) y2 = size.y - 1 - ((-y2 - 1) % size.y); | |||||
else if (y2 > 0) y2 = y2 % size.y; | |||||
if (y2 < 0) y2 = isize.y - 1 - ((-y2 - 1) % isize.y); | |||||
else if (y2 > 0) y2 = y2 % isize.y; | |||||
for (int i = -ksize.x; i <= ksize.x; i++) | for (int i = -ksize.x; i <= ksize.x; i++) | ||||
{ | { | ||||
int x2 = x + i; | int x2 = x + i; | ||||
if (x2 < 0) x2 = size.x - 1 - ((-x2 - 1) % size.x); | |||||
else if (x2 > 0) x2 = x2 % size.x; | |||||
if (x2 < 0) x2 = isize.x - 1 - ((-x2 - 1) % isize.x); | |||||
else if (x2 > 0) x2 = x2 % isize.x; | |||||
list[i + ksize.x][j + ksize.y] = srcp[y2 * size.x + x2].rgb; | |||||
list[i + ksize.x][j + ksize.y] = srcp[y2 * isize.x + x2].rgb; | |||||
} | } | ||||
} | } | ||||
@@ -139,26 +141,26 @@ Image Image::Median(ivec2 ksize) const | |||||
} | } | ||||
/* Store the median value */ | /* Store the median value */ | ||||
dstp[y * size.x + x] = vec4(median, srcp[y * size.x + x].a); | |||||
dstp[y * isize.x + x] = vec4(median, srcp[y * isize.x + x].a); | |||||
} | } | ||||
} | } | ||||
tmp.Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
tmp.unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::Median(array2d<float> const &kernel) const | |||||
image image::Median(array2d<float> const &kernel) const | |||||
{ | { | ||||
ivec2 const size = GetSize(); | |||||
Image tmp = *this; | |||||
Image ret(size); | |||||
ivec2 const isize = size(); | |||||
image tmp = *this; | |||||
image ret(isize); | |||||
/* FIXME: TODO */ | /* FIXME: TODO */ | ||||
#if 0 | #if 0 | ||||
if (GetFormat() == PixelFormat::Y_8 || GetFormat() == PixelFormat::Y_F32) | |||||
if (format() == PixelFormat::Y_8 || format() == PixelFormat::Y_F32) | |||||
{ | { | ||||
} | } | ||||
else | else | ||||
@@ -167,27 +169,27 @@ Image Image::Median(array2d<float> const &kernel) const | |||||
ivec2 const ksize = kernel.size(); | ivec2 const ksize = kernel.size(); | ||||
array2d<vec3> list(ksize); | array2d<vec3> list(ksize); | ||||
vec4 *srcp = tmp.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *srcp = tmp.lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int y = 0; y < size.y; y++) | |||||
for (int y = 0; y < isize.y; y++) | |||||
{ | { | ||||
for (int x = 0; x < size.x; x++) | |||||
for (int x = 0; x < isize.x; x++) | |||||
{ | { | ||||
/* Make a list of neighbours */ | /* Make a list of neighbours */ | ||||
for (int j = 0; j < ksize.y; j++) | for (int j = 0; j < ksize.y; j++) | ||||
{ | { | ||||
int y2 = y + j - ksize.y / 2; | int y2 = y + j - ksize.y / 2; | ||||
if (y2 < 0) y2 = size.y - 1 - ((-y2 - 1) % size.y); | |||||
else if (y2 > 0) y2 = y2 % size.y; | |||||
if (y2 < 0) y2 = isize.y - 1 - ((-y2 - 1) % isize.y); | |||||
else if (y2 > 0) y2 = y2 % isize.y; | |||||
for (int i = 0; i < ksize.x; i++) | for (int i = 0; i < ksize.x; i++) | ||||
{ | { | ||||
int x2 = x + i - ksize.x / 2; | int x2 = x + i - ksize.x / 2; | ||||
if (x2 < 0) x2 = size.x - 1 - ((-x2 - 1) % size.x); | |||||
else if (x2 > 0) x2 = x2 % size.x; | |||||
if (x2 < 0) x2 = isize.x - 1 - ((-x2 - 1) % isize.x); | |||||
else if (x2 > 0) x2 = x2 % isize.x; | |||||
list[i][j] = srcp[y2 * size.x + x2].rgb; | |||||
list[i][j] = srcp[y2 * isize.x + x2].rgb; | |||||
} | } | ||||
} | } | ||||
@@ -222,12 +224,12 @@ Image Image::Median(array2d<float> const &kernel) const | |||||
} | } | ||||
/* Store the median value */ | /* Store the median value */ | ||||
dstp[y * size.x + x] = vec4(median, srcp[y * size.x + x].a); | |||||
dstp[y * isize.x + x] = vec4(median, srcp[y * isize.x + x].a); | |||||
} | } | ||||
} | } | ||||
tmp.Unlock(srcp); | |||||
ret.Unlock(dstp); | |||||
tmp.unlock(srcp); | |||||
ret.unlock(dstp); | |||||
} | } | ||||
return ret; | return ret; | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,28 +19,28 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
Image Image::YUVToRGB() const | |||||
image image::YUVToRGB() const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = Color::YUVToRGB(pixels[n]); | pixels[n] = Color::YUVToRGB(pixels[n]); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
return ret; | return ret; | ||||
} | } | ||||
Image Image::RGBToYUV() const | |||||
image image::RGBToYUV() const | |||||
{ | { | ||||
Image ret = *this; | |||||
int count = GetSize().x * GetSize().y; | |||||
image ret = *this; | |||||
int count = size().x * size().y; | |||||
vec4 *pixels = ret.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *pixels = ret.lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < count; ++n) | for (int n = 0; n < count; ++n) | ||||
pixels[n] = Color::RGBToYUV(pixels[n]); | pixels[n] = Color::RGBToYUV(pixels[n]); | ||||
ret.Unlock(pixels); | |||||
ret.unlock(pixels); | |||||
return ret; | return ret; | ||||
} | } | ||||
@@ -43,12 +43,12 @@ public: | |||||
array2d<typename PixelType<T>::type> m_array2d; | array2d<typename PixelType<T>::type> m_array2d; | ||||
}; | }; | ||||
class ImageData | |||||
class image_data | |||||
{ | { | ||||
friend class Image; | |||||
friend class image; | |||||
public: | public: | ||||
ImageData() | |||||
image_data() | |||||
: m_size(0, 0), | : m_size(0, 0), | ||||
m_wrap_x(WrapMode::Clamp), | m_wrap_x(WrapMode::Clamp), | ||||
m_wrap_y(WrapMode::Clamp), | m_wrap_y(WrapMode::Clamp), | ||||
@@ -66,38 +66,5 @@ public: | |||||
PixelFormat m_format; | PixelFormat m_format; | ||||
}; | }; | ||||
class ImageCodec | |||||
{ | |||||
public: | |||||
virtual char const *GetName() { return "<ImageCodec>"; } | |||||
virtual bool Load(Image *image, char const *path) = 0; | |||||
virtual bool Save(Image *image, char const *path) = 0; | |||||
/* TODO: this should become more fine-grained */ | |||||
int m_priority; | |||||
}; | |||||
#define REGISTER_IMAGE_CODEC(name) \ | |||||
extern ImageCodec *Register##name(); \ | |||||
{ \ | |||||
/* Insert image codecs in a sorted list */ \ | |||||
ImageCodec *codec = Register##name(); \ | |||||
int i = 0, prio = codec->m_priority; \ | |||||
for ( ; i < codeclist.count(); ++i) \ | |||||
{ \ | |||||
if (codeclist[i]->m_priority <= prio) \ | |||||
break; \ | |||||
} \ | |||||
codeclist.insert(codec, i); \ | |||||
} | |||||
#define DECLARE_IMAGE_CODEC(name, priority) \ | |||||
ImageCodec *Register##name() \ | |||||
{ \ | |||||
ImageCodec *ret = new name(); \ | |||||
ret->m_priority = priority; \ | |||||
return ret; \ | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -19,89 +19,34 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
/* HACK: We cannot make this an ImageLoader member function, because the | |||||
* REGISTER_IMAGE_CODEC macro forward-declares free functions from | |||||
* the "lol" namespace. An apparent bug in Visual Studio's compiler | |||||
* makes it think these functions are actually in the top-level | |||||
* namespace when the forward declaration is in a class member function. | |||||
* To avoid the problem, we make the forward declaration in a free | |||||
* function. | |||||
* The bug was reported to Microsoft and fixed by them, but the fix | |||||
* is not yet available. | |||||
* https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */ | |||||
static bool RegisterAllCodecs(array<ImageCodec *> &codeclist) | |||||
{ | |||||
#if defined __ANDROID__ | |||||
REGISTER_IMAGE_CODEC(AndroidImageCodec) | |||||
#endif | |||||
#if defined LOL_USE_GDIPLUS | |||||
REGISTER_IMAGE_CODEC(GdiPlusImageCodec) | |||||
#endif | |||||
#if defined __APPLE__ && defined __MACH__ && defined __arm__ | |||||
REGISTER_IMAGE_CODEC(IosImageCodec) | |||||
#endif | |||||
#if defined LOL_USE_SDL_IMAGE | |||||
REGISTER_IMAGE_CODEC(SdlImageCodec) | |||||
#endif | |||||
#if defined LOL_USE_IMLIB2 | |||||
REGISTER_IMAGE_CODEC(Imlib2ImageCodec) | |||||
#endif | |||||
REGISTER_IMAGE_CODEC(DummyImageCodec) | |||||
REGISTER_IMAGE_CODEC(ZedImageCodec) | |||||
REGISTER_IMAGE_CODEC(ZedPaletteImageCodec) | |||||
REGISTER_IMAGE_CODEC(OricImageCodec) | |||||
return true; | |||||
} | |||||
/* | /* | ||||
* Our static image loader | |||||
* Public image class | |||||
*/ | */ | ||||
static class ImageLoader | |||||
image::image() | |||||
: m_data(new image_data()) | |||||
{ | { | ||||
friend class Image; | |||||
public: | |||||
inline ImageLoader() | |||||
{ | |||||
RegisterAllCodecs(m_codecs); | |||||
} | |||||
private: | |||||
array<ImageCodec *> m_codecs; | |||||
map<String, Image *> m_images; | |||||
} | } | ||||
g_image_loader; | |||||
/* | |||||
* Public Image class | |||||
*/ | |||||
Image::Image() | |||||
: m_data(new ImageData()) | |||||
{ | |||||
} | |||||
Image::Image(char const *path) | |||||
: m_data(new ImageData()) | |||||
image::image(char const *path) | |||||
: m_data(new image_data()) | |||||
{ | { | ||||
Load(path); | |||||
load(path); | |||||
} | } | ||||
Image::Image(ivec2 size) | |||||
: m_data(new ImageData()) | |||||
image::image(ivec2 size) | |||||
: m_data(new image_data()) | |||||
{ | { | ||||
SetSize(size); | |||||
resize(size); | |||||
} | } | ||||
Image::Image (Image const &other) | |||||
: m_data(new ImageData()) | |||||
image::image (image const &other) | |||||
: m_data(new image_data()) | |||||
{ | { | ||||
Copy(other); | Copy(other); | ||||
} | } | ||||
Image & Image::operator =(Image other) | |||||
image & image::operator =(image other) | |||||
{ | { | ||||
/* Since the argument is passed by value, we’re assured it’s a new | /* Since the argument is passed by value, we’re assured it’s a new | ||||
* object and we can safely swap our m_data pointers. */ | * object and we can safely swap our m_data pointers. */ | ||||
@@ -109,7 +54,7 @@ Image & Image::operator =(Image other) | |||||
return *this; | return *this; | ||||
} | } | ||||
Image::~Image() | |||||
image::~image() | |||||
{ | { | ||||
for (int k : m_data->m_pixels.keys()) | for (int k : m_data->m_pixels.keys()) | ||||
delete m_data->m_pixels[k]; | delete m_data->m_pixels[k]; | ||||
@@ -117,85 +62,67 @@ Image::~Image() | |||||
delete m_data; | delete m_data; | ||||
} | } | ||||
void Image::DummyFill() | |||||
{ | |||||
//TODO: This is not very beautiful | |||||
for (auto codec : g_image_loader.m_codecs) | |||||
{ | |||||
if (String(codec->GetName()).contains("Dummy")) | |||||
{ | |||||
codec->Load(this, nullptr); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
void Image::Copy(uint8_t* pixels, ivec2 const& size, PixelFormat fmt) | |||||
void image::Copy(uint8_t* src_pixels, ivec2 const& size, PixelFormat fmt) | |||||
{ | { | ||||
ASSERT(fmt != PixelFormat::Unknown); | ASSERT(fmt != PixelFormat::Unknown); | ||||
SetSize(size); | |||||
SetFormat(fmt); | |||||
memcpy(m_data->m_pixels[(int)fmt]->data(), pixels, | |||||
resize(size); | |||||
set_format(fmt); | |||||
memcpy(m_data->m_pixels[(int)fmt]->data(), src_pixels, | |||||
size.x * size.y * BytesPerPixel(fmt)); | size.x * size.y * BytesPerPixel(fmt)); | ||||
} | } | ||||
void Image::Copy(Image const &other) | |||||
void image::Copy(image const &src) | |||||
{ | { | ||||
ivec2 size = other.GetSize(); | |||||
PixelFormat fmt = other.GetFormat(); | |||||
ivec2 size = src.size(); | |||||
PixelFormat fmt = src.format(); | |||||
SetSize(size); | |||||
resize(size); | |||||
if (fmt != PixelFormat::Unknown) | if (fmt != PixelFormat::Unknown) | ||||
{ | { | ||||
SetFormat(fmt); | |||||
set_format(fmt); | |||||
memcpy(m_data->m_pixels[(int)fmt]->data(), | memcpy(m_data->m_pixels[(int)fmt]->data(), | ||||
other.m_data->m_pixels[(int)fmt]->data(), | |||||
src.m_data->m_pixels[(int)fmt]->data(), | |||||
size.x * size.y * BytesPerPixel(fmt)); | size.x * size.y * BytesPerPixel(fmt)); | ||||
} | } | ||||
} | } | ||||
bool Image::Load(char const *path) | |||||
void image::DummyFill() | |||||
{ | { | ||||
ImageCodec* last_codec = nullptr; | |||||
for (auto codec : g_image_loader.m_codecs) | |||||
{ | |||||
last_codec = codec; | |||||
if (codec->Load(this, path)) | |||||
{ | |||||
msg::info("Image::Load: Codec %s succesfully loaded %s.\n", codec->GetName(), path); | |||||
return true; | |||||
} | |||||
} | |||||
//Log error, because we shouldn't be here | |||||
msg::error("Image::Load: Last codec %s, Error loading image %s.\n", last_codec->GetName(), path); | |||||
return false; | |||||
load("DUMMY"); | |||||
} | } | ||||
bool Image::Save(char const *path) | |||||
bool image::load(char const *path) | |||||
{ | { | ||||
ImageCodec* last_codec = nullptr; | |||||
for (auto codec : g_image_loader.m_codecs) | |||||
auto resource = ResourceLoader::Load(path); | |||||
if (resource == nullptr) | |||||
return false; | |||||
auto image_resource = dynamic_cast<ResourceImageData*>(resource); | |||||
if (image_resource == nullptr) | |||||
{ | { | ||||
last_codec = codec; | |||||
if (codec->Save(this, path)) | |||||
{ | |||||
msg::info("Image::Save: Codec %s succesfully saved %s.\n", codec->GetName(), path); | |||||
return true; | |||||
} | |||||
delete image_resource; | |||||
return false; | |||||
} | } | ||||
//Log error, because we shouldn't be here | |||||
msg::error("Image::Save: Last codec %s, Error saving image %s.\n", last_codec->GetName(), path); | |||||
return false; | |||||
Copy(*image_resource->m_image); | |||||
delete image_resource; | |||||
return true; | |||||
} | } | ||||
ivec2 Image::GetSize() const | |||||
bool image::save(char const *path) | |||||
{ | |||||
auto data = new ResourceImageData(new image(*this)); | |||||
auto result = ResourceLoader::Save(path, data); | |||||
delete data; | |||||
return result; | |||||
} | |||||
ivec2 image::size() const | |||||
{ | { | ||||
return m_data->m_size; | return m_data->m_size; | ||||
} | } | ||||
void Image::SetSize(ivec2 size) | |||||
void image::resize(ivec2 size) | |||||
{ | { | ||||
ASSERT(size.x > 0); | ASSERT(size.x > 0); | ||||
ASSERT(size.y > 0); | ASSERT(size.y > 0); | ||||
@@ -215,40 +142,40 @@ void Image::SetSize(ivec2 size) | |||||
} | } | ||||
/* Wrap-around mode for some operations */ | /* Wrap-around mode for some operations */ | ||||
WrapMode Image::GetWrapX() const | |||||
WrapMode image::GetWrapX() const | |||||
{ | { | ||||
return m_data->m_wrap_x; | return m_data->m_wrap_x; | ||||
} | } | ||||
WrapMode Image::GetWrapY() const | |||||
WrapMode image::GetWrapY() const | |||||
{ | { | ||||
return m_data->m_wrap_y; | return m_data->m_wrap_y; | ||||
} | } | ||||
void Image::SetWrap(WrapMode wrap_x, WrapMode wrap_y) | |||||
void image::SetWrap(WrapMode wrap_x, WrapMode wrap_y) | |||||
{ | { | ||||
m_data->m_wrap_x = wrap_x; | m_data->m_wrap_x = wrap_x; | ||||
m_data->m_wrap_y = wrap_y; | m_data->m_wrap_y = wrap_y; | ||||
} | } | ||||
/* The Lock() method */ | |||||
template<PixelFormat T> typename PixelType<T>::type *Image::Lock() | |||||
/* The lock() method */ | |||||
template<PixelFormat T> typename PixelType<T>::type *image::lock() | |||||
{ | { | ||||
SetFormat(T); | |||||
set_format(T); | |||||
return (typename PixelType<T>::type *)m_data->m_pixels[(int)T]->data(); | return (typename PixelType<T>::type *)m_data->m_pixels[(int)T]->data(); | ||||
} | } | ||||
/* The Lock2D() method */ | |||||
void *Image::Lock2DHelper(PixelFormat T) | |||||
/* The lock2d() method */ | |||||
void *image::lock2d_helper(PixelFormat T) | |||||
{ | { | ||||
SetFormat(T); | |||||
set_format(T); | |||||
return m_data->m_pixels[(int)T]->data2d(); | return m_data->m_pixels[(int)T]->data2d(); | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
void Image::Unlock2D(array2d<T> const &array) | |||||
void image::unlock2d(array2d<T> const &array) | |||||
{ | { | ||||
ASSERT(m_data->m_pixels.has_key((int)m_data->m_format)); | ASSERT(m_data->m_pixels.has_key((int)m_data->m_format)); | ||||
ASSERT(array.data() == m_data->m_pixels[(int)m_data->m_format]->data()); | ASSERT(array.data() == m_data->m_pixels[(int)m_data->m_format]->data()); | ||||
@@ -256,9 +183,9 @@ void Image::Unlock2D(array2d<T> const &array) | |||||
/* Explicit specialisations for the above templates */ | /* Explicit specialisations for the above templates */ | ||||
#define _T(T) \ | #define _T(T) \ | ||||
template PixelType<T>::type *Image::Lock<T>(); \ | |||||
template array2d<PixelType<T>::type> &Image::Lock2D<T>(); \ | |||||
template void Image::Unlock2D(array2d<PixelType<T>::type> const &array); | |||||
template PixelType<T>::type *image::lock<T>(); \ | |||||
template array2d<PixelType<T>::type> &image::lock2d<T>(); \ | |||||
template void image::unlock2d(array2d<PixelType<T>::type> const &array); | |||||
_T(PixelFormat::Y_8) | _T(PixelFormat::Y_8) | ||||
_T(PixelFormat::RGB_8) | _T(PixelFormat::RGB_8) | ||||
_T(PixelFormat::RGBA_8) | _T(PixelFormat::RGBA_8) | ||||
@@ -268,25 +195,18 @@ _T(PixelFormat::RGBA_F32) | |||||
#undef _T | #undef _T | ||||
/* Special case for the "any" format: return the last active buffer */ | /* Special case for the "any" format: return the last active buffer */ | ||||
void *Image::Lock() | |||||
void *image::lock() | |||||
{ | { | ||||
ASSERT(m_data->m_format != PixelFormat::Unknown); | ASSERT(m_data->m_format != PixelFormat::Unknown); | ||||
return m_data->m_pixels[(int)m_data->m_format]->data(); | return m_data->m_pixels[(int)m_data->m_format]->data(); | ||||
} | } | ||||
void Image::Unlock(void const *pixels) | |||||
void image::unlock(void const *pixels) | |||||
{ | { | ||||
ASSERT(m_data->m_pixels.has_key((int)m_data->m_format)); | ASSERT(m_data->m_pixels.has_key((int)m_data->m_format)); | ||||
ASSERT(pixels == m_data->m_pixels[(int)m_data->m_format]->data()); | ASSERT(pixels == m_data->m_pixels[(int)m_data->m_format]->data()); | ||||
} | } | ||||
bool Image::RetrieveTiles(array<ivec2, ivec2>& tiles) const | |||||
{ | |||||
/* TODO: re-implement this */ | |||||
//return m_data->m_codecdata->RetrieveTiles(tiles); | |||||
return false; | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,7 +19,7 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
array2d<float> Image::BayerKernel(ivec2 size) | |||||
array2d<float> image::kernel::bayer(ivec2 size) | |||||
{ | { | ||||
array2d<float> ret(size); | array2d<float> ret(size); | ||||
@@ -46,7 +48,7 @@ array2d<float> Image::BayerKernel(ivec2 size) | |||||
return ret; | return ret; | ||||
} | } | ||||
array2d<float> Image::HalftoneKernel(ivec2 size) | |||||
array2d<float> image::kernel::halftone(ivec2 size) | |||||
{ | { | ||||
array2d<float> ret(size); | array2d<float> ret(size); | ||||
@@ -72,10 +74,10 @@ array2d<float> Image::HalftoneKernel(ivec2 size) | |||||
ret[x][y] = flip ? 10.f - r : r; | ret[x][y] = flip ? 10.f - r : r; | ||||
} | } | ||||
return NormalizeKernel(ret); | |||||
return normalize(ret); | |||||
} | } | ||||
array2d<float> Image::BlueNoiseKernel(ivec2 size, ivec2 gsize) | |||||
array2d<float> image::kernel::blue_noise(ivec2 size, ivec2 gsize) | |||||
{ | { | ||||
float const epsilon = 1.f / (size.x * size.y + 1); | float const epsilon = 1.f / (size.x * size.y + 1); | ||||
gsize = lol::min(size, gsize); | gsize = lol::min(size, gsize); | ||||
@@ -180,7 +182,7 @@ static int cmpdot(const void *p1, const void *p2) | |||||
return ((Dot const *)p1)->val > ((Dot const *)p2)->val; | return ((Dot const *)p1)->val > ((Dot const *)p2)->val; | ||||
} | } | ||||
array2d<float> Image::NormalizeKernel(array2d<float> const &kernel) | |||||
array2d<float> image::kernel::normalize(array2d<float> const &kernel) | |||||
{ | { | ||||
ivec2 size = kernel.size(); | ivec2 size = kernel.size(); | ||||
@@ -209,7 +211,7 @@ array2d<float> Image::NormalizeKernel(array2d<float> const &kernel) | |||||
return dst; | return dst; | ||||
} | } | ||||
array2d<float> Image::EdiffKernel(EdiffAlgorithm algorithm) | |||||
array2d<float> image::kernel::ediff(EdiffAlgorithm algorithm) | |||||
{ | { | ||||
switch (algorithm) | switch (algorithm) | ||||
{ | { | ||||
@@ -270,7 +272,7 @@ array2d<float> Image::EdiffKernel(EdiffAlgorithm algorithm) | |||||
* there is little chance that any value below 0.2 will be useful. */ | * there is little chance that any value below 0.2 will be useful. */ | ||||
#define BLUR_EPSILON 0.2f | #define BLUR_EPSILON 0.2f | ||||
array2d<float> Image::GaussianKernel(vec2 radius, float angle, vec2 delta) | |||||
array2d<float> image::kernel::gaussian(vec2 radius, float angle, vec2 delta) | |||||
{ | { | ||||
array2d<float> kernel; | array2d<float> kernel; | ||||
@@ -60,7 +60,7 @@ Movie::~Movie() | |||||
delete m_data; | delete m_data; | ||||
} | } | ||||
void Movie::Feed(Image const &image) | |||||
void Movie::Feed(image const &image) | |||||
{ | { | ||||
#if LOL_USE_FFMPEG | #if LOL_USE_FFMPEG | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,10 +19,10 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
bool Image::RenderRandom(ivec2 size) | |||||
bool image::RenderRandom(ivec2 size) | |||||
{ | { | ||||
SetSize(size); | |||||
vec4 *pixels = Lock<PixelFormat::RGBA_F32>(); | |||||
resize(size); | |||||
vec4 *pixels = lock<PixelFormat::RGBA_F32>(); | |||||
for (int n = 0; n < size.x * size.y; ++n) | for (int n = 0; n < size.x * size.y; ++n) | ||||
pixels[n] = vec4(lol::rand(1.f), | pixels[n] = vec4(lol::rand(1.f), | ||||
@@ -28,7 +30,7 @@ bool Image::RenderRandom(ivec2 size) | |||||
lol::rand(1.f), | lol::rand(1.f), | ||||
1.f); | 1.f); | ||||
Unlock(pixels); | |||||
unlock(pixels); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2004—2015 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -60,7 +60,7 @@ static u8vec4 f32tou8(vec4 pixel) | |||||
* Pixel-level image manipulation | * Pixel-level image manipulation | ||||
*/ | */ | ||||
PixelFormat Image::GetFormat() const | |||||
PixelFormat image::format() const | |||||
{ | { | ||||
return m_data->m_format; | return m_data->m_format; | ||||
} | } | ||||
@@ -81,41 +81,41 @@ PixelFormat Image::GetFormat() const | |||||
* x lossless conversion (u8 to float) | * x lossless conversion (u8 to float) | ||||
* # lossy conversion (dithering and/or convert color→gray) | * # lossy conversion (dithering and/or convert color→gray) | ||||
*/ | */ | ||||
void Image::SetFormat(PixelFormat fmt) | |||||
void image::set_format(PixelFormat fmt) | |||||
{ | { | ||||
PixelFormat old_fmt = m_data->m_format; | PixelFormat old_fmt = m_data->m_format; | ||||
/* Preliminary intermediate conversions */ | /* Preliminary intermediate conversions */ | ||||
if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_F32) | if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_F32) | ||||
SetFormat(PixelFormat::RGBA_F32); | |||||
set_format(PixelFormat::RGBA_F32); | |||||
else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_F32) | else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_F32) | ||||
SetFormat(PixelFormat::RGBA_F32); | |||||
set_format(PixelFormat::RGBA_F32); | |||||
else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGBA_8) | else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGBA_8) | ||||
SetFormat(PixelFormat::RGBA_F32); | |||||
set_format(PixelFormat::RGBA_F32); | |||||
else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGB_8) | else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGB_8) | ||||
SetFormat(PixelFormat::RGBA_F32); | |||||
set_format(PixelFormat::RGBA_F32); | |||||
else if (old_fmt == PixelFormat::RGB_F32 && fmt == PixelFormat::RGBA_8) | else if (old_fmt == PixelFormat::RGB_F32 && fmt == PixelFormat::RGBA_8) | ||||
SetFormat(PixelFormat::RGBA_F32); | |||||
set_format(PixelFormat::RGBA_F32); | |||||
else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_F32) | else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_F32) | ||||
SetFormat(PixelFormat::RGB_F32); | |||||
set_format(PixelFormat::RGB_F32); | |||||
else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::RGB_8) | else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::RGB_8) | ||||
SetFormat(PixelFormat::RGB_F32); | |||||
set_format(PixelFormat::RGB_F32); | |||||
else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_8) | else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_8) | ||||
SetFormat(PixelFormat::RGB_F32); | |||||
set_format(PixelFormat::RGB_F32); | |||||
else if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_8) | else if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_8) | ||||
SetFormat(PixelFormat::RGB_F32); | |||||
set_format(PixelFormat::RGB_F32); | |||||
else if (old_fmt == PixelFormat::RGB_F32 && fmt == PixelFormat::Y_8) | else if (old_fmt == PixelFormat::RGB_F32 && fmt == PixelFormat::Y_8) | ||||
SetFormat(PixelFormat::Y_F32); | |||||
set_format(PixelFormat::Y_F32); | |||||
else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_8) | else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_8) | ||||
SetFormat(PixelFormat::Y_F32); | |||||
set_format(PixelFormat::Y_F32); | |||||
old_fmt = m_data->m_format; | old_fmt = m_data->m_format; | ||||
/* Set the new active pixel format */ | /* Set the new active pixel format */ | ||||
m_data->m_format = fmt; | m_data->m_format = fmt; | ||||
ivec2 size = GetSize(); | |||||
int count = size.x * size.y; | |||||
ivec2 isize = size(); | |||||
int count = isize.x * isize.y; | |||||
/* If we never used this format, allocate a new buffer: we will | /* If we never used this format, allocate a new buffer: we will | ||||
* obviously need it. */ | * obviously need it. */ | ||||
@@ -131,17 +131,17 @@ void Image::SetFormat(PixelFormat fmt) | |||||
case PixelFormat::Unknown: | case PixelFormat::Unknown: | ||||
break; | break; | ||||
case PixelFormat::Y_8: | case PixelFormat::Y_8: | ||||
data = new PixelData<PixelFormat::Y_8>(size); break; | |||||
data = new PixelData<PixelFormat::Y_8>(isize); break; | |||||
case PixelFormat::RGB_8: | case PixelFormat::RGB_8: | ||||
data = new PixelData<PixelFormat::RGB_8>(size); break; | |||||
data = new PixelData<PixelFormat::RGB_8>(isize); break; | |||||
case PixelFormat::RGBA_8: | case PixelFormat::RGBA_8: | ||||
data = new PixelData<PixelFormat::RGBA_8>(size); break; | |||||
data = new PixelData<PixelFormat::RGBA_8>(isize); break; | |||||
case PixelFormat::Y_F32: | case PixelFormat::Y_F32: | ||||
data = new PixelData<PixelFormat::Y_F32>(size); break; | |||||
data = new PixelData<PixelFormat::Y_F32>(isize); break; | |||||
case PixelFormat::RGB_F32: | case PixelFormat::RGB_F32: | ||||
data = new PixelData<PixelFormat::RGB_F32>(size); break; | |||||
data = new PixelData<PixelFormat::RGB_F32>(isize); break; | |||||
case PixelFormat::RGBA_F32: | case PixelFormat::RGBA_F32: | ||||
data = new PixelData<PixelFormat::RGBA_F32>(size); break; | |||||
data = new PixelData<PixelFormat::RGBA_F32>(isize); break; | |||||
} | } | ||||
#if __GNUC__ | #if __GNUC__ | ||||
#pragma GCC diagnostic pop | #pragma GCC diagnostic pop | ||||
@@ -314,31 +314,31 @@ void Image::SetFormat(PixelFormat fmt) | |||||
#if 0 | #if 0 | ||||
init_tables(); | init_tables(); | ||||
for (int y = 0; y < size.y; y++) | |||||
for (int x = 0; x < size.x; x++) | |||||
for (int y = 0; y < isize.y; y++) | |||||
for (int x = 0; x < isize.x; x++) | |||||
for (i = 0; i < 4; i++) | for (i = 0; i < 4; i++) | ||||
{ | { | ||||
double p, e; | double p, e; | ||||
uint8_t d; | uint8_t d; | ||||
p = src[4 * (y * size.x + x) + i]; | |||||
p = src[4 * (y * isize.x + x) + i]; | |||||
if (p < 0.) d = 0.; | if (p < 0.) d = 0.; | ||||
else if (p > 1.) d = 255; | else if (p > 1.) d = 255; | ||||
else d = (int)(255.999 * pow(p, 1. / global_gamma)); | else d = (int)(255.999 * pow(p, 1. / global_gamma)); | ||||
dest[4 * (y * size.x + x) + i] = d; | |||||
dest[4 * (y * isize.x + x) + i] = d; | |||||
e = (p - u8tof32(d)) / 16; | e = (p - u8tof32(d)) / 16; | ||||
if (x < size.x - 1) | |||||
src[4 * (y * size.x + x + 1) + i] += e * 7; | |||||
if (y < size.y - 1) | |||||
if (x < isize.x - 1) | |||||
src[4 * (y * isize.x + x + 1) + i] += e * 7; | |||||
if (y < isize.y - 1) | |||||
{ | { | ||||
if (x > 0) | if (x > 0) | ||||
src[4 * ((y + 1) * size.x + x - 1) + i] += e * 3; | |||||
src[4 * ((y + 1) * size.x + x) + i] += e * 5; | |||||
if (x < size.x - 1) | |||||
src[4 * ((y + 1) * size.x + x + 1) + i] += e; | |||||
src[4 * ((y + 1) * isize.x + x - 1) + i] += e * 3; | |||||
src[4 * ((y + 1) * isize.x + x) + i] += e * 5; | |||||
if (x < isize.x - 1) | |||||
src[4 * ((y + 1) * isize.x + x + 1) + i] += e; | |||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -17,10 +19,10 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
static Image ResizeBicubic(Image &image, ivec2 size); | |||||
static Image ResizeBresenham(Image &image, ivec2 size); | |||||
static image ResizeBicubic(image &src, ivec2 size); | |||||
static image ResizeBresenham(image &src, ivec2 size); | |||||
Image Image::Resize(ivec2 size, ResampleAlgorithm algorithm) | |||||
image image::Resize(ivec2 size, ResampleAlgorithm algorithm) | |||||
{ | { | ||||
switch (algorithm) | switch (algorithm) | ||||
{ | { | ||||
@@ -32,13 +34,13 @@ Image Image::Resize(ivec2 size, ResampleAlgorithm algorithm) | |||||
} | } | ||||
} | } | ||||
static Image ResizeBicubic(Image &image, ivec2 size) | |||||
static image ResizeBicubic(image &src, ivec2 size) | |||||
{ | { | ||||
Image dst(size); | |||||
ivec2 const oldsize = image.GetSize(); | |||||
image dst(size); | |||||
ivec2 const oldsize = src.size(); | |||||
vec4 const *srcp = image.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = dst.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 const *srcp = src.lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = dst.lock<PixelFormat::RGBA_F32>(); | |||||
float scalex = size.x > 1 ? (oldsize.x - 1.f) / (size.x - 1) : 1.f; | float scalex = size.x > 1 ? (oldsize.x - 1.f) / (size.x - 1) : 1.f; | ||||
float scaley = size.y > 1 ? (oldsize.y - 1.f) / (size.y - 1) : 1.f; | float scaley = size.y > 1 ? (oldsize.y - 1.f) / (size.y - 1) : 1.f; | ||||
@@ -121,8 +123,8 @@ static Image ResizeBicubic(Image &image, ivec2 size) | |||||
} | } | ||||
} | } | ||||
dst.Unlock(dstp); | |||||
image.Unlock(srcp); | |||||
dst.unlock(dstp); | |||||
src.unlock(srcp); | |||||
return dst; | return dst; | ||||
} | } | ||||
@@ -134,14 +136,14 @@ static Image ResizeBicubic(Image &image, ivec2 size) | |||||
/* FIXME: the algorithm does not handle alpha components properly. Resulting | /* FIXME: the algorithm does not handle alpha components properly. Resulting | ||||
* alpha should be the mean alpha value of the neightbouring pixels, but | * alpha should be the mean alpha value of the neightbouring pixels, but | ||||
* the colour components should be weighted with the alpha value. */ | * the colour components should be weighted with the alpha value. */ | ||||
static Image ResizeBresenham(Image &image, ivec2 size) | |||||
static image ResizeBresenham(image &src, ivec2 size) | |||||
{ | { | ||||
Image dst(size); | |||||
ivec2 const oldsize = image.GetSize(); | |||||
image dst(size); | |||||
ivec2 const oldsize = src.size(); | |||||
float const invswsh = 1.0f / (oldsize.x * oldsize.y); | float const invswsh = 1.0f / (oldsize.x * oldsize.y); | ||||
vec4 const *srcp = image.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = dst.Lock<PixelFormat::RGBA_F32>(); | |||||
vec4 const *srcp = src.lock<PixelFormat::RGBA_F32>(); | |||||
vec4 *dstp = dst.lock<PixelFormat::RGBA_F32>(); | |||||
array<vec4> aline, line; | array<vec4> aline, line; | ||||
aline.resize(size.x); | aline.resize(size.x); | ||||
@@ -198,8 +200,8 @@ static Image ResizeBresenham(Image &image, ivec2 size) | |||||
dstp[y * size.x + x] = aline[x] * invswsh; | dstp[y * size.x + x] = aline[x] * invswsh; | ||||
} | } | ||||
dst.Unlock(dstp); | |||||
image.Unlock(srcp); | |||||
dst.unlock(dstp); | |||||
src.unlock(srcp); | |||||
return dst; | return dst; | ||||
} | } | ||||
@@ -0,0 +1,57 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright: (c) 2016—2017 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2016—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// | |||||
#pragma once | |||||
// | |||||
// The ResourceCodecData class | |||||
// ------------------------ | |||||
// | |||||
namespace lol | |||||
{ | |||||
class ResourceCodec | |||||
{ | |||||
public: | |||||
virtual char const *GetName() { return "<ResourceCodec>"; } | |||||
virtual ResourceCodecData* Load(char const *path) = 0; | |||||
virtual bool Save(char const *path, ResourceCodecData* data) = 0; | |||||
/* TODO: this should become more fine-grained */ | |||||
int m_priority; | |||||
}; | |||||
#define REGISTER_IMAGE_CODEC(name) \ | |||||
extern ResourceCodec *Register##name(); \ | |||||
{ \ | |||||
/* Insert image codecs in a sorted list */ \ | |||||
ResourceCodec *codec = Register##name(); \ | |||||
int i = 0, prio = codec->m_priority; \ | |||||
for ( ; i < codeclist.count(); ++i) \ | |||||
{ \ | |||||
if (codeclist[i]->m_priority <= prio) \ | |||||
break; \ | |||||
} \ | |||||
codeclist.insert(codec, i); \ | |||||
} | |||||
#define DECLARE_IMAGE_CODEC(name, priority) \ | |||||
ResourceCodec *Register##name() \ | |||||
{ \ | |||||
ResourceCodec *ret = new name(); \ | |||||
ret->m_priority = priority; \ | |||||
return ret; \ | |||||
} | |||||
} /* namespace lol */ | |||||
@@ -0,0 +1,121 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright © 2016—2017 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2016—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | |||||
#include <lol/engine-internal.h> | |||||
#include "resource-private.h" | |||||
#include <algorithm> /* for std::swap */ | |||||
namespace lol | |||||
{ | |||||
/* HACK: We cannot make this an ImageLoader member function, because the | |||||
* REGISTER_IMAGE_CODEC macro forward-declares free functions from | |||||
* the "lol" namespace. An apparent bug in Visual Studio's compiler | |||||
* makes it think these functions are actually in the top-level | |||||
* namespace when the forward declaration is in a class member function. | |||||
* To avoid the problem, we make the forward declaration in a free | |||||
* function. | |||||
* The bug was reported to Microsoft and fixed by them, but the fix | |||||
* is not yet available. | |||||
* https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */ | |||||
static bool RegisterAllCodecs(array<ResourceCodec *> &codeclist) | |||||
{ | |||||
#if defined __ANDROID__ | |||||
REGISTER_IMAGE_CODEC(AndroidImageCodec) | |||||
#endif | |||||
#if defined LOL_USE_GDIPLUS | |||||
REGISTER_IMAGE_CODEC(GdiPlusImageCodec) | |||||
#endif | |||||
#if defined __APPLE__ && defined __MACH__ && defined __arm__ | |||||
REGISTER_IMAGE_CODEC(IosImageCodec) | |||||
#endif | |||||
#if defined LOL_USE_SDL_IMAGE | |||||
REGISTER_IMAGE_CODEC(SdlImageCodec) | |||||
#endif | |||||
#if defined LOL_USE_IMLIB2 | |||||
REGISTER_IMAGE_CODEC(Imlib2ImageCodec) | |||||
#endif | |||||
REGISTER_IMAGE_CODEC(ZedImageCodec) | |||||
REGISTER_IMAGE_CODEC(ZedPaletteImageCodec) | |||||
REGISTER_IMAGE_CODEC(OricImageCodec) | |||||
REGISTER_IMAGE_CODEC(DummyImageCodec) | |||||
return true; | |||||
} | |||||
/* | |||||
* Our static image loader | |||||
*/ | |||||
static class StaticResourceLoader | |||||
{ | |||||
friend class ResourceLoader; | |||||
public: | |||||
inline StaticResourceLoader() | |||||
{ | |||||
RegisterAllCodecs(m_codecs); | |||||
} | |||||
private: | |||||
array<ResourceCodec *> m_codecs; | |||||
} | |||||
g_resource_loader; | |||||
/* | |||||
* The public resource loader | |||||
*/ | |||||
ResourceCodecData* ResourceLoader::Load(char const *path) | |||||
{ | |||||
ResourceCodec* last_codec = nullptr; | |||||
for (auto codec : g_resource_loader.m_codecs) | |||||
{ | |||||
last_codec = codec; | |||||
auto data = codec->Load(path); | |||||
if (data != nullptr) | |||||
{ | |||||
msg::info("image::Load: Codec %s succesfully loaded %s.\n", codec->GetName(), path); | |||||
return data; | |||||
} | |||||
} | |||||
//Log error, because we shouldn't be here | |||||
msg::error("image::Load: Last codec %s, Error loading resource %s.\n", last_codec->GetName(), path); | |||||
return nullptr; | |||||
} | |||||
bool ResourceLoader::Save(char const *path, ResourceCodecData* data) | |||||
{ | |||||
ResourceCodec* last_codec = nullptr; | |||||
for (auto codec : g_resource_loader.m_codecs) | |||||
{ | |||||
last_codec = codec; | |||||
if (codec->Save(path, data)) | |||||
{ | |||||
msg::info("image::Save: Codec %s succesfully saved %s.\n", codec->GetName(), path); | |||||
return true; | |||||
} | |||||
} | |||||
//Log error, because we shouldn't be here | |||||
msg::error("image::Save: Last codec %s, Error saving resource %s.\n", last_codec->GetName(), path); | |||||
return false; | |||||
} | |||||
} /* namespace lol */ | |||||
@@ -36,6 +36,16 @@ String InputDevice::GetText() | |||||
return ret; | return ret; | ||||
} | } | ||||
bool InputDevice::IsTextInputActive() | |||||
{ | |||||
return m_input_active; | |||||
} | |||||
void InputDevice::SetTextInputActive(bool status) | |||||
{ | |||||
m_input_active = status; | |||||
} | |||||
void InputDeviceInternal::AddKey(int index, const char* name) | void InputDeviceInternal::AddKey(int index, const char* name) | ||||
{ | { | ||||
if (index == -1) | if (index == -1) | ||||
@@ -104,7 +114,7 @@ InputDeviceInternal* InputDeviceInternal::CreateStandardMouse() | |||||
mouse->AddAxis(g_name_mouse_axis_y.C()); | mouse->AddAxis(g_name_mouse_axis_y.C()); | ||||
mouse->AddAxis(g_name_mouse_axis_xpixel.C()); | mouse->AddAxis(g_name_mouse_axis_xpixel.C()); | ||||
mouse->AddAxis(g_name_mouse_axis_ypixel.C()); | mouse->AddAxis(g_name_mouse_axis_ypixel.C()); | ||||
mouse->AddAxis(g_name_mouse_axis_scroll.C()); | |||||
mouse->AddAxis(g_name_mouse_axis_scroll.C(), .0000001f); | |||||
mouse->AddCursor(g_name_mouse_cursor.C()); | mouse->AddCursor(g_name_mouse_cursor.C()); | ||||
@@ -98,6 +98,8 @@ public: | |||||
/** Gets the latest contents of text input. */ | /** Gets the latest contents of text input. */ | ||||
String GetText(); | String GetText(); | ||||
bool IsTextInputActive(); | |||||
void SetTextInputActive(bool status); | |||||
/** Gets the current value of the given axis. Devices should try to | /** Gets the current value of the given axis. Devices should try to | ||||
* clamp this value between -1 and 1, though it is not guaranteed. */ | * clamp this value between -1 and 1, though it is not guaranteed. */ | ||||
@@ -199,6 +201,7 @@ protected: | |||||
/** Text input state */ | /** Text input state */ | ||||
String m_text; | String m_text; | ||||
bool m_input_active; | |||||
/** Axis states (value and sensitivity) */ | /** Axis states (value and sensitivity) */ | ||||
array<float, float> m_axis; | array<float, float> m_axis; | ||||
@@ -208,7 +211,9 @@ protected: | |||||
static bool m_capturemouse; | static bool m_capturemouse; | ||||
InputDevice(String const &name) : m_name(name) | |||||
InputDevice(String const &name) | |||||
: m_name(name), | |||||
m_input_active(false) | |||||
{ | { | ||||
devices.push_unique(this); | devices.push_unique(this); | ||||
} | } | ||||
@@ -148,6 +148,7 @@ | |||||
<ClCompile Include="image\noise.cpp" /> | <ClCompile Include="image\noise.cpp" /> | ||||
<ClCompile Include="image\pixel.cpp" /> | <ClCompile Include="image\pixel.cpp" /> | ||||
<ClCompile Include="image\resample.cpp" /> | <ClCompile Include="image\resample.cpp" /> | ||||
<ClCompile Include="image\resource.cpp" /> | |||||
<ClCompile Include="input\controller.cpp" /> | <ClCompile Include="input\controller.cpp" /> | ||||
<ClCompile Include="input\input.cpp" /> | <ClCompile Include="input\input.cpp" /> | ||||
<ClCompile Include="light.cpp" /> | <ClCompile Include="light.cpp" /> | ||||
@@ -238,6 +239,7 @@ | |||||
<ClInclude Include="forge.h" /> | <ClInclude Include="forge.h" /> | ||||
<ClInclude Include="gradient.h" /> | <ClInclude Include="gradient.h" /> | ||||
<ClInclude Include="image\image-private.h" /> | <ClInclude Include="image\image-private.h" /> | ||||
<ClInclude Include="image\resource-private.h" /> | |||||
<ClInclude Include="input\controller.h" /> | <ClInclude Include="input\controller.h" /> | ||||
<ClInclude Include="input\input.h" /> | <ClInclude Include="input\input.h" /> | ||||
<ClInclude Include="input\input_internal.h" /> | <ClInclude Include="input\input_internal.h" /> | ||||
@@ -285,6 +287,7 @@ | |||||
<ClInclude Include="lol\image\image.h" /> | <ClInclude Include="lol\image\image.h" /> | ||||
<ClInclude Include="lol\image\movie.h" /> | <ClInclude Include="lol\image\movie.h" /> | ||||
<ClInclude Include="lol\image\pixel.h" /> | <ClInclude Include="lol\image\pixel.h" /> | ||||
<ClInclude Include="lol\image\resource.h" /> | |||||
<ClInclude Include="lol\math\all.h" /> | <ClInclude Include="lol\math\all.h" /> | ||||
<ClInclude Include="lol\math\arraynd.h" /> | <ClInclude Include="lol\math\arraynd.h" /> | ||||
<ClInclude Include="lol\math\bigint.h" /> | <ClInclude Include="lol\math\bigint.h" /> | ||||
@@ -397,4 +400,4 @@ | |||||
<ImportGroup Label="ExtensionTargets"> | <ImportGroup Label="ExtensionTargets"> | ||||
<Import Project="$(LolDir)\build\msbuild\lolfx.targets" /> | <Import Project="$(LolDir)\build\msbuild\lolfx.targets" /> | ||||
</ImportGroup> | </ImportGroup> | ||||
</Project> | |||||
</Project> |
@@ -22,96 +22,157 @@ namespace lol | |||||
namespace Debug | namespace Debug | ||||
{ | { | ||||
class DrawContext | |||||
{ | |||||
public: | |||||
class Data | |||||
{ | |||||
public: | |||||
vec4 m_color = vec4(1.f); | |||||
float m_duration = 0.0f; | |||||
int m_mask = 0; | |||||
float m_segment_size = 8; | |||||
//Resets draw infos | |||||
void DrawSetupReset(); | |||||
//Sets draw infos | |||||
void DrawSetupTime(float new_time); | |||||
void DrawSetupMask(int new_mask); | |||||
void DrawSetupSegment(float segment_size); | |||||
void DrawSetupColor(vec4 color); | |||||
void DrawSetup(float new_time, int new_mask, float segment_size, vec4 color); | |||||
//Screen to world conversion | |||||
vec3 WorldToScreen(vec3 pos); | |||||
vec3 WorldToScreen(vec3 pos, mat4 view_proj); | |||||
vec3 WorldToScreen(vec4 pos); | |||||
vec3 WorldToScreen(vec4 pos, mat4 view_proj); | |||||
vec3 ScreenToWorld(vec2 pos, float z=-1.f); | |||||
vec3 ScreenToWorld(vec3 pos); | |||||
vec3 ScreenToWorld(vec2 pos, mat4 inv_view_proj, float z=-1.f); | |||||
vec3 ScreenToWorld(vec3 pos, mat4 inv_view_proj); | |||||
vec3 ScreenToWorld(vec3 pos, mat4 view, mat4 proj); | |||||
//Draw stuff in World | |||||
//-- LINE | |||||
void DrawLine(vec3 a, vec3 b); | |||||
void DrawLine(vec2 a, vec3 b, float az=-1.f); | |||||
void DrawLine(vec2 a, vec2 b, float az=-1.f, float bz=-1.f); | |||||
void DrawLine(vec3 a, vec3 b, vec4 color); | |||||
void DrawLine(vec2 a, vec3 b, vec4 color, float az=-1.f); | |||||
void DrawLine(vec2 a, vec2 b, vec4 color, float az=-1.f, float bz=-1.f); | |||||
//-- GIZMO | |||||
void DrawGizmo(vec3 pos, vec3 x, vec3 y, vec3 z, float size); | |||||
void DrawGizmo(vec2 pos, vec3 x, vec3 y, vec3 z, float size, float posz = -1.f); | |||||
//-- GRID | |||||
void DrawGrid(vec3 pos, vec3 x, vec3 y, vec3 z, float size, bool draw_3d=false); | |||||
//-- ARROW | |||||
void DrawArrow(vec3 a, vec3 b, vec2 s); | |||||
void DrawArrow(vec2 a, vec3 b, vec2 s, float az=-1.f); | |||||
void DrawArrow(vec2 a, vec2 b, vec2 s, float az=-1.f, float bz=-1.f); | |||||
void DrawArrow(vec3 a, vec3 b, vec3 s); | |||||
void DrawArrow(vec2 a, vec3 b, vec3 s, float az=-1.f); | |||||
void DrawArrow(vec2 a, vec2 b, vec3 s, float az=-1.f, float bz=-1.f); | |||||
void DrawArrow(vec3 a, vec3 b, vec3 s, vec4 color); | |||||
void DrawArrow(vec2 a, vec3 b, vec3 s, vec4 color, float az=-1.f); | |||||
void DrawArrow(vec2 a, vec2 b, vec3 s, vec4 color, float az=-1.f, float bz=-1.f); | |||||
//-- BOX | |||||
void DrawBox(box3 a); | |||||
void DrawBox(box2 a); | |||||
void DrawBox(box3 a, vec4 color); | |||||
void DrawBox(box2 a, vec4 color); | |||||
void DrawBox(vec3 a, vec3 b); | |||||
void DrawBox(vec2 a, vec2 b); | |||||
void DrawBox(vec2 a, float s); | |||||
void DrawBox(vec3 a, vec3 b, vec4 color); | |||||
void DrawBox(vec2 a, vec2 b, vec4 color); | |||||
void DrawBox(vec2 a, float s, vec4 color); | |||||
void DrawBox(box3 a, mat4 transform); | |||||
void DrawBox(box2 a, mat2 transform); | |||||
void DrawBox(box3 a, mat4 transform, vec4 color); | |||||
void DrawBox(box2 a, mat2 transform, vec4 color); | |||||
void DrawBox(vec3 a, vec3 b, mat4 transform); | |||||
void DrawBox(vec2 a, vec2 b, mat2 transform); | |||||
void DrawBox(vec2 a, float s, mat2 transform); | |||||
void DrawBox(vec3 a, vec3 b, mat4 transform, vec4 color); | |||||
void DrawBox(vec2 a, vec2 b, mat2 transform, vec4 color); | |||||
void DrawBox(vec2 a, float s, mat2 transform, vec4 color); | |||||
//-- CIRCLE | |||||
void DrawCircle(vec2 a, float s); | |||||
void DrawCircle(vec3 a, vec3 n); | |||||
void DrawCircle(vec2 a, vec2 s); | |||||
void DrawCircle(vec3 a, vec3 n, vec4 color); | |||||
void DrawCircle(vec2 a, vec2 s, vec4 color); | |||||
void DrawCircle(vec3 a, vec3 x, vec3 y); | |||||
void DrawCircle(vec2 a, vec2 x, vec2 y); | |||||
void DrawCircle(vec3 a, vec3 x, vec3 y, vec4 color); | |||||
void DrawCircle(vec2 a, vec2 x, vec2 y, vec4 color); | |||||
//-- SPHERE | |||||
void DrawSphere(vec3 a, float s); | |||||
void DrawSphere(vec3 a, float s, vec4 color); | |||||
void DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z); | |||||
void DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z, vec4 color); | |||||
//-- CAPSULE | |||||
void DrawCapsule(vec3 a, float s, vec3 h); | |||||
void DrawCapsule(vec3 a, float s, vec3 h, vec4 color); | |||||
void DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h); | |||||
void DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h, vec4 color); | |||||
//-- VIEW PROJ | |||||
void DrawViewProj(mat4 view_proj); | |||||
void DrawViewProj(mat4 view_proj, vec4 color); | |||||
void DrawViewProj(mat4 view, mat4 proj); | |||||
void DrawViewProj(mat4 view, mat4 proj, vec4 color); | |||||
Data() {} | |||||
Data(vec4 color, float duration = -1.f, int mask = 0xFFFFFFFF, float segment_size = 1.f) | |||||
{ | |||||
m_color = color; | |||||
m_duration = duration; | |||||
m_mask = mask; | |||||
m_segment_size = segment_size; | |||||
} | |||||
inline Data& operator=(vec4 const& color) { m_color = color; return *this; } | |||||
}; | |||||
private: | |||||
static Data m_global; | |||||
Data m_previous; | |||||
Data m_current; | |||||
DrawContext(vec4 color, float duration, int mask, float segment_size) | |||||
{ | |||||
//Store old datas | |||||
m_previous.m_color = m_global.m_color; | |||||
m_previous.m_duration = m_global.m_duration; | |||||
m_previous.m_mask = m_global.m_mask; | |||||
m_previous.m_segment_size = m_global.m_segment_size; | |||||
//Create new one | |||||
SetColor(color); | |||||
SetDuration(duration); | |||||
SetMask(mask); | |||||
SetSegmentSize(segment_size); | |||||
} | |||||
public: | |||||
~DrawContext() | |||||
{ | |||||
m_global.m_color = m_previous.m_color; | |||||
m_global.m_duration = m_previous.m_duration; | |||||
m_global.m_mask = m_previous.m_mask; | |||||
m_global.m_segment_size = m_previous.m_segment_size; | |||||
} | |||||
static DrawContext New(vec4 color, float duration = -1.f, int mask = 0xFFFFFFFF, float segment_size = 1.f) | |||||
{ | |||||
return DrawContext(color, duration, mask, segment_size); | |||||
} | |||||
static DrawContext New(DrawContext& dc) | |||||
{ | |||||
return DrawContext(dc.m_current.m_color, dc.m_current.m_duration, dc.m_current.m_mask, dc.m_current.m_segment_size); | |||||
} | |||||
static Data GetGlobalData() { return m_global; } | |||||
//Setup methods | |||||
void SetColor(vec4 color) { m_global.m_color = m_current.m_color = color; } | |||||
void SetDuration(float duration) { m_global.m_duration = m_current.m_duration = duration; } | |||||
void SetMask(int mask) { m_global.m_mask = m_current.m_mask = mask; } | |||||
void SetSegmentSize(float segment_size) { m_global.m_segment_size = m_current.m_segment_size = segment_size; } | |||||
}; | |||||
//Screen to world conversion | |||||
vec3 WorldToScreen(vec3 pos); | |||||
vec3 WorldToScreen(vec3 pos, mat4 view_proj); | |||||
vec3 WorldToScreen(vec4 pos); | |||||
vec3 WorldToScreen(vec4 pos, mat4 view_proj); | |||||
vec3 ScreenToWorld(vec2 pos, float z=-1.f); | |||||
vec3 ScreenToWorld(vec3 pos); | |||||
vec3 ScreenToWorld(vec2 pos, mat4 inv_view_proj, float z=-1.f); | |||||
vec3 ScreenToWorld(vec3 pos, mat4 inv_view_proj); | |||||
vec3 ScreenToWorld(vec3 pos, mat4 view, mat4 proj); | |||||
//Draw stuff in World | |||||
//Draw stuff in World | |||||
//-- LINE | |||||
void DrawLine(vec3 a, vec3 b, DrawContext::Data data); | |||||
void DrawLine(vec2 a, vec3 b, DrawContext::Data data, float az = -1.f); | |||||
void DrawLine(vec2 a, vec2 b, DrawContext::Data data, float az = -1.f, float bz = -1.f); | |||||
void DrawLine(vec3 a, vec3 b); | |||||
void DrawLine(vec2 a, vec3 b, float az = -1.f); | |||||
void DrawLine(vec2 a, vec2 b, float az = -1.f, float bz = -1.f); | |||||
//-- GIZMO | |||||
void DrawGizmo(vec3 pos, vec3 x, vec3 y, vec3 z, float size); | |||||
void DrawGizmo(vec2 pos, vec3 x, vec3 y, vec3 z, float size, float posz = -1.f); | |||||
//-- GRID | |||||
void DrawGrid(vec3 pos, vec3 x, vec3 y, vec3 z, float size, bool draw_3d=false); | |||||
//-- ARROW | |||||
void DrawArrow(vec3 a, vec3 b, vec2 s); | |||||
void DrawArrow(vec2 a, vec3 b, vec2 s, float az=-1.f); | |||||
void DrawArrow(vec2 a, vec2 b, vec2 s, float az=-1.f, float bz=-1.f); | |||||
void DrawArrow(vec3 a, vec3 b, vec3 s); | |||||
void DrawArrow(vec2 a, vec3 b, vec3 s, float az=-1.f); | |||||
void DrawArrow(vec2 a, vec2 b, vec3 s, float az=-1.f, float bz=-1.f); | |||||
void DrawArrow(vec3 a, vec3 b, vec3 s, DrawContext::Data data); | |||||
void DrawArrow(vec2 a, vec3 b, vec3 s, DrawContext::Data data, float az=-1.f); | |||||
void DrawArrow(vec2 a, vec2 b, vec3 s, DrawContext::Data data, float az=-1.f, float bz=-1.f); | |||||
//-- BOX | |||||
void DrawBox(box3 a); | |||||
void DrawBox(box2 a); | |||||
void DrawBox(box3 a, DrawContext::Data data); | |||||
void DrawBox(box2 a, DrawContext::Data data); | |||||
void DrawBox(vec3 a, vec3 b); | |||||
void DrawBox(vec2 a, vec2 b); | |||||
void DrawBox(vec2 a, float s); | |||||
void DrawBox(vec3 a, vec3 b, DrawContext::Data data); | |||||
void DrawBox(vec2 a, vec2 b, DrawContext::Data data); | |||||
void DrawBox(vec2 a, float s, DrawContext::Data data); | |||||
void DrawBox(box3 a, mat4 transform); | |||||
void DrawBox(box2 a, mat2 transform); | |||||
void DrawBox(box3 a, mat4 transform, DrawContext::Data data); | |||||
void DrawBox(box2 a, mat2 transform, DrawContext::Data data); | |||||
void DrawBox(vec3 a, vec3 b, mat4 transform); | |||||
void DrawBox(vec2 a, vec2 b, mat2 transform); | |||||
void DrawBox(vec2 a, float s, mat2 transform); | |||||
void DrawBox(vec3 a, vec3 b, mat4 transform, DrawContext::Data data); | |||||
void DrawBox(vec2 a, vec2 b, mat2 transform, DrawContext::Data data); | |||||
void DrawBox(vec2 a, float s, mat2 transform, DrawContext::Data data); | |||||
//-- CIRCLE | |||||
void DrawCircle(vec2 a, float s); | |||||
void DrawCircle(vec3 a, vec3 n); | |||||
void DrawCircle(vec2 a, vec2 s); | |||||
void DrawCircle(vec3 a, vec3 n, DrawContext::Data data); | |||||
void DrawCircle(vec2 a, vec2 s, DrawContext::Data data); | |||||
void DrawCircle(vec3 a, vec3 x, vec3 y); | |||||
void DrawCircle(vec2 a, vec2 x, vec2 y); | |||||
void DrawCircle(vec3 a, vec3 x, vec3 y, DrawContext::Data data); | |||||
void DrawCircle(vec2 a, vec2 x, vec2 y, DrawContext::Data data); | |||||
//-- SPHERE | |||||
void DrawSphere(vec3 a, float s); | |||||
void DrawSphere(vec3 a, float s, DrawContext::Data data); | |||||
void DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z); | |||||
void DrawSphere(vec3 a, vec3 x, vec3 y, vec3 z, DrawContext::Data data); | |||||
//-- CAPSULE | |||||
void DrawCapsule(vec3 a, float s, vec3 h); | |||||
void DrawCapsule(vec3 a, float s, vec3 h, DrawContext::Data data); | |||||
void DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h); | |||||
void DrawCapsule(vec3 a, vec3 x, vec3 y, vec3 z, vec3 h, DrawContext::Data data); | |||||
//-- VIEW PROJ | |||||
void DrawViewProj(mat4 view_proj); | |||||
void DrawViewProj(mat4 view_proj, DrawContext::Data data); | |||||
void DrawViewProj(mat4 view, mat4 proj); | |||||
void DrawViewProj(mat4 view, mat4 proj, DrawContext::Data data); | |||||
} /* namespace Debug */ | } /* namespace Debug */ | ||||
@@ -36,4 +36,5 @@ | |||||
#include <lol/public.h> | #include <lol/public.h> | ||||
#include <lol/extras.h> | #include <lol/extras.h> | ||||
#include <lol/legacy.h> | |||||
@@ -31,4 +31,5 @@ | |||||
#include <lol/public.h> | #include <lol/public.h> | ||||
#include <lol/extras.h> | #include <lol/extras.h> | ||||
#include <lol/legacy.h> | |||||
@@ -103,7 +103,7 @@ public: | |||||
TextureUniform GetTextureUniform() const; | TextureUniform GetTextureUniform() const; | ||||
ivec2 GetSize() const; | ivec2 GetSize() const; | ||||
class Image GetImage() const; | |||||
class image GetImage() const; | |||||
void Bind(); | void Bind(); | ||||
void Unbind(); | void Unbind(); | ||||
@@ -36,6 +36,8 @@ public: | |||||
void SetDepthMask(DepthMask mask); | void SetDepthMask(DepthMask mask); | ||||
void SetCullMode(CullMode mode); | void SetCullMode(CullMode mode); | ||||
void SetPolygonMode(PolygonMode mode); | void SetPolygonMode(PolygonMode mode); | ||||
void SetScissorMode(ScissorMode mode); | |||||
void SetScissorRect(vec4 rect); | |||||
ibox2 GetViewport(); | ibox2 GetViewport(); | ||||
vec4 GetClearColor(); | vec4 GetClearColor(); | ||||
@@ -50,6 +52,8 @@ public: | |||||
DepthMask GetDepthMask(); | DepthMask GetDepthMask(); | ||||
CullMode GetCullMode(); | CullMode GetCullMode(); | ||||
PolygonMode GetPolygonMode(); | PolygonMode GetPolygonMode(); | ||||
ScissorMode GetScissorMode(); | |||||
vec4 GetScissorRect(); | |||||
private: | private: | ||||
RenderContextData *m_data; | RenderContextData *m_data; | ||||
@@ -123,6 +123,13 @@ enum class AlphaFunc : uint8_t | |||||
Always, | Always, | ||||
}; | }; | ||||
/* A safe enum to indicate the depth mask. */ | |||||
enum class ScissorMode : uint8_t | |||||
{ | |||||
Disabled, | |||||
Enabled, | |||||
}; | |||||
class Renderer | class Renderer | ||||
{ | { | ||||
private: | private: | ||||
@@ -176,6 +183,11 @@ public: | |||||
void SetPolygonMode(PolygonMode mode); | void SetPolygonMode(PolygonMode mode); | ||||
PolygonMode GetPolygonMode() const; | PolygonMode GetPolygonMode() const; | ||||
void SetScissorMode(ScissorMode mode); | |||||
void SetScissorRect(vec4 rect); | |||||
ScissorMode GetScissorMode() const; | |||||
vec4 GetScissorRect() const; | |||||
private: | private: | ||||
RendererData *m_data; | RendererData *m_data; | ||||
}; | }; | ||||
@@ -15,5 +15,6 @@ | |||||
#include <lol/image/pixel.h> | #include <lol/image/pixel.h> | ||||
#include <lol/image/color.h> | #include <lol/image/color.h> | ||||
#include <lol/image/image.h> | #include <lol/image/image.h> | ||||
#include <lol/image/resource.h> | |||||
#include <lol/image/movie.h> | #include <lol/image/movie.h> | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -13,7 +13,7 @@ | |||||
#pragma once | #pragma once | ||||
// | // | ||||
// The Image class | |||||
// The image class | |||||
// --------------- | // --------------- | ||||
// | // | ||||
@@ -58,117 +58,120 @@ enum class EdiffAlgorithm : uint8_t | |||||
Lite, | Lite, | ||||
}; | }; | ||||
//Image ----------------------------------------------------------------------- | |||||
class Image | |||||
// image ----------------------------------------------------------------------- | |||||
class image | |||||
{ | { | ||||
public: | public: | ||||
Image(); | |||||
Image(ivec2 size); | |||||
image(); | |||||
image(ivec2 size); | |||||
/* XXX: use of this ctor should be discouraged, as it will not | /* XXX: use of this ctor should be discouraged, as it will not | ||||
* return information about a possible error. */ | * return information about a possible error. */ | ||||
Image(char const *path); | |||||
image(char const *path); | |||||
/* Rule of three */ | /* Rule of three */ | ||||
Image(Image const &other); | |||||
Image & operator =(Image other); | |||||
~Image(); | |||||
image(image const &other); | |||||
image & operator =(image other); | |||||
~image(); | |||||
void DummyFill(); | void DummyFill(); | ||||
void Copy(uint8_t* pixels, ivec2 const& size, PixelFormat fmt); | void Copy(uint8_t* pixels, ivec2 const& size, PixelFormat fmt); | ||||
void Copy(Image const &other); | |||||
bool Load(char const *path); | |||||
bool Save(char const *path); | |||||
void Copy(image const &other); | |||||
bool load(char const *path); | |||||
bool save(char const *path); | |||||
/* Low level access */ | /* Low level access */ | ||||
ivec2 GetSize() const; | |||||
void SetSize(ivec2); | |||||
ivec2 size() const; | |||||
void resize(ivec2); | |||||
PixelFormat GetFormat() const; | |||||
void SetFormat(PixelFormat fmt); | |||||
PixelFormat format() const; | |||||
void set_format(PixelFormat fmt); | |||||
WrapMode GetWrapX() const; | WrapMode GetWrapX() const; | ||||
WrapMode GetWrapY() const; | WrapMode GetWrapY() const; | ||||
void SetWrap(WrapMode wrap_x, WrapMode wrap_y); | void SetWrap(WrapMode wrap_x, WrapMode wrap_y); | ||||
/* Lock continuous arrays of pixels for writing */ | /* Lock continuous arrays of pixels for writing */ | ||||
template<PixelFormat T> typename PixelType<T>::type *Lock(); | |||||
void *Lock(); | |||||
void Unlock(void const *pixels); | |||||
template<PixelFormat T> typename PixelType<T>::type *lock(); | |||||
void *lock(); | |||||
void unlock(void const *pixels); | |||||
/* Lock 2D arrays of pixels for writing */ | /* Lock 2D arrays of pixels for writing */ | ||||
template<PixelFormat T> | template<PixelFormat T> | ||||
inline array2d<typename PixelType<T>::type> &Lock2D() | |||||
inline array2d<typename PixelType<T>::type> &lock2d() | |||||
{ | { | ||||
/* Hack: this indirection is needed because of a Visual Studio ICE */ | /* Hack: this indirection is needed because of a Visual Studio ICE */ | ||||
return *(array2d<typename PixelType<T>::type> *)Lock2DHelper(T); | |||||
return *(array2d<typename PixelType<T>::type> *)lock2d_helper(T); | |||||
} | } | ||||
template<typename T> | template<typename T> | ||||
void Unlock2D(array2d<T> const &); | |||||
/* XXX: this does not belong here */ | |||||
bool RetrieveTiles(array<ivec2, ivec2>& tiles) const; | |||||
void unlock2d(array2d<T> const &); | |||||
/* Image processing kernels */ | /* Image processing kernels */ | ||||
static array2d<float> BayerKernel(ivec2 size); | |||||
static array2d<float> HalftoneKernel(ivec2 size); | |||||
static array2d<float> BlueNoiseKernel(ivec2 size, | |||||
ivec2 gsize = ivec2(7, 7)); | |||||
static array2d<float> EdiffKernel(EdiffAlgorithm algorithm); | |||||
static array2d<float> NormalizeKernel(array2d<float> const &kernel); | |||||
static array2d<float> GaussianKernel(vec2 radius, | |||||
float angle = 0.f, | |||||
vec2 delta = vec2(0.f, 0.f)); | |||||
struct kernel | |||||
{ | |||||
kernel() = delete; | |||||
static array2d<float> normalize(array2d<float> const &kernel); | |||||
static array2d<float> bayer(ivec2 size); | |||||
static array2d<float> halftone(ivec2 size); | |||||
static array2d<float> blue_noise(ivec2 size, | |||||
ivec2 gsize = ivec2(7, 7)); | |||||
static array2d<float> ediff(EdiffAlgorithm algorithm); | |||||
static array2d<float> gaussian(vec2 radius, | |||||
float angle = 0.f, | |||||
vec2 delta = vec2(0.f, 0.f)); | |||||
}; | |||||
/* Rendering */ | /* Rendering */ | ||||
bool RenderRandom(ivec2 size); | bool RenderRandom(ivec2 size); | ||||
/* Resize and crop */ | /* Resize and crop */ | ||||
Image Resize(ivec2 size, ResampleAlgorithm algorithm); | |||||
Image Crop(ibox2 box) const; | |||||
image Resize(ivec2 size, ResampleAlgorithm algorithm); | |||||
image Crop(ibox2 box) const; | |||||
/* Image processing */ | /* Image processing */ | ||||
Image AutoContrast() const; | |||||
Image Brightness(float val) const; | |||||
Image Contrast(float val) const; | |||||
Image Convolution(array2d<float> const &kernel); | |||||
Image Dilate(); | |||||
Image Erode(); | |||||
Image Invert() const; | |||||
Image Median(ivec2 radii) const; | |||||
Image Median(array2d<float> const &kernel) const; | |||||
Image Sharpen(array2d<float> const &kernel); | |||||
Image Threshold(float val) const; | |||||
Image Threshold(vec3 val) const; | |||||
Image RGBToYUV() const; | |||||
Image YUVToRGB() const; | |||||
image AutoContrast() const; | |||||
image Brightness(float val) const; | |||||
image Contrast(float val) const; | |||||
image Convolution(array2d<float> const &kernel); | |||||
image Dilate(); | |||||
image Erode(); | |||||
image Invert() const; | |||||
image Median(ivec2 radii) const; | |||||
image Median(array2d<float> const &kernel) const; | |||||
image Sharpen(array2d<float> const &kernel); | |||||
image Threshold(float val) const; | |||||
image Threshold(vec3 val) const; | |||||
image RGBToYUV() const; | |||||
image YUVToRGB() const; | |||||
/* Dithering */ | /* Dithering */ | ||||
Image DitherRandom() const; | |||||
Image DitherEdiff(array2d<float> const &kernel, | |||||
ScanMode scan = ScanMode::Raster) const; | |||||
Image DitherOstromoukhov(ScanMode scan = ScanMode::Raster) const; | |||||
Image DitherOrdered(array2d<float> const &kernel) const; | |||||
Image DitherHalftone(float radius, float angle) const; | |||||
Image DitherDbs() const; | |||||
image dither_random() const; | |||||
image dither_ediff(array2d<float> const &kernel, | |||||
ScanMode scan = ScanMode::Raster) const; | |||||
image dither_ostromoukhov(ScanMode scan = ScanMode::Raster) const; | |||||
image dither_ordered(array2d<float> const &kernel) const; | |||||
image dither_halftone(float radius, float angle) const; | |||||
image dither_dbs() const; | |||||
/* Combine images */ | /* Combine images */ | ||||
static Image Merge(Image &src1, Image &src2, float alpha); | |||||
static Image Mean(Image &src1, Image &src2); | |||||
static Image Min(Image &src1, Image &src2); | |||||
static Image Max(Image &src1, Image &src2); | |||||
static Image Overlay(Image &src1, Image &src2); | |||||
static Image Screen(Image &src1, Image &src2); | |||||
static Image Multiply(Image &src1, Image &src2); | |||||
static Image Divide(Image &src1, Image &src2); | |||||
static Image Add(Image &src1, Image &src2); | |||||
static Image Sub(Image &src1, Image &src2); | |||||
static Image Difference(Image &src1, Image &src2); | |||||
static image Merge(image &src1, image &src2, float alpha); | |||||
static image Mean(image &src1, image &src2); | |||||
static image Min(image &src1, image &src2); | |||||
static image Max(image &src1, image &src2); | |||||
static image Overlay(image &src1, image &src2); | |||||
static image Screen(image &src1, image &src2); | |||||
static image Multiply(image &src1, image &src2); | |||||
static image Divide(image &src1, image &src2); | |||||
static image Add(image &src1, image &src2); | |||||
static image Sub(image &src1, image &src2); | |||||
static image Difference(image &src1, image &src2); | |||||
private: | private: | ||||
void *Lock2DHelper(PixelFormat T); | |||||
void *lock2d_helper(PixelFormat T); | |||||
class ImageData *m_data; | |||||
class image_data *m_data; | |||||
}; | }; | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -34,7 +34,7 @@ public: | |||||
#endif | #endif | ||||
~Movie(); | ~Movie(); | ||||
void Feed(Image const &image); | |||||
void Feed(image const &image); | |||||
private: | private: | ||||
class MovieData *m_data; | class MovieData *m_data; | ||||
@@ -0,0 +1,74 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright © 2016—2017 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2016—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | |||||
#pragma once | |||||
// | |||||
// The Resource class | |||||
// --------------- | |||||
// | |||||
#include <lol/math/arraynd.h> | |||||
#include <lol/math/vector.h> | |||||
#include <lol/math/geometry.h> | |||||
#include <lol/image/pixel.h> | |||||
namespace lol | |||||
{ | |||||
//ResourceCodecData ----------------------------------------------------------- | |||||
class ResourceCodecData | |||||
{ | |||||
public: | |||||
ResourceCodecData() { } | |||||
virtual ~ResourceCodecData() { } | |||||
}; | |||||
//ResourceImageData ----------------------------------------------------------- | |||||
class ResourceImageData : public ResourceCodecData | |||||
{ | |||||
public: | |||||
ResourceImageData(image* img) | |||||
{ | |||||
m_image = img; | |||||
} | |||||
virtual ~ResourceImageData() | |||||
{ | |||||
if (m_image) | |||||
delete m_image; | |||||
} | |||||
image* m_image = nullptr; | |||||
}; | |||||
//ResourceImageData ----------------------------------------------------------- | |||||
class ResourceTilesetData : public ResourceImageData | |||||
{ | |||||
public: | |||||
ResourceTilesetData(image* img) | |||||
: ResourceImageData(img) | |||||
{ } | |||||
array<ivec2, ivec2> m_tiles; | |||||
}; | |||||
//ResourceLoader -------------------------------------------------------------- | |||||
class ResourceLoader | |||||
{ | |||||
public: | |||||
static ResourceCodecData* Load(char const *path); | |||||
static bool Save(char const *path, ResourceCodecData* data); | |||||
}; | |||||
} /* namespace lol */ | |||||
@@ -0,0 +1,26 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | |||||
#pragma once | |||||
// | |||||
// Legacy types that will disappear one day | |||||
// ---------------------------------------- | |||||
// | |||||
namespace lol | |||||
{ | |||||
typedef image Image; | |||||
} /* namespace lol */ | |||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#pragma once | #pragma once | ||||
@@ -81,7 +83,7 @@ public: | |||||
int WriteString(const String &buf); | int WriteString(const String &buf); | ||||
long int GetPosFromStart(); | long int GetPosFromStart(); | ||||
void SetPosFromStart(long int pos); | void SetPosFromStart(long int pos); | ||||
long int GetSize(); | |||||
long int size(); | |||||
long int GetModificationTime(); | long int GetModificationTime(); | ||||
private: | private: | ||||
@@ -124,16 +124,16 @@ public: | |||||
{ } | { } | ||||
//Returns a dummy image, and start a job to load the image on a thread | //Returns a dummy image, and start a job to load the image on a thread | ||||
Image* Load(const lol::String& path); | |||||
bool CheckStatus(Image* image); | |||||
image* Load(const lol::String& path); | |||||
bool CheckStatus(image* img); | |||||
protected: | protected: | ||||
virtual void TreatResult(ThreadJob* result); | virtual void TreatResult(ThreadJob* result); | ||||
private: | private: | ||||
Image m_dummy_image; | |||||
map<String, Image*> m_images; | |||||
array<Image*> m_loaded_images; | |||||
image m_dummy_image; | |||||
map<String, image*> m_images; | |||||
array<image*> m_loaded_images; | |||||
}; | }; | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -18,6 +18,72 @@ | |||||
using namespace lol; | using namespace lol; | ||||
//Imgui extension --------------------------------------------------------------------------------- | |||||
namespace ImGui | |||||
{ | |||||
IMGUI_API void SetNextWindowDockingAndSize(const ImVec2& size, ImGuiSetDock dock, const ImVec2& padding, ImGuiSetCond cond) | |||||
{ | |||||
SetNextWindowDockingAndSize(size, dock, ImVec4(vec2(padding).xyxy), cond); | |||||
} | |||||
IMGUI_API void SetNextWindowDockingAndSize(const ImVec2& size, ImGuiSetDock dock, const ImVec4& padding, ImGuiSetCond cond) | |||||
{ | |||||
vec4 pdg = padding; | |||||
vec2 vsz = vec2(Video::GetSize()); | |||||
vec2 ctr = pdg.xy + (((vsz - pdg.zw) - pdg.xy) * .5f); | |||||
vec2 pos = vec2(); | |||||
switch (dock) | |||||
{ | |||||
case ImGuiSetDock_Center: pos = vec2(ctr.x - (size.x * .5f), ctr.y - (size.y * .5f)); break; | |||||
case ImGuiSetDock_Top: pos = vec2(ctr.x - (size.x * .5f), pdg.y); break; | |||||
case ImGuiSetDock_TopRight: pos = vec2(vsz.x - (size.x + pdg.z), pdg.y); break; | |||||
case ImGuiSetDock_Right: pos = vec2(vsz.x - (size.x + pdg.z), ctr.y - (size.y * .5f)); break; | |||||
case ImGuiSetDock_BottomRight: pos = vec2(vsz.x - (size.x + pdg.z), vsz.y - (size.y + pdg.w)); break; | |||||
case ImGuiSetDock_Bottom: pos = vec2(ctr.x - (size.x * .5f), vsz.y - (size.y + pdg.w)); break; | |||||
case ImGuiSetDock_BottomLeft: pos = vec2(pdg.x, vsz.y - (size.y + pdg.w)); break; | |||||
case ImGuiSetDock_Left: pos = vec2(pdg.x, ctr.y - (size.y * .5f)); break; | |||||
case ImGuiSetDock_TopLeft: pos = vec2(pdg.x, pdg.y); break; | |||||
} | |||||
ImGui::SetNextWindowPos(pos, cond); | |||||
ImGui::SetNextWindowSize(size, cond); | |||||
} | |||||
IMGUI_API void SetNextWindowDocking(ImGuiSetDock dock, const ImVec2& padding, ImGuiSetCond cond) | |||||
{ | |||||
SetNextWindowDocking(dock, ImVec4(vec2(padding).xyxy), cond); | |||||
} | |||||
IMGUI_API void SetNextWindowDocking(ImGuiSetDock dock, const ImVec4& padding, ImGuiSetCond cond) | |||||
{ | |||||
vec2 vsz = vec2(Video::GetSize()); | |||||
vec2 size = vec2(); | |||||
vec2 pos = vec2(); | |||||
vec4 pdg = padding; | |||||
switch (dock) | |||||
{ | |||||
case ImGuiSetDock_Center: size = vsz - vec2(pdg.x + pdg.z, pdg.y + pdg.w); break; | |||||
case ImGuiSetDock_Top: size = vec2(vsz.x - (pdg.x + pdg.z), vsz.y *.5f - pdg.y); break; | |||||
case ImGuiSetDock_TopRight: size = vec2(vsz.x *.5f - pdg.z, vsz.y *.5f - pdg.y); break; | |||||
case ImGuiSetDock_Right: size = vec2(vsz.x *.5f - pdg.z, vsz.y - (pdg.y + pdg.w)); break; | |||||
case ImGuiSetDock_BottomRight: size = vec2(vsz.x *.5f - pdg.z, vsz.y *.5f - pdg.w); break; | |||||
case ImGuiSetDock_Bottom: size = vec2(vsz.x - (pdg.x + pdg.z), vsz.y *.5f - pdg.w); break; | |||||
case ImGuiSetDock_BottomLeft: size = vec2(vsz.x *.5f - pdg.x, vsz.y *.5f - pdg.w); break; | |||||
case ImGuiSetDock_Left: size = vec2(vsz.x *.5f - pdg.x, vsz.y - (pdg.y + pdg.w)); break; | |||||
case ImGuiSetDock_TopLeft: size = vec2(vsz.x *.5f - pdg.x, vsz.y *.5f - pdg.y); break; | |||||
} | |||||
SetNextWindowDockingAndSize(size, dock, padding, cond); | |||||
} | |||||
IMGUI_API float GetMainMenuBarHeight() | |||||
{ | |||||
ImGuiContext& g = *GImGui; | |||||
return g.FontBaseSize + g.Style.FramePadding.y * 2.0f; | |||||
} | |||||
} | |||||
//LolImGui ---------------------------------------------------------------------------------------- | |||||
#define Line(s) ((s) + "\n") | #define Line(s) ((s) + "\n") | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -227,6 +293,8 @@ void LolImGui::TickGame(float seconds) | |||||
} | } | ||||
} | } | ||||
m_keyboard->SetTextInputActive(io.WantTextInput); | |||||
//Update text input | //Update text input | ||||
String text = m_keyboard->GetText(); | String text = m_keyboard->GetText(); | ||||
//text.case_change(io.KeyShift); | //text.case_change(io.KeyShift); | ||||
@@ -342,6 +410,7 @@ void LolImGui::RenderDrawListsMethod(ImDrawData* draw_data) | |||||
RenderContext rc; | RenderContext rc; | ||||
rc.SetCullMode(CullMode::Disabled); | rc.SetCullMode(CullMode::Disabled); | ||||
rc.SetDepthFunc(DepthFunc::Disabled); | rc.SetDepthFunc(DepthFunc::Disabled); | ||||
rc.SetScissorMode(ScissorMode::Enabled); | |||||
m_shader->Bind(); | m_shader->Bind(); | ||||
for (int n = 0; n < draw_data->CmdListsCount; n++) | for (int n = 0; n < draw_data->CmdListsCount; n++) | ||||
@@ -375,9 +444,14 @@ void LolImGui::RenderDrawListsMethod(ImDrawData* draw_data) | |||||
m_vdecl->SetStream(vbo, m_attribs[0], m_attribs[1], m_attribs[2]); | m_vdecl->SetStream(vbo, m_attribs[0], m_attribs[1], m_attribs[2]); | ||||
const ImDrawIdx* idx_buffer_offset = 0; | const ImDrawIdx* idx_buffer_offset = 0; | ||||
for (size_t cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) | |||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) | |||||
{ | { | ||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[(int)cmd_i]; | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[(int)cmd_i]; | ||||
TextureImage* image = (TextureImage*)pcmd->TextureId; | |||||
if (image) image->Bind(); | |||||
rc.SetScissorRect(vec4(pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w)); | |||||
#ifdef SHOW_IMGUI_DEBUG | #ifdef SHOW_IMGUI_DEBUG | ||||
//----------------------------------------------------------------- | //----------------------------------------------------------------- | ||||
//<Debug render> -------------------------------------------------- | //<Debug render> -------------------------------------------------- | ||||
@@ -419,11 +493,13 @@ void LolImGui::RenderDrawListsMethod(ImDrawData* draw_data) | |||||
//<\Debug render> ------------------------------------------------- | //<\Debug render> ------------------------------------------------- | ||||
//----------------------------------------------------------------- | //----------------------------------------------------------------- | ||||
#endif //SHOW_IMGUI_DEBUG | #endif //SHOW_IMGUI_DEBUG | ||||
Debug::DrawLine(vec2::zero, vec2::axis_x, Color::green); | |||||
//Debug::DrawLine(vec2::zero, vec2::axis_x /*, Color::green*/); | |||||
m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, pcmd->ElemCount, (const short*)idx_buffer_offset); | m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, pcmd->ElemCount, (const short*)idx_buffer_offset); | ||||
idx_buffer_offset += pcmd->ElemCount; | idx_buffer_offset += pcmd->ElemCount; | ||||
if (image) image->Unbind(); | |||||
} | } | ||||
m_vdecl->Unbind(); | m_vdecl->Unbind(); | ||||
@@ -12,12 +12,50 @@ | |||||
#pragma once | #pragma once | ||||
#define IM_VEC2_CLASS_EXTRA ImVec2(const lol::vec2 &v) { x = v.x; y = v.y; } \ | |||||
ImVec2(const lol::ivec2 &v) : ImVec2(lol::vec2(v)) { } \ | |||||
operator lol::vec2() const { return lol::vec2(x, y); } \ | |||||
operator lol::ivec2() const { return lol::ivec2(lol::vec2(x, y)); } | |||||
#define IM_VEC4_CLASS_EXTRA ImVec4(const lol::vec4 &v) { x = v.x; y = v.y; z = v.z; w = v.w; } \ | |||||
ImVec4(const lol::ivec4 &v) : ImVec4(lol::vec4(v)) { } \ | |||||
operator lol::vec4() const { return lol::vec4(x, y, z, w); } \ | |||||
operator lol::ivec4() const { return lol::ivec4(lol::vec4(x, y, z, w)); } | |||||
#include "imgui.h" | #include "imgui.h" | ||||
#undef IM_VEC2_CLASS_EXTRA | |||||
#undef IM_VEC4_CLASS_EXTRA | |||||
//Imgui extension --------------------------------------------------------------------------------- | |||||
typedef int ImGuiSetDock; // condition flags for Set*() // enum ImGuiSetCond_ | |||||
enum ImGuiSetDock_ | |||||
{ | |||||
ImGuiSetDock_Center, | |||||
ImGuiSetDock_Top, | |||||
ImGuiSetDock_TopRight, | |||||
ImGuiSetDock_Right, | |||||
ImGuiSetDock_BottomRight, | |||||
ImGuiSetDock_Bottom, | |||||
ImGuiSetDock_BottomLeft, | |||||
ImGuiSetDock_Left, | |||||
ImGuiSetDock_TopLeft, | |||||
}; | |||||
namespace ImGui | |||||
{ | |||||
IMGUI_API void SetNextWindowDockingAndSize(const ImVec2& size, ImGuiSetDock dock, const ImVec2& padding, ImGuiSetCond cond = 0); | |||||
IMGUI_API void SetNextWindowDockingAndSize(const ImVec2& size, ImGuiSetDock dock, const ImVec4& padding = ImVec4(0, 0, 0, 0), ImGuiSetCond cond = 0); | |||||
IMGUI_API void SetNextWindowDocking(ImGuiSetDock dock, const ImVec2& padding, ImGuiSetCond cond = 0); | |||||
IMGUI_API void SetNextWindowDocking(ImGuiSetDock dock, const ImVec4& padding = ImVec4(0, 0, 0, 0), ImGuiSetCond cond = 0); | |||||
IMGUI_API float GetMainMenuBarHeight(); | |||||
} | |||||
//LolImGui ---------------------------------------------------------------------------------------- | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
//LolImGui -------------------------------------------------------------------- | |||||
class LolImGui : public Entity | class LolImGui : public Entity | ||||
{ | { | ||||
typedef Entity super; | typedef Entity super; | ||||
@@ -40,8 +40,9 @@ class LuaBaseData | |||||
int status = luaL_dostring(l, s.C()); | int status = luaL_dostring(l, s.C()); | ||||
if (status == 1) | if (status == 1) | ||||
{ | { | ||||
LuaString error; error.Get(l, -1); | |||||
msg::error("Lua error %s\n", error().C()); | |||||
auto stack = LuaStack::Begin(l, -1); | |||||
auto error = stack.Get<String>(); | |||||
msg::error("Lua error %s\n", error.C()); | |||||
lua_pop(l, 1); | lua_pop(l, 1); | ||||
} | } | ||||
return status; | return status; | ||||
@@ -53,8 +54,8 @@ class LuaBaseData | |||||
if (lua_isnoneornil(l, 1)) | if (lua_isnoneornil(l, 1)) | ||||
return LUA_ERRFILE; | return LUA_ERRFILE; | ||||
LuaCharPtr var; var.Get(l, 1); | |||||
char const *filename = var;// lua_tostring(l, 1); | |||||
auto stack = LuaStack::Begin(l); | |||||
char const *filename = stack.Get<char const*>(); | |||||
int status = LUA_ERRFILE; | int status = LUA_ERRFILE; | ||||
File f; | File f; | ||||
@@ -76,8 +77,9 @@ class LuaBaseData | |||||
msg::error("could not find Lua file %s\n", filename); | msg::error("could not find Lua file %s\n", filename); | ||||
else if (status == 1) | else if (status == 1) | ||||
{ | { | ||||
LuaString error; error.Get(l, -1); | |||||
msg::error("Lua error %s\n", error().C()); | |||||
stack.SetIndex(-1); | |||||
auto error = stack.Get<String>(); | |||||
msg::error("Lua error %s\n", error.C()); | |||||
lua_pop(l, 1); | lua_pop(l, 1); | ||||
} | } | ||||
@@ -251,6 +251,13 @@ void SdlInputData::Tick(float seconds) | |||||
m_mouse->SetAxis(4, 0); | m_mouse->SetAxis(4, 0); | ||||
# if !LOL_USE_OLD_SDL | |||||
if (m_keyboard->IsTextInputActive()) | |||||
SDL_StartTextInput(); | |||||
else | |||||
SDL_StopTextInput(); | |||||
# endif | |||||
/* Handle keyboard and WM events */ | /* Handle keyboard and WM events */ | ||||
SDL_Event event; | SDL_Event event; | ||||
while (SDL_PollEvent(&event)) | while (SDL_PollEvent(&event)) | ||||
@@ -271,10 +278,10 @@ void SdlInputData::Tick(float seconds) | |||||
# endif | # endif | ||||
{ | { | ||||
//Lock management | //Lock management | ||||
# if defined SDLOL_CapsLock && defined SDLOL_ScrollLock && defined SDLOL_NumLockClear | |||||
case SDLOL_CapsLock: | case SDLOL_CapsLock: | ||||
case SDLOL_ScrollLock: | case SDLOL_ScrollLock: | ||||
case SDLOL_NumLockClear: | case SDLOL_NumLockClear: | ||||
# if defined SDLOL_CapsLock && defined SDLOL_ScrollLock && defined SDLOL_NumLockClear | |||||
//Update status on key down only | //Update status on key down only | ||||
if (event.type == SDL_KEYDOWN) | if (event.type == SDL_KEYDOWN) | ||||
{ | { | ||||
@@ -306,19 +313,9 @@ void SdlInputData::Tick(float seconds) | |||||
# else | # else | ||||
if (ScanCodeIsValid(sc)) | if (ScanCodeIsValid(sc)) | ||||
{ | { | ||||
//Set key updates the corresponding key | |||||
m_keyboard->SetKey(sc, event.type == SDL_KEYDOWN); | m_keyboard->SetKey(sc, event.type == SDL_KEYDOWN); | ||||
if (event.type == SDL_KEYDOWN | |||||
&& !m_keyboard->GetKey(SDLOL_RCtrl) | |||||
&& !m_keyboard->GetKey(SDLOL_LCtrl) | |||||
&& !m_keyboard->GetKey(SDLOL_RAlt) | |||||
&& !m_keyboard->GetKey(SDLOL_LAlt)) | |||||
{ | |||||
String str = ScanCodeToText(sc); | |||||
str.case_change(m_keyboard->GetKey(SDLOL_CapsLockStatus) | |||||
^ (m_keyboard->GetKey(SDLOL_RShift) | |||||
|| m_keyboard->GetKey(SDLOL_LShift))); | |||||
m_keyboard->AddText(str); | |||||
} | |||||
/* DEBUG STUFF | /* DEBUG STUFF | ||||
msg::info("Repeat: 0x%02x : %s/%s/%s/%i\n", | msg::info("Repeat: 0x%02x : %s/%s/%s/%i\n", | ||||
(int)m_keyboard, ScanCodeToText(sc).C(), ScanCodeToName(sc).C(), | (int)m_keyboard, ScanCodeToText(sc).C(), ScanCodeToName(sc).C(), | ||||
@@ -334,6 +331,14 @@ void SdlInputData::Tick(float seconds) | |||||
} | } | ||||
break; | break; | ||||
# if !LOL_USE_OLD_SDL | |||||
//case SDL_TEXTEDITING: //TODO: handle that ? | |||||
case SDL_TEXTINPUT: | |||||
m_keyboard->AddText(event.text.text); | |||||
break; | |||||
# endif | |||||
# if LOL_USE_OLD_SDL | # if LOL_USE_OLD_SDL | ||||
case SDL_MOUSEBUTTONDOWN: | case SDL_MOUSEBUTTONDOWN: | ||||
case SDL_MOUSEBUTTONUP: | case SDL_MOUSEBUTTONUP: | ||||
@@ -168,10 +168,10 @@ private: | |||||
/* Old line API <P0, P1, COLOR, TIME, MASK> */ | /* Old line API <P0, P1, COLOR, TIME, MASK> */ | ||||
struct line_api | struct line_api | ||||
{ | { | ||||
float m_time, m_segment_size; | |||||
vec4 m_color; | |||||
//float m_duration, m_segment_size; | |||||
//vec4 m_color; | |||||
array<vec3, vec3, vec4, float, int, bool, bool> m_lines; | array<vec3, vec3, vec4, float, int, bool, bool> m_lines; | ||||
int m_mask, m_debug_mask; | |||||
int /*m_mask,*/ m_debug_mask; | |||||
Shader *m_shader; | Shader *m_shader; | ||||
VertexDeclaration *m_vdecl; | VertexDeclaration *m_vdecl; | ||||
} | } | ||||
@@ -241,11 +241,6 @@ Scene::Scene(ivec2 size) | |||||
data->m_line_api.m_vdecl = new VertexDeclaration(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color)); | data->m_line_api.m_vdecl = new VertexDeclaration(VertexStream<vec4,vec4>(VertexUsage::Position, VertexUsage::Color)); | ||||
data->m_line_api.m_debug_mask = 1; | data->m_line_api.m_debug_mask = 1; | ||||
SetLineTime(); | |||||
SetLineMask(); | |||||
SetLineSegmentSize(); | |||||
SetLineColor(); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -533,56 +528,19 @@ void Scene::AddTile(TileSet *tileset, int id, mat4 model) | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
void Scene::SetLineTime(float new_time) | |||||
{ | |||||
ASSERT(!!data, "Trying to access a non-ready scene"); | |||||
data->m_line_api.m_time = new_time; | |||||
} | |||||
void Scene::SetLineMask(int new_mask) | |||||
{ | |||||
ASSERT(!!data, "Trying to access a non-ready scene"); | |||||
data->m_line_api.m_mask = new_mask; | |||||
} | |||||
void Scene::SetLineSegmentSize(float new_segment_size) | |||||
{ | |||||
ASSERT(!!data, "Trying to access a non-ready scene"); | |||||
data->m_line_api.m_segment_size = new_segment_size; | |||||
} | |||||
void Scene::SetLineColor(vec4 new_color) | |||||
{ | |||||
ASSERT(!!data, "Trying to access a non-ready scene"); | |||||
data->m_line_api.m_color = new_color; | |||||
} | |||||
//----------------------------------------------------------------------------- | |||||
float Scene::GetLineSegmentSize() | |||||
{ | |||||
ASSERT(!!data, "Trying to access a non-ready scene"); | |||||
return data->m_line_api.m_segment_size; | |||||
} | |||||
vec4 Scene::GetLineColor() | |||||
void Scene::AddLine(vec3 a, vec3 b, vec4 color) | |||||
{ | { | ||||
ASSERT(!!data, "Trying to access a non-ready scene"); | ASSERT(!!data, "Trying to access a non-ready scene"); | ||||
return data->m_line_api.m_color; | |||||
data->m_line_api.m_lines.push(a, b, color, -1.f, 0xFFFFFFFF, false, false); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
void Scene::AddLine(vec3 a, vec3 b, vec4 color) | |||||
void Scene::AddLine(vec3 a, vec3 b, vec4 color, float duration, int mask) | |||||
{ | { | ||||
ASSERT(!!data, "Trying to access a non-ready scene"); | ASSERT(!!data, "Trying to access a non-ready scene"); | ||||
data->m_line_api.m_lines.push(a, b, color, | |||||
data->m_line_api.m_time, data->m_line_api.m_mask, false, false); | |||||
data->m_line_api.m_lines.push(a, b, color, duration, mask, false, false); | |||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
@@ -765,7 +723,7 @@ void Scene::render_tiles() // XXX: rename to Blit() | |||||
if (!data->m_tile_api.m_shader) | if (!data->m_tile_api.m_shader) | ||||
data->m_tile_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_tile)); | data->m_tile_api.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_tile)); | ||||
if (!data->m_tile_api.m_palette_shader) | |||||
if (!data->m_tile_api.m_palette_shader && data->m_tile_api.m_palettes.count()) | |||||
data->m_tile_api.m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_palette)); | data->m_tile_api.m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(gpu_palette)); | ||||
for (int p = 0; p < 2; p++) | for (int p = 0; p < 2; p++) | ||||
@@ -791,7 +749,7 @@ void Scene::render_tiles() // XXX: rename to Blit() | |||||
shader->SetUniform(uni_mat, mat4(1.f)); | shader->SetUniform(uni_mat, mat4(1.f)); | ||||
uni_tex = shader->GetUniformLocation("u_texture"); | uni_tex = shader->GetUniformLocation("u_texture"); | ||||
uni_pal = data->m_tile_api.m_palette_shader->GetUniformLocation("u_palette"); | |||||
uni_pal = data->m_tile_api.m_palette_shader ? data->m_tile_api.m_palette_shader->GetUniformLocation("u_palette") : ShaderUniform(); | |||||
uni_texsize = shader->GetUniformLocation("u_texsize"); | uni_texsize = shader->GetUniformLocation("u_texsize"); | ||||
for (int buf = 0, i = 0, n; i < tiles.count(); i = n, buf += 2) | for (int buf = 0, i = 0, n; i < tiles.count(); i = n, buf += 2) | ||||
@@ -851,6 +809,9 @@ void Scene::render_tiles() // XXX: rename to Blit() | |||||
tiles.empty(); | tiles.empty(); | ||||
shader->Unbind(); | shader->Unbind(); | ||||
if (!data->m_tile_api.m_palette_shader) | |||||
break; | |||||
} | } | ||||
#if (defined LOL_USE_GLEW || defined HAVE_GL_2X) && !defined HAVE_GLES_2X | #if (defined LOL_USE_GLEW || defined HAVE_GL_2X) && !defined HAVE_GLES_2X | ||||
@@ -234,14 +234,8 @@ public: | |||||
void AddTile(TileSet *tileset, int id, mat4 model); | void AddTile(TileSet *tileset, int id, mat4 model); | ||||
public: | public: | ||||
void SetLineTime(float new_time = -1.f); | |||||
void SetLineMask(int new_mask = 0xFFFFFFFF); | |||||
void SetLineSegmentSize(float new_segment_size = 1.f); | |||||
void SetLineColor(vec4 new_color = vec4(1.f)); | |||||
float GetLineSegmentSize(); | |||||
vec4 GetLineColor(); | |||||
void AddLine(vec3 a, vec3 b, vec4 color); | void AddLine(vec3 a, vec3 b, vec4 color); | ||||
void AddLine(vec3 a, vec3 b, vec4 color, float duration, int mask); | |||||
void AddLight(Light *light); | void AddLight(Light *light); | ||||
array<Light *> const &GetLights(); | array<Light *> const &GetLights(); | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -182,7 +184,7 @@ class FileData | |||||
#endif | #endif | ||||
} | } | ||||
long int GetSize() | |||||
long int size() | |||||
{ | { | ||||
#if __ANDROID__ | #if __ANDROID__ | ||||
return 0; | return 0; | ||||
@@ -321,9 +323,9 @@ void File::SetPosFromStart(long int pos) | |||||
} | } | ||||
//-- | //-- | ||||
long int File::GetSize() | |||||
long int File::size() | |||||
{ | { | ||||
return m_data->GetSize(); | |||||
return m_data->size(); | |||||
} | } | ||||
//-- | //-- | ||||
@@ -104,6 +104,13 @@ void init(int argc, char *argv[], | |||||
rootdir += "../src/"; /* FIXME: use SEPARATOR? */ | rootdir += "../src/"; /* FIXME: use SEPARATOR? */ | ||||
add_data_dir(rootdir); | add_data_dir(rootdir); | ||||
/* This data dir is for submodule support stuff */ | |||||
rootdir = solutiondir; | |||||
if (rootdir.count() && rootdir.last() != SEPARATOR) | |||||
rootdir += SEPARATOR; | |||||
rootdir += "./lol/src/"; /* FIXME: use SEPARATOR? */ | |||||
add_data_dir(rootdir); | |||||
/* This data dir is for project-specific stuff */ | /* This data dir is for project-specific stuff */ | ||||
rootdir = projectdir; | rootdir = projectdir; | ||||
if (rootdir.count() && rootdir.last() != SEPARATOR) | if (rootdir.count() && rootdir.last() != SEPARATOR) | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine | // Lol Engine | ||||
// | // | ||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | // © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | ||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
@@ -175,7 +175,7 @@ public: | |||||
protected: | protected: | ||||
virtual bool DoWork() | virtual bool DoWork() | ||||
{ | { | ||||
return m_image.Load(m_path.C()); | |||||
return m_image.load(m_path.C()); | |||||
} | } | ||||
String m_path; | String m_path; | ||||
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine — Unit tests | // Lol Engine — Unit tests | ||||
// | // | ||||
// Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | // | ||||
// Lol Engine is free software. It comes without any warranty, to | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // the extent permitted by applicable law. You can redistribute it | ||||
@@ -23,13 +23,13 @@ lolunit_declare_fixture(image_test) | |||||
{ | { | ||||
lolunit_declare_test(open_image) | lolunit_declare_test(open_image) | ||||
{ | { | ||||
Image image("data/gradient.png"); | |||||
image img("data/gradient.png"); | |||||
ivec2 size = image.GetSize(); | |||||
lolunit_assert_equal(size.x, 256); | |||||
lolunit_assert_equal(size.y, 16); | |||||
ivec2 isize = img.size(); | |||||
lolunit_assert_equal(isize.x, 256); | |||||
lolunit_assert_equal(isize.y, 16); | |||||
u8vec4 *data = image.Lock<PixelFormat::RGBA_8>(); | |||||
u8vec4 *data = img.lock<PixelFormat::RGBA_8>(); | |||||
lolunit_assert(data); | lolunit_assert(data); | ||||
lolunit_assert_equal((int)data[0].r, 0x00); | lolunit_assert_equal((int)data[0].r, 0x00); | ||||
@@ -40,7 +40,7 @@ lolunit_declare_fixture(image_test) | |||||
lolunit_assert_equal((int)data[255].g, 0xff); | lolunit_assert_equal((int)data[255].g, 0xff); | ||||
lolunit_assert_equal((int)data[255].b, 0xff); | lolunit_assert_equal((int)data[255].b, 0xff); | ||||
image.Unlock(data); | |||||
img.unlock(data); | |||||
} | } | ||||
}; | }; | ||||
@@ -1,11 +1,13 @@ | |||||
// | // | ||||
// Lol Engine | |||||
// Lol Engine | |||||
// | // | ||||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://www.wtfpl.net/ for more details. | |||||
// Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | // | ||||
#include <lol/engine-internal.h> | #include <lol/engine-internal.h> | ||||
@@ -44,10 +46,10 @@ TextureImage::TextureImage(char const *path) | |||||
Init(path); | Init(path); | ||||
} | } | ||||
TextureImage::TextureImage(char const *path, Image* image) | |||||
TextureImage::TextureImage(char const *path, image* img) | |||||
: m_data(GetNewData()) | : m_data(GetNewData()) | ||||
{ | { | ||||
Init(path, image); | |||||
Init(path, img); | |||||
} | } | ||||
TextureImage::~TextureImage() | TextureImage::~TextureImage() | ||||
@@ -57,16 +59,28 @@ TextureImage::~TextureImage() | |||||
void TextureImage::Init(char const *path) | void TextureImage::Init(char const *path) | ||||
{ | { | ||||
Init(path, new Image(path)); | |||||
Init(path, ResourceLoader::Load(path)); | |||||
} | } | ||||
void TextureImage::Init(char const *path, Image* image) | |||||
void TextureImage::Init(char const *path, ResourceCodecData* loaded_data) | |||||
{ | |||||
//Load image if available | |||||
auto image_data = dynamic_cast<ResourceImageData*>(loaded_data); | |||||
if (image_data != nullptr) | |||||
{ | |||||
Init(path, new image(*image_data->m_image)); | |||||
} | |||||
delete image_data; | |||||
} | |||||
void TextureImage::Init(char const *path, image* img) | |||||
{ | { | ||||
m_data->m_name = String("<textureimage> ") + path; | m_data->m_name = String("<textureimage> ") + path; | ||||
m_data->m_texture = nullptr; | m_data->m_texture = nullptr; | ||||
m_data->m_image = image; | |||||
m_data->m_image_size = m_data->m_image->GetSize(); | |||||
m_data->m_image = img; | |||||
m_data->m_image_size = m_data->m_image->size(); | |||||
m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x), | m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x), | ||||
PotUp(m_data->m_image_size.y)); | PotUp(m_data->m_image_size.y)); | ||||
@@ -99,13 +113,13 @@ void TextureImage::TickDraw(float seconds, Scene &scene) | |||||
m_data->m_texture = nullptr; | m_data->m_texture = nullptr; | ||||
} | } | ||||
PixelFormat format = m_data->m_image->GetFormat(); | |||||
PixelFormat format = m_data->m_image->format(); | |||||
int planes = BytesPerPixel(format); | int planes = BytesPerPixel(format); | ||||
int w = m_data->m_texture_size.x; | int w = m_data->m_texture_size.x; | ||||
int h = m_data->m_texture_size.y; | int h = m_data->m_texture_size.y; | ||||
uint8_t *pixels = (uint8_t *)m_data->m_image->Lock(); | |||||
uint8_t *pixels = (uint8_t *)m_data->m_image->lock(); | |||||
bool resized = false; | bool resized = false; | ||||
if (w != m_data->m_image_size.x || h != m_data->m_image_size.y) | if (w != m_data->m_image_size.x || h != m_data->m_image_size.y) | ||||
{ | { | ||||
@@ -117,6 +131,7 @@ void TextureImage::TickDraw(float seconds, Scene &scene) | |||||
pixels = tmp; | pixels = tmp; | ||||
resized = false; | resized = false; | ||||
} | } | ||||
/* FIXME: no unlock? */ | |||||
m_data->m_texture = new Texture(ivec2(w, h), format); | m_data->m_texture = new Texture(ivec2(w, h), format); | ||||
m_data->m_texture->SetData(pixels); | m_data->m_texture->SetData(pixels); | ||||
@@ -134,12 +149,12 @@ char const *TextureImage::GetName() | |||||
return m_data->m_name.C(); | return m_data->m_name.C(); | ||||
} | } | ||||
void TextureImage::UpdateTexture(Image* image) | |||||
void TextureImage::UpdateTexture(image* img) | |||||
{ | { | ||||
m_data->m_image = image; | |||||
m_data->m_image_size = m_data->m_image->GetSize(); | |||||
m_data->m_image = img; | |||||
m_data->m_image_size = m_data->m_image->size(); | |||||
m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x), | m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x), | ||||
PotUp(m_data->m_image_size.y)); | |||||
PotUp(m_data->m_image_size.y)); | |||||
} | } | ||||
Texture * TextureImage::GetTexture() | Texture * TextureImage::GetTexture() | ||||
@@ -152,16 +167,21 @@ Texture const * TextureImage::GetTexture() const | |||||
return m_data->m_texture; | return m_data->m_texture; | ||||
} | } | ||||
Image * TextureImage::GetImage() | |||||
image * TextureImage::GetImage() | |||||
{ | { | ||||
return m_data->m_image; | return m_data->m_image; | ||||
} | } | ||||
Image const * TextureImage::GetImage() const | |||||
image const * TextureImage::GetImage() const | |||||
{ | { | ||||
return m_data->m_image; | return m_data->m_image; | ||||
} | } | ||||
ivec2 TextureImage::GetImageSize() const | |||||
{ | |||||
return m_data->m_image_size; | |||||
} | |||||
ivec2 TextureImage::GetTextureSize() const | ivec2 TextureImage::GetTextureSize() const | ||||
{ | { | ||||
return m_data->m_texture_size; | return m_data->m_texture_size; | ||||
@@ -18,6 +18,7 @@ | |||||
// zero, the texture is freed. | // zero, the texture is freed. | ||||
// | // | ||||
#include <lol/image/resource.h> | |||||
#include <lol/image/image.h> | #include <lol/image/image.h> | ||||
#include <lol/gpu/texture.h> | #include <lol/gpu/texture.h> | ||||
@@ -38,12 +39,13 @@ protected: | |||||
public: | public: | ||||
TextureImage(char const *path); | TextureImage(char const *path); | ||||
TextureImage(char const *path, Image* image); | |||||
TextureImage(char const *path, image* img); | |||||
virtual ~TextureImage(); | virtual ~TextureImage(); | ||||
protected: | protected: | ||||
void Init(char const *path); | void Init(char const *path); | ||||
virtual void Init(char const *path, Image* image); | |||||
virtual void Init(char const *path, ResourceCodecData* loaded_data); | |||||
virtual void Init(char const *path, image* img); | |||||
protected: | protected: | ||||
virtual void TickDraw(float seconds, Scene &scene); | virtual void TickDraw(float seconds, Scene &scene); | ||||
@@ -52,11 +54,12 @@ public: | |||||
/* Inherited from Entity */ | /* Inherited from Entity */ | ||||
virtual char const *GetName(); | virtual char const *GetName(); | ||||
void UpdateTexture(Image* image); | |||||
void UpdateTexture(image* img); | |||||
Texture * GetTexture(); | Texture * GetTexture(); | ||||
Texture const * GetTexture() const; | Texture const * GetTexture() const; | ||||
Image * GetImage(); | |||||
Image const * GetImage() const; | |||||
image * GetImage(); | |||||
image const * GetImage() const; | |||||
ivec2 GetImageSize() const; | |||||
ivec2 GetTextureSize() const; | ivec2 GetTextureSize() const; | ||||
void Bind(); | void Bind(); | ||||
void Unbind(); | void Unbind(); | ||||
@@ -30,10 +30,10 @@ public: | |||||
static TileSet *Register(char const *path, ivec2 size, ivec2 count); | static TileSet *Register(char const *path, ivec2 size, ivec2 count); | ||||
static TileSet *Register(String const &path); | static TileSet *Register(String const &path); | ||||
static TileSet *Register(char const *path); | static TileSet *Register(char const *path); | ||||
static TileSet *Register(String const &path, Image* image, ivec2 size, ivec2 count); | |||||
static TileSet *Register(char const *path, Image* image, ivec2 size, ivec2 count); | |||||
static TileSet *Register(String const &path, Image* image); | |||||
static TileSet *Register(char const *path, Image* image); | |||||
static TileSet *Register(String const &path, image* img, ivec2 size, ivec2 count); | |||||
static TileSet *Register(char const *path, image* img, ivec2 size, ivec2 count); | |||||
static TileSet *Register(String const &path, image* img); | |||||
static TileSet *Register(char const *path, image* img); | |||||
static void Deregister(TileSet *); | static void Deregister(TileSet *); | ||||
private: | private: | ||||
@@ -46,25 +46,25 @@ protected: | |||||
*/ | */ | ||||
TileSet::TileSet(char const *path) | TileSet::TileSet(char const *path) | ||||
: TextureImage(path), | |||||
: m_tileset_data(new TileSetData()), | |||||
m_palette(nullptr), | |||||
TextureImage(path) | |||||
{ | |||||
} | |||||
TileSet::TileSet(char const *path, Image* image) | |||||
: TextureImage(path, image), | |||||
m_tileset_data(new TileSetData()), | m_tileset_data(new TileSetData()), | ||||
m_palette(nullptr) | m_palette(nullptr) | ||||
{ | { | ||||
array<ivec2, ivec2> tiles; | |||||
if (m_data->m_image->RetrieveTiles(tiles)) | |||||
for (int i = 0; i < tiles.count(); i++) | |||||
define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2)); | |||||
} | } | ||||
TileSet::TileSet(char const *path, Image* image) | |||||
: TextureImage(path, image), | |||||
TileSet::TileSet(char const *path, Image* image, array<ivec2, ivec2>& tiles) | |||||
: TextureImage(path, image), | |||||
m_tileset_data(new TileSetData()), | m_tileset_data(new TileSetData()), | ||||
m_palette(nullptr) | m_palette(nullptr) | ||||
{ | { | ||||
array<ivec2, ivec2> tiles; | |||||
if (m_data->m_image->RetrieveTiles(tiles)) | |||||
for (int i = 0; i < tiles.count(); i++) | |||||
define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2)); | |||||
define_tile(tiles); | |||||
} | } | ||||
TileSet::TileSet(char const *path, ivec2 size, ivec2 count) | TileSet::TileSet(char const *path, ivec2 size, ivec2 count) | ||||
@@ -118,6 +118,20 @@ TileSet::~TileSet() | |||||
delete m_tileset_data; | delete m_tileset_data; | ||||
} | } | ||||
void TileSet::Init(char const *path, ResourceCodecData* loaded_data) | |||||
{ | |||||
//Load tileset if available | |||||
auto tileset_data = dynamic_cast<ResourceTilesetData*>(loaded_data); | |||||
if (tileset_data != nullptr) | |||||
{ | |||||
define_tile(tileset_data->m_tiles); | |||||
} | |||||
m_data->m_name = String("<tileset> ") + path; | |||||
super::Init(path, loaded_data); | |||||
} | |||||
void TileSet::Init(char const *path, Image* image) | void TileSet::Init(char const *path, Image* image) | ||||
{ | { | ||||
super::Init(path, image); | super::Init(path, image); | ||||
@@ -132,6 +146,11 @@ char const *TileSet::GetName() | |||||
} | } | ||||
//New methods ----------------------------------------------------------------- | //New methods ----------------------------------------------------------------- | ||||
void TileSet::clear_all() | |||||
{ | |||||
m_tileset_data->m_tiles.empty(); | |||||
} | |||||
int TileSet::define_tile(ibox2 rect) | int TileSet::define_tile(ibox2 rect) | ||||
{ | { | ||||
m_tileset_data->m_tiles.push(rect, | m_tileset_data->m_tiles.push(rect, | ||||
@@ -152,6 +171,18 @@ void TileSet::define_tile(ivec2 count) | |||||
} | } | ||||
} | } | ||||
void TileSet::define_tile(array<ibox2>& tiles) | |||||
{ | |||||
for (int i = 0; i < tiles.count(); i++) | |||||
define_tile(tiles[i]); | |||||
} | |||||
void TileSet::define_tile(array<ivec2, ivec2>& tiles) | |||||
{ | |||||
for (int i = 0; i < tiles.count(); i++) | |||||
define_tile(ibox2(tiles[i].m1, tiles[i].m1 + tiles[i].m2)); | |||||
} | |||||
int TileSet::GetTileCount() const | int TileSet::GetTileCount() const | ||||
{ | { | ||||
return m_tileset_data->m_tiles.count(); | return m_tileset_data->m_tiles.count(); | ||||
@@ -162,6 +193,16 @@ ivec2 TileSet::GetTileSize(int tileid) const | |||||
return m_tileset_data->m_tiles[tileid].m1.extent(); | return m_tileset_data->m_tiles[tileid].m1.extent(); | ||||
} | } | ||||
ibox2 TileSet::GetTilePixel(int tileid) const | |||||
{ | |||||
return m_tileset_data->m_tiles[tileid].m1; | |||||
} | |||||
box2 TileSet::GetTileTexel(int tileid) const | |||||
{ | |||||
return m_tileset_data->m_tiles[tileid].m2; | |||||
} | |||||
//Palette --------------------------------------------------------------------- | //Palette --------------------------------------------------------------------- | ||||
void TileSet::SetPalette(TileSet* palette) | void TileSet::SetPalette(TileSet* palette) | ||||
{ | { | ||||
@@ -42,26 +42,33 @@ class TileSet : public TextureImage | |||||
public: | public: | ||||
TileSet(char const *path); | TileSet(char const *path); | ||||
TileSet(char const *path, Image* image); | |||||
TileSet(char const *path, image* img); | |||||
TileSet(char const *path, image* img, array<ivec2, ivec2>& tiles); | |||||
/* Old style: path to PNG file */ | /* Old style: path to PNG file */ | ||||
TileSet(char const *path, ivec2 size, ivec2 count); | TileSet(char const *path, ivec2 size, ivec2 count); | ||||
TileSet(char const *path, Image* image, ivec2 size, ivec2 count); | |||||
TileSet(char const *path, image* img, ivec2 size, ivec2 count); | |||||
virtual ~TileSet(); | virtual ~TileSet(); | ||||
protected: | protected: | ||||
virtual void Init(char const *path, Image* image); | |||||
virtual void Init(char const *path, ResourceCodecData* loaded_data); | |||||
virtual void Init(char const *path, image* img); | |||||
public: | public: | ||||
/* Inherited from Entity */ | /* Inherited from Entity */ | ||||
virtual char const *GetName(); | virtual char const *GetName(); | ||||
/* New methods */ | /* New methods */ | ||||
void clear_all(); | |||||
int define_tile(ibox2 rect); | int define_tile(ibox2 rect); | ||||
void define_tile(ivec2 count); | void define_tile(ivec2 count); | ||||
void define_tile(array<ibox2>& tiles); | |||||
void define_tile(array<ivec2, ivec2>& tiles); | |||||
int GetTileCount() const; | int GetTileCount() const; | ||||
ivec2 GetTileSize(int tileid) const; | ivec2 GetTileSize(int tileid) const; | ||||
ibox2 GetTilePixel(int tileid) const; | |||||
box2 GetTileTexel(int tileid) const; | |||||
void SetPalette(TileSet* palette); | void SetPalette(TileSet* palette); | ||||
TileSet* GetPalette(); | TileSet* GetPalette(); | ||||
@@ -61,6 +61,12 @@ template< class T > inline int GetRandom(array<T> src) | |||||
// Gets the value for the given enum type. | // Gets the value for the given enum type. | ||||
template<class T> inline T FindValue(const char* name) | template<class T> inline T FindValue(const char* name) | ||||
{ | |||||
auto str = String(name); | |||||
return FindValue<T>(str); | |||||
} | |||||
template<class T> inline T FindValue(String const& name) | |||||
{ | { | ||||
String n = name; | String n = name; | ||||
n.to_lower(); | n.to_lower(); | ||||
@@ -72,10 +78,6 @@ template<class T> inline T FindValue(const char* name) | |||||
} | } | ||||
return T::Max; | return T::Max; | ||||
} | } | ||||
template<class T> inline T FindValue(String const& name) | |||||
{ | |||||
return FindValue<T>(name.C()); | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||