3545 lines
143 KiB
C++
3545 lines
143 KiB
C++
/**************************************************************************************/
|
|
/* */
|
|
/* Visualization Library */
|
|
/* http://visualizationlibrary.org */
|
|
/* */
|
|
/* Copyright (c) 2005-2020, Michele Bosi */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or without modification, */
|
|
/* are permitted provided that the following conditions are met: */
|
|
/* */
|
|
/* - Redistributions of source code must retain the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer. */
|
|
/* */
|
|
/* - Redistributions in binary form must reproduce the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer in the documentation and/or */
|
|
/* other materials provided with the distribution. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
|
|
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
|
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
|
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
|
|
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
|
|
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
|
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/**************************************************************************************/
|
|
|
|
#ifndef VLXWrapper_Graphics_INCLUDE_ONCE
|
|
#define VLXWrapper_Graphics_INCLUDE_ONCE
|
|
|
|
#include <vlX/WrappersCore.hpp>
|
|
#include <vlCore/LoadWriterManager.hpp>
|
|
#include <vlGraphics/Actor.hpp>
|
|
#include <vlGraphics/Effect.hpp>
|
|
#include <vlGraphics/Shader.hpp>
|
|
#include <vlGraphics/Geometry.hpp>
|
|
#include <vlGraphics/Light.hpp>
|
|
#include <vlGraphics/ClipPlane.hpp>
|
|
#include <vlGraphics/Camera.hpp>
|
|
#include <vlGraphics/DrawElements.hpp>
|
|
#include <vlGraphics/MultiDrawElements.hpp>
|
|
#include <vlGraphics/DrawArrays.hpp>
|
|
#include <vlGraphics/SceneManagerActorTree.hpp>
|
|
#include <vlGraphics/DistanceLODEvaluator.hpp>
|
|
#include <vlGraphics/PixelLODEvaluator.hpp>
|
|
#include <vlGraphics/DepthSortCallback.hpp>
|
|
#include <vlGraphics/GLSL.hpp>
|
|
#include <vlCore/ResourceDatabase.hpp>
|
|
#include <vlCore/DiskFile.hpp>
|
|
|
|
namespace vlX
|
|
{
|
|
/** VLX wrapper of vl::Array */
|
|
struct VLXClassWrapper_Array: public ClassWrapper
|
|
{
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
if (!vlx->getValue("Value"))
|
|
{
|
|
vl::Log::error( vl::Say("Line %n : error. 'VLXValue' expected in object '%s'. \n") << vlx->lineNumber() << vlx->tag() );
|
|
return NULL;
|
|
}
|
|
|
|
const VLXValue& value = *vlx->getValue("Value");
|
|
|
|
vl::ref<vl::ArrayAbstract> arr_abstract;
|
|
|
|
if (vlx->tag() == "<vl::ArrayFloat1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_float = value.getArrayReal();
|
|
vl::ref<vl::ArrayFloat1> arr_float1 = new vl::ArrayFloat1; arr_abstract = arr_float1;
|
|
arr_float1->resize( vlx_arr_float->value().size() );
|
|
vlx_arr_float->copyTo((float*)arr_float1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayFloat2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_float = value.getArrayReal();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayFloat2> arr_float2 = new vl::ArrayFloat2; arr_abstract = arr_float2;
|
|
arr_float2->resize( vlx_arr_float->value().size() / 2 );
|
|
vlx_arr_float->copyTo((float*)arr_float2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayFloat3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_float = value.getArrayReal();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayFloat3> arr_float3 = new vl::ArrayFloat3; arr_abstract = arr_float3;
|
|
arr_float3->resize( vlx_arr_float->value().size() / 3 );
|
|
vlx_arr_float->copyTo((float*)arr_float3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayFloat4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_float = value.getArrayReal();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_float->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayFloat4> arr_float4 = new vl::ArrayFloat4; arr_abstract = arr_float4;
|
|
arr_float4->resize( vlx_arr_float->value().size() / 4 );
|
|
vlx_arr_float->copyTo((float*)arr_float4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayDouble1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
|
|
vl::ref<vl::ArrayDouble1> arr_floating1 = new vl::ArrayDouble1; arr_abstract = arr_floating1;
|
|
arr_floating1->resize( vlx_arr_floating->value().size() );
|
|
vlx_arr_floating->copyTo((double*)arr_floating1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayDouble2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayDouble2> arr_floating2 = new vl::ArrayDouble2; arr_abstract = arr_floating2;
|
|
arr_floating2->resize( vlx_arr_floating->value().size() / 2 );
|
|
vlx_arr_floating->copyTo((double*)arr_floating2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayDouble3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayDouble3> arr_floating3 = new vl::ArrayDouble3; arr_abstract = arr_floating3;
|
|
arr_floating3->resize( vlx_arr_floating->value().size() / 3 );
|
|
vlx_arr_floating->copyTo((double*)arr_floating3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayDouble4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayReal, value);
|
|
const VLXArrayReal* vlx_arr_floating = value.getArrayReal();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_floating->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayDouble4> arr_floating4 = new vl::ArrayDouble4; arr_abstract = arr_floating4;
|
|
arr_floating4->resize( vlx_arr_floating->value().size() / 4 );
|
|
vlx_arr_floating->copyTo((double*)arr_floating4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayInt1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
vl::ref<vl::ArrayInt1> arr_int1 = new vl::ArrayInt1; arr_abstract = arr_int1;
|
|
arr_int1->resize( vlx_arr_int->value().size() );
|
|
vlx_arr_int->copyTo((int*)arr_int1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayInt2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayInt2> arr_int2 = new vl::ArrayInt2; arr_abstract = arr_int2;
|
|
arr_int2->resize( vlx_arr_int->value().size() / 2 );
|
|
vlx_arr_int->copyTo((int*)arr_int2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayInt3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayInt3> arr_int3 = new vl::ArrayInt3; arr_abstract = arr_int3;
|
|
arr_int3->resize( vlx_arr_int->value().size() / 3 );
|
|
vlx_arr_int->copyTo((int*)arr_int3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayInt4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayInt4> arr_int4 = new vl::ArrayInt4; arr_abstract = arr_int4;
|
|
arr_int4->resize( vlx_arr_int->value().size() / 4 );
|
|
vlx_arr_int->copyTo((int*)arr_int4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUInt1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
vl::ref<vl::ArrayUInt1> arr_int1 = new vl::ArrayUInt1; arr_abstract = arr_int1;
|
|
arr_int1->resize( vlx_arr_int->value().size() );
|
|
vlx_arr_int->copyTo((unsigned int*)arr_int1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUInt2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayUInt2> arr_int2 = new vl::ArrayUInt2; arr_abstract = arr_int2;
|
|
arr_int2->resize( vlx_arr_int->value().size() / 2 );
|
|
vlx_arr_int->copyTo((unsigned int*)arr_int2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUInt3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayUInt3> arr_int3 = new vl::ArrayUInt3; arr_abstract = arr_int3;
|
|
arr_int3->resize( vlx_arr_int->value().size() / 3 );
|
|
vlx_arr_int->copyTo((unsigned int*)arr_int3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUInt4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayUInt4> arr_int4 = new vl::ArrayUInt4; arr_abstract = arr_int4;
|
|
arr_int4->resize( vlx_arr_int->value().size() / 4 );
|
|
vlx_arr_int->copyTo((unsigned int*)arr_int4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayShort1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
vl::ref<vl::ArrayShort1> arr_short1 = new vl::ArrayShort1; arr_abstract = arr_short1;
|
|
arr_short1->resize( vlx_arr_int->value().size() );
|
|
vlx_arr_int->copyTo((short*)arr_short1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayShort2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayShort2> arr_short2 = new vl::ArrayShort2; arr_abstract = arr_short2;
|
|
arr_short2->resize( vlx_arr_int->value().size() / 2 );
|
|
vlx_arr_int->copyTo((short*)arr_short2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayShort3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayShort3> arr_short3 = new vl::ArrayShort3; arr_abstract = arr_short3;
|
|
arr_short3->resize( vlx_arr_int->value().size() / 3 );
|
|
vlx_arr_int->copyTo((short*)arr_short3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayShort4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayShort4> arr_short4 = new vl::ArrayShort4; arr_abstract = arr_short4;
|
|
arr_short4->resize( vlx_arr_int->value().size() / 4 );
|
|
vlx_arr_int->copyTo((short*)arr_short4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUShort1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
vl::ref<vl::ArrayUShort1> arr_short1 = new vl::ArrayUShort1; arr_abstract = arr_short1;
|
|
arr_short1->resize( vlx_arr_int->value().size() );
|
|
vlx_arr_int->copyTo((unsigned short*)arr_short1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUShort2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayUShort2> arr_short2 = new vl::ArrayUShort2; arr_abstract = arr_short2;
|
|
arr_short2->resize( vlx_arr_int->value().size() / 2 );
|
|
vlx_arr_int->copyTo((unsigned short*)arr_short2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUShort3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayUShort3> arr_short3 = new vl::ArrayUShort3; arr_abstract = arr_short3;
|
|
arr_short3->resize( vlx_arr_int->value().size() / 3 );
|
|
vlx_arr_int->copyTo((unsigned short*)arr_short3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUShort4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayUShort4> arr_short4 = new vl::ArrayUShort4; arr_abstract = arr_short4;
|
|
arr_short4->resize( vlx_arr_int->value().size() / 4 );
|
|
vlx_arr_int->copyTo((unsigned short*)arr_short4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayByte1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
vl::ref<vl::ArrayByte1> arr_byte1 = new vl::ArrayByte1; arr_abstract = arr_byte1;
|
|
arr_byte1->resize( vlx_arr_int->value().size() );
|
|
vlx_arr_int->copyTo((char*)arr_byte1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayByte2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayByte2> arr_byte2 = new vl::ArrayByte2; arr_abstract = arr_byte2;
|
|
arr_byte2->resize( vlx_arr_int->value().size() / 2 );
|
|
vlx_arr_int->copyTo((char*)arr_byte2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayByte3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayByte3> arr_byte3 = new vl::ArrayByte3; arr_abstract = arr_byte3;
|
|
arr_byte3->resize( vlx_arr_int->value().size() / 3 );
|
|
vlx_arr_int->copyTo((char*)arr_byte3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayByte4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayByte4> arr_byte4 = new vl::ArrayByte4; arr_abstract = arr_byte4;
|
|
arr_byte4->resize( vlx_arr_int->value().size() / 4 );
|
|
vlx_arr_int->copyTo((char*)arr_byte4->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUByte1>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
vl::ref<vl::ArrayUByte1> arr_byte1 = new vl::ArrayUByte1; arr_abstract = arr_byte1;
|
|
arr_byte1->resize( vlx_arr_int->value().size() );
|
|
vlx_arr_int->copyTo((unsigned char*)arr_byte1->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUByte2>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 2 == 0, value)
|
|
vl::ref<vl::ArrayUByte2> arr_byte2 = new vl::ArrayUByte2; arr_abstract = arr_byte2;
|
|
arr_byte2->resize( vlx_arr_int->value().size() / 2 );
|
|
vlx_arr_int->copyTo((unsigned char*)arr_byte2->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUByte3>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 3 == 0, value)
|
|
vl::ref<vl::ArrayUByte3> arr_byte3 = new vl::ArrayUByte3; arr_abstract = arr_byte3;
|
|
arr_byte3->resize( vlx_arr_int->value().size() / 3 );
|
|
vlx_arr_int->copyTo((unsigned char*)arr_byte3->ptr());
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::ArrayUByte4>")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN_NULL(value.type() == VLXValue::ArrayInteger, value);
|
|
const VLXArrayInteger* vlx_arr_int = value.getArrayInteger();
|
|
VLX_IMPORT_CHECK_RETURN_NULL( vlx_arr_int->value().size() % 4 == 0, value)
|
|
vl::ref<vl::ArrayUByte4> arr_byte4 = new vl::ArrayUByte4; arr_abstract = arr_byte4;
|
|
arr_byte4->resize( vlx_arr_int->value().size() / 4 );
|
|
vlx_arr_int->copyTo((unsigned char*)arr_byte4->ptr());
|
|
}
|
|
else
|
|
{
|
|
s.signalImportError( vl::Say("Line %n : unknown array '%s'.\n") << vlx->lineNumber() << vlx->tag() );
|
|
}
|
|
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, arr_abstract.get());
|
|
return arr_abstract.get();
|
|
}
|
|
|
|
template<typename T_Array, typename T_VLXArray>
|
|
vl::ref<VLXStructure> export_ArrayT(VLXSerializer& s, const vl::Object* arr_abstract)
|
|
{
|
|
const T_Array* arr = arr_abstract->as<T_Array>();
|
|
vl::ref<VLXStructure> st =new VLXStructure(vlx_makeTag(arr_abstract).c_str(), s.generateID("array_"));
|
|
vl::ref<T_VLXArray> vlx_array = new T_VLXArray;
|
|
if (arr->size())
|
|
{
|
|
vlx_array->value().resize( arr->size() * arr->glSize() );
|
|
typename T_VLXArray::scalar_type* dst = &vlx_array->value()[0];
|
|
const typename T_Array::scalar_type* src = (const typename T_Array::scalar_type*)arr->begin();
|
|
const typename T_Array::scalar_type* end = (const typename T_Array::scalar_type*)arr->end();
|
|
for(; src<end; ++src, ++dst)
|
|
*dst = (typename T_VLXArray::scalar_type)*src;
|
|
}
|
|
st->value().push_back( VLXStructure::KeyValue("Value", vlx_array.get() ) );
|
|
return st;
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
vl::ref<VLXStructure> vlx;
|
|
if(obj->classType() == vl::ArrayUInt1::Type())
|
|
vlx = export_ArrayT<vl::ArrayUInt1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUInt2::Type())
|
|
vlx = export_ArrayT<vl::ArrayUInt2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUInt3::Type())
|
|
vlx = export_ArrayT<vl::ArrayUInt3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUInt4::Type())
|
|
vlx = export_ArrayT<vl::ArrayUInt4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayInt1::Type())
|
|
vlx = export_ArrayT<vl::ArrayInt1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayInt2::Type())
|
|
vlx = export_ArrayT<vl::ArrayInt2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayInt3::Type())
|
|
vlx = export_ArrayT<vl::ArrayInt3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayInt4::Type())
|
|
vlx = export_ArrayT<vl::ArrayInt4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayUShort1::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUShort2::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUShort3::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUShort4::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayUShort1::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUShort2::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUShort3::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUShort4::Type())
|
|
vlx = export_ArrayT<vl::ArrayUShort4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayShort1::Type())
|
|
vlx = export_ArrayT<vl::ArrayShort1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayShort2::Type())
|
|
vlx = export_ArrayT<vl::ArrayShort2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayShort3::Type())
|
|
vlx = export_ArrayT<vl::ArrayShort3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayShort4::Type())
|
|
vlx = export_ArrayT<vl::ArrayShort4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayUByte1::Type())
|
|
vlx = export_ArrayT<vl::ArrayUByte1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUByte2::Type())
|
|
vlx = export_ArrayT<vl::ArrayUByte2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUByte3::Type())
|
|
vlx = export_ArrayT<vl::ArrayUByte3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayUByte4::Type())
|
|
vlx = export_ArrayT<vl::ArrayUByte4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayByte1::Type())
|
|
vlx = export_ArrayT<vl::ArrayByte1, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayByte2::Type())
|
|
vlx = export_ArrayT<vl::ArrayByte2, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayByte3::Type())
|
|
vlx = export_ArrayT<vl::ArrayByte3, VLXArrayInteger>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayByte4::Type())
|
|
vlx = export_ArrayT<vl::ArrayByte4, VLXArrayInteger>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayFloat1::Type())
|
|
vlx = export_ArrayT<vl::ArrayFloat1, VLXArrayReal>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayFloat2::Type())
|
|
vlx = export_ArrayT<vl::ArrayFloat2, VLXArrayReal>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayFloat3::Type())
|
|
vlx = export_ArrayT<vl::ArrayFloat3, VLXArrayReal>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayFloat4::Type())
|
|
vlx = export_ArrayT<vl::ArrayFloat4, VLXArrayReal>(s, obj);
|
|
else
|
|
|
|
if(obj->classType() == vl::ArrayDouble1::Type())
|
|
vlx = export_ArrayT<vl::ArrayDouble1, VLXArrayReal>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayDouble2::Type())
|
|
vlx = export_ArrayT<vl::ArrayDouble2, VLXArrayReal>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayDouble3::Type())
|
|
vlx = export_ArrayT<vl::ArrayDouble3, VLXArrayReal>(s, obj);
|
|
else
|
|
if(obj->classType() == vl::ArrayDouble4::Type())
|
|
vlx = export_ArrayT<vl::ArrayDouble4, VLXArrayReal>(s, obj);
|
|
else
|
|
{
|
|
s.signalExportError("Array type not supported for export.\n");
|
|
}
|
|
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Renderable */
|
|
struct VLXClassWrapper_Renderable: public ClassWrapper
|
|
{
|
|
virtual void exportRenderable(const vl::Renderable* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "BufferObjectEnabled" << obj->isBufferObjectEnabled();
|
|
*vlx << "DisplayListEnabled" << obj->isDisplayListEnabled();
|
|
if (!obj->boundsDirty())
|
|
{
|
|
*vlx << "AABB" << export_AABB(obj->boundingBox());
|
|
*vlx << "Sphere" << export_Sphere(obj->boundingSphere());
|
|
}
|
|
else
|
|
vl::Log::debug("VLXClassWrapper_Renderable : skipping dirty bounds.\n");
|
|
}
|
|
|
|
void importRenderable(const VLXStructure* vlx, vl::Renderable* ren)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
ren->setObjectName( name->getString() );
|
|
|
|
const std::vector<VLXStructure::KeyValue>& values = vlx->value();
|
|
for(size_t i=0; i<values.size(); ++i)
|
|
{
|
|
const std::string& key = values[i].key();
|
|
if (key == "BufferObjectEnabled")
|
|
{
|
|
ren->setBufferObjectEnabled( values[i].value().getBool() );
|
|
}
|
|
else
|
|
if (key == "DisplayListEnabled")
|
|
{
|
|
ren->setDisplayListEnabled( values[i].value().getBool() );
|
|
}
|
|
else
|
|
if (key == "AABB")
|
|
{
|
|
ren->setBoundingBox( import_AABB(values[i].value().getStructure()) );
|
|
}
|
|
else
|
|
if (key == "Sphere")
|
|
{
|
|
ren->setBoundingSphere( import_Sphere(values[i].value().getStructure()) );
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Geometry */
|
|
struct VLXClassWrapper_Geometry: public VLXClassWrapper_Renderable
|
|
{
|
|
void importGeometry(VLXSerializer& s, const VLXStructure* vlx, vl::Geometry* geom)
|
|
{
|
|
VLXClassWrapper_Renderable::importRenderable(vlx, geom);
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
|
|
if (key == "VertexArray")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if (arr)
|
|
geom->setVertexArray(arr);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (key == "NormalArray")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if (arr)
|
|
geom->setNormalArray(arr);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (key == "ColorArray")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if (arr)
|
|
geom->setColorArray(arr);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (key == "SecondaryColorArray")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if (arr)
|
|
geom->setSecondaryColorArray(arr);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (key == "FogCoordArray")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if (arr)
|
|
geom->setFogCoordArray(arr);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (strstr(key.c_str(), "TexCoordArray") == key.c_str())
|
|
{
|
|
const char* ch = key.c_str() + 13/*strlen("TexCoordArray")*/;
|
|
int tex_unit = 0;
|
|
for(; *ch; ++ch)
|
|
{
|
|
if (*ch>='0' && *ch<='9')
|
|
tex_unit = tex_unit*10 + (*ch - '0');
|
|
else
|
|
{
|
|
vl::Log::error( vl::Say("Line %n : error. ") << value.lineNumber() );
|
|
vl::Log::error( "TexCoordArray must end with a number!\n" );
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
}
|
|
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::ArrayAbstract* arr = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if (arr)
|
|
geom->setTexCoordArray(tex_unit, arr);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (strstr(key.c_str(), "VertexAttribArray") == key.c_str())
|
|
{
|
|
// MIC FIXME
|
|
//const char* ch = key.c_str() + 17/*strlen("VertexAttribArray")*/;
|
|
//int attrib_location = 0;
|
|
//for(; *ch; ++ch)
|
|
//{
|
|
// if (*ch>='0' && *ch<='9')
|
|
// attrib_location = attrib_location*10 + (*ch - '0');
|
|
// else
|
|
// {
|
|
// vl::Log::error( vl::Say("Line %n : error. ") << value.lineNumber() );
|
|
// vl::Log::error( "VertexAttribArray must end with a number!\n" );
|
|
// s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
// }
|
|
//}
|
|
|
|
//VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
//VertexAttribInfo* info_ptr = s.importVLX(value.getStructure())->as<vl::VertexAttribInfo>();
|
|
//if (info_ptr)
|
|
//{
|
|
// VertexAttribInfo info = *info_ptr;
|
|
// info.setAttribLocation(attrib_location);
|
|
// geom->setVertexAttribArray(info);
|
|
//}
|
|
//else
|
|
// s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
else
|
|
if (key == "DrawCall")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(value.type() == VLXValue::Structure, value)
|
|
vl::DrawCall* draw_call = s.importVLX(value.getStructure())->as<vl::DrawCall>();
|
|
if (draw_call)
|
|
geom->drawCalls().push_back(draw_call);
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Geometry> geom = new vl::Geometry;
|
|
// registration must be done here to avoid loops
|
|
s.registerImportedStructure(vlx, geom.get());
|
|
importGeometry(s, vlx, geom.get());
|
|
return geom;
|
|
}
|
|
|
|
void exportGeometry(VLXSerializer& s, const vl::Geometry* geom, VLXStructure* vlx)
|
|
{
|
|
// vl::Renderable
|
|
VLXClassWrapper_Renderable::exportRenderable(geom, vlx);
|
|
|
|
// vl::Geometry
|
|
if (geom->vertexArray())
|
|
*vlx << "VertexArray" << s.exportVLX(geom->vertexArray());
|
|
|
|
if (geom->normalArray())
|
|
*vlx << "NormalArray" << s.exportVLX(geom->normalArray());
|
|
|
|
if (geom->colorArray())
|
|
*vlx << "ColorArray" << s.exportVLX(geom->colorArray());
|
|
|
|
if (geom->secondaryColorArray())
|
|
*vlx << "SecondaryColorArray" << s.exportVLX(geom->secondaryColorArray());
|
|
|
|
if (geom->fogCoordArray())
|
|
*vlx << "FogCoordArray" << s.exportVLX(geom->fogCoordArray());
|
|
|
|
for( int i=0; i<vl::VA_MaxTexCoordCount; ++i)
|
|
{
|
|
if (geom->texCoordArray(i))
|
|
{
|
|
std::string tex_coord_array = vl::String::printf("TexCoordArray%d", i).toStdString();
|
|
*vlx << tex_coord_array.c_str() << s.exportVLX(geom->texCoordArray(i));
|
|
}
|
|
}
|
|
|
|
// MIC FIXME: unify with above
|
|
//for(size_t i=0; i<VA_MaxAttribCount; ++i)
|
|
//{
|
|
// if (geom->vertexAttribArray(i))
|
|
// {
|
|
// std::string vertex_attrib_array = vl::String::printf("VertexAttribArray%d", i).toStdString();
|
|
// *vlx << vertex_attrib_array.c_str() << s.exportVLX(geom->vertexAttribArray(i));
|
|
// }
|
|
//}
|
|
|
|
for(int i=0; i<geom->drawCalls().size(); ++i) {
|
|
*vlx << "DrawCall" << s.exportVLX(geom->drawCalls().at(i));
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Geometry* cast_obj = obj->as<vl::Geometry>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("geometry_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportGeometry(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::DrawCall and subclasses. */
|
|
struct VLXClassWrapper_DrawCall: public ClassWrapper
|
|
{
|
|
void importDrawCall(VLXSerializer& s, const VLXStructure* vlx, vl::DrawCall* draw_call)
|
|
{
|
|
if(draw_call->isOfType(vl::DrawElementsBase::Type()))
|
|
{
|
|
vl::DrawElementsBase* de= draw_call->as<vl::DrawElementsBase>();
|
|
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
de->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if( key == "PrimitiveType" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value)
|
|
de->setPrimitiveType( vlx_EPrimitiveType( value, s ) );
|
|
VLX_IMPORT_CHECK_RETURN( de->primitiveType() != vl::PT_UNKNOWN , value);
|
|
}
|
|
else
|
|
if( key == "Enabled" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
|
|
de->setEnabled( value.getBool() );
|
|
}
|
|
else
|
|
if( key == "Instances" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
|
|
de->setInstances( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if( key == "PrimitiveRestartEnabled" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
|
|
de->setPrimitiveRestartEnabled( value.getBool() );
|
|
}
|
|
else
|
|
if( key == "BaseVertex" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
|
|
de->setBaseVertex( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if( key == "IndexBuffer" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure , value)
|
|
vl::ArrayAbstract* arr_abstract = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if(!arr_abstract)
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
|
|
if ( de->isOfType(vl::DrawElementsUInt::Type()) )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUInt1::Type(), value);
|
|
de->as<vl::DrawElementsUInt>()->setIndexBuffer( arr_abstract->as<vl::ArrayUInt1>() );
|
|
}
|
|
else
|
|
if ( de->isOfType(vl::DrawElementsUShort::Type()) )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUShort1::Type(), value);
|
|
de->as<vl::DrawElementsUShort>()->setIndexBuffer( arr_abstract->as<vl::ArrayUShort1>() );
|
|
}
|
|
else
|
|
if ( de->isOfType(vl::DrawElementsUByte::Type()) )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUByte1::Type(), value);
|
|
de->as<vl::DrawElementsUByte>()->setIndexBuffer( arr_abstract->as<vl::ArrayUByte1>() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if(draw_call->isOfType(vl::MultiDrawElementsBase::Type()))
|
|
{
|
|
vl::MultiDrawElementsBase* de = draw_call->as<vl::MultiDrawElementsBase>();
|
|
|
|
VL_CHECK(de)
|
|
VL_CHECK(draw_call)
|
|
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
de->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if( key == "PrimitiveType" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value)
|
|
de->setPrimitiveType( vlx_EPrimitiveType( value, s ) );
|
|
VLX_IMPORT_CHECK_RETURN( de->primitiveType() != vl::PT_UNKNOWN , value);
|
|
}
|
|
else
|
|
if( key == "Enabled" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
|
|
de->setEnabled( value.getBool() );
|
|
}
|
|
else
|
|
if( key == "PrimitiveRestartEnabled" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
|
|
de->setPrimitiveRestartEnabled( value.getBool() );
|
|
}
|
|
else
|
|
if( key == "BaseVertices" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger , value)
|
|
de->baseVertices().resize( value.getArrayInteger()->value().size() );
|
|
if (de->baseVertices().size())
|
|
value.getArrayInteger()->copyTo( &de->baseVertices()[0] );
|
|
// de->setBaseVertices( value.getArrayInt32()->value() );
|
|
}
|
|
else
|
|
if( key == "CountVector" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger , value)
|
|
de->countVector().resize( value.getArrayInteger()->value().size() );
|
|
if (de->countVector().size())
|
|
value.getArrayInteger()->copyTo( &de->countVector()[0] );
|
|
// de->countVector() = value.getArrayInt32()->value();
|
|
}
|
|
else
|
|
if( key == "IndexBuffer" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure , value)
|
|
vl::ArrayAbstract* arr_abstract = s.importVLX(value.getStructure())->as<vl::ArrayAbstract>();
|
|
if( !arr_abstract )
|
|
s.signalImportError( vl::Say("Line %n : import error.\n") << value.lineNumber() );
|
|
|
|
if ( de->isOfType(vl::MultiDrawElementsUInt::Type()) )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUInt1::Type(), value);
|
|
de->as<vl::MultiDrawElementsUInt>()->setIndexBuffer( arr_abstract->as<vl::ArrayUInt1>() );
|
|
}
|
|
else
|
|
if ( de->isOfType(vl::MultiDrawElementsUShort::Type()) )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUShort1::Type(), value);
|
|
de->as<vl::MultiDrawElementsUShort>()->setIndexBuffer( arr_abstract->as<vl::ArrayUShort1>() );
|
|
}
|
|
else
|
|
if ( de->isOfType(vl::MultiDrawElementsUByte::Type()) )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(arr_abstract->classType() == vl::ArrayUByte1::Type(), value);
|
|
de->as<vl::MultiDrawElementsUByte>()->setIndexBuffer( arr_abstract->as<vl::ArrayUByte1>() );
|
|
}
|
|
}
|
|
}
|
|
|
|
// finalize setup
|
|
de->computePointerVector();
|
|
de->computeBufferObjectPointerVector();
|
|
if ( de->baseVertices().size() != de->countVector().size() )
|
|
de->baseVertices().resize( de->countVector().size() );
|
|
}
|
|
else
|
|
if( draw_call->isOfType(vl::DrawArrays::Type()) )
|
|
{
|
|
vl::ref<vl::DrawArrays> da = draw_call->as<vl::DrawArrays>();
|
|
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
da->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
|
|
if( key == "PrimitiveType" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier , value)
|
|
da->setPrimitiveType( vlx_EPrimitiveType( value, s ) );
|
|
VLX_IMPORT_CHECK_RETURN( da->primitiveType() != vl::PT_UNKNOWN , value);
|
|
}
|
|
else
|
|
if( key == "Enabled" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool , value)
|
|
da->setEnabled( value.getBool() );
|
|
}
|
|
else
|
|
if( key == "Instances" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
|
|
da->setInstances( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if( key == "Start" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
|
|
da->setStart( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if( key == "Count" )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer , value)
|
|
da->setCount( (int)value.getInteger() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::DrawCall> dc;
|
|
if (vlx->tag() == "<vl::DrawElementsUInt>")
|
|
dc = new vl::DrawElementsUInt;
|
|
else
|
|
if (vlx->tag() == "<vl::DrawElementsUShort>")
|
|
dc = new vl::DrawElementsUShort;
|
|
else
|
|
if (vlx->tag() == "<vl::DrawElementsUByte>")
|
|
dc = new vl::DrawElementsUByte;
|
|
else
|
|
if (vlx->tag() == "<vl::MultiDrawElementsUInt>")
|
|
dc = new vl::MultiDrawElementsUInt;
|
|
else
|
|
if (vlx->tag() == "<vl::MultiDrawElementsUShort>")
|
|
dc = new vl::MultiDrawElementsUShort;
|
|
else
|
|
if (vlx->tag() == "<vl::MultiDrawElementsUByte>")
|
|
dc = new vl::MultiDrawElementsUByte;
|
|
else
|
|
if (vlx->tag() == "<vl::DrawArrays>")
|
|
dc = new vl::DrawArrays;
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : error. Unknown draw call.\n") << vlx->lineNumber() );
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, dc.get());
|
|
importDrawCall(s, vlx, dc.get());
|
|
return dc;
|
|
}
|
|
|
|
void exportDrawCallBase(VLXSerializer& s, const vl::DrawCall* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "PrimitiveType" << vlx_Identifier(vlx_EPrimitiveType(obj->primitiveType()));
|
|
*vlx << "Enabled" << obj->isEnabled();
|
|
if (obj->patchParameter())
|
|
*vlx << "PatchParameter" << s.exportVLX(obj->patchParameter());
|
|
}
|
|
|
|
void exportDrawCall(VLXSerializer& s, const vl::DrawCall* dcall, VLXStructure* vlx)
|
|
{
|
|
exportDrawCallBase(s, dcall, vlx);
|
|
|
|
if (dcall->isOfType(vl::DrawArrays::Type()))
|
|
{
|
|
const vl::DrawArrays* da = dcall->as<vl::DrawArrays>();
|
|
*vlx << "Instances" << (long long)da->instances();
|
|
*vlx << "Start" << (long long)da->start();
|
|
*vlx << "Count" << (long long)da->count();
|
|
}
|
|
else
|
|
if (dcall->isOfType(vl::DrawElementsUInt::Type()))
|
|
{
|
|
const vl::DrawElementsUInt* de = dcall->as<vl::DrawElementsUInt>();
|
|
*vlx << "Instances" << (long long)de->instances();
|
|
*vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
|
|
*vlx << "BaseVertex" << (long long)de->baseVertex();
|
|
*vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
|
|
}
|
|
else
|
|
if (dcall->isOfType(vl::DrawElementsUShort::Type()))
|
|
{
|
|
const vl::DrawElementsUShort* de = dcall->as<vl::DrawElementsUShort>();
|
|
*vlx << "Instances" << (long long)de->instances();
|
|
*vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
|
|
*vlx << "BaseVertex" << (long long)de->baseVertex();
|
|
*vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
|
|
}
|
|
else
|
|
if (dcall->isOfType(vl::DrawElementsUByte::Type()))
|
|
{
|
|
const vl::DrawElementsUByte* de = dcall->as<vl::DrawElementsUByte>();
|
|
*vlx << "Instances" << (long long)de->instances();
|
|
*vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
|
|
*vlx << "BaseVertex" << (long long)de->baseVertex();
|
|
*vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
|
|
}
|
|
else
|
|
if (dcall->isOfType(vl::MultiDrawElementsUInt::Type()))
|
|
{
|
|
const vl::MultiDrawElementsUInt* de = dcall->as<vl::MultiDrawElementsUInt>();
|
|
*vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
|
|
*vlx << "BaseVertices" << vlx_toValue(de->baseVertices());
|
|
*vlx << "CountVector" << vlx_toValue(de->countVector());
|
|
*vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
|
|
}
|
|
else
|
|
if (dcall->isOfType(vl::MultiDrawElementsUShort::Type()))
|
|
{
|
|
const vl::MultiDrawElementsUShort* de = dcall->as<vl::MultiDrawElementsUShort>();
|
|
*vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
|
|
*vlx << "BaseVertices" << vlx_toValue(de->baseVertices());
|
|
*vlx << "CountVector" << vlx_toValue(de->countVector());
|
|
*vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
|
|
}
|
|
else
|
|
if (dcall->isOfType(vl::MultiDrawElementsUByte::Type()))
|
|
{
|
|
const vl::MultiDrawElementsUByte* de = dcall->as<vl::MultiDrawElementsUByte>();
|
|
*vlx << "PrimitiveRestartEnabled" << de->primitiveRestartEnabled();
|
|
*vlx << "BaseVertices" << vlx_toValue(de->baseVertices());
|
|
*vlx << "CountVector" << vlx_toValue(de->countVector());
|
|
*vlx << "IndexBuffer" << s.exportVLX(de->indexBuffer());
|
|
}
|
|
else
|
|
{
|
|
vl::Log::error("vl::DrawCall type not supported for export.\n");
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::DrawCall* cast_obj = obj->as<vl::DrawCall>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("drawcall_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportDrawCall(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::PatchParameter */
|
|
struct VLXClassWrapper_PatchParameter: public ClassWrapper
|
|
{
|
|
void importPatchParameter(const VLXStructure* vlx, vl::PatchParameter* pp)
|
|
{
|
|
std::vector<VLXStructure::KeyValue> values = vlx->value();
|
|
for(size_t i=0; i<values.size(); ++i)
|
|
{
|
|
const std::string& key = values[i].key();
|
|
if (key == "PatchVertices")
|
|
{
|
|
pp->setPatchVertices( (int)values[i].value().getInteger() );
|
|
}
|
|
else
|
|
if (key == "PatchDefaultOuterLevel")
|
|
{
|
|
pp->setPatchDefaultOuterLevel( (vl::fvec4)vlx_vec4(values[i].value().getArrayReal()) );
|
|
}
|
|
else
|
|
if (key == "PatchDefaultInnerLevel")
|
|
{
|
|
pp->setPatchDefaultInnerLevel( (vl::fvec2)vlx_vec2(values[i].value().getArrayReal()) );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::PatchParameter> pp = new vl::PatchParameter;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, pp.get());
|
|
importPatchParameter(vlx, pp.get());
|
|
return pp;
|
|
}
|
|
|
|
void exportPatchParameter(const vl::PatchParameter* pp, VLXStructure* vlx)
|
|
{
|
|
*vlx << "PatchVertices" << (long long)pp->patchVertices();
|
|
*vlx << "PatchDefaultOuterLevel" << vlx_toValue((vl::vec4)pp->patchDefaultOuterLevel());
|
|
*vlx << "PatchDefaultInnerLevel" << vlx_toValue((vl::vec2)pp->patchDefaultInnerLevel());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::PatchParameter* cast_obj = obj->as<vl::PatchParameter>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("patchparam_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportPatchParameter(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::ResourceDatabase */
|
|
struct VLXClassWrapper_ResourceDatabase: public ClassWrapper
|
|
{
|
|
void importResourceDatabase(VLXSerializer& s, const VLXStructure* vlx, vl::ResourceDatabase* resdb)
|
|
{
|
|
const VLXValue* vlx_obj_name = vlx->getValue("ObjectName");
|
|
if (vlx_obj_name)
|
|
resdb->setObjectName( vlx_obj_name->getString() );
|
|
|
|
const VLXValue* vlx_res = vlx->getValue("Resources");
|
|
if (vlx_res)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( vlx_res->type() == VLXValue::List, *vlx_res );
|
|
// get the list
|
|
const VLXList* list = vlx_res->getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
const VLXValue& value = list->value()[i];
|
|
|
|
// the member of this list must be all structures.
|
|
|
|
if (value.type() != VLXValue::Structure)
|
|
{
|
|
s.signalImportError( vl::Say("Line %n : structure expected.\n") << value.lineNumber() );
|
|
return;
|
|
}
|
|
|
|
resdb->resources().push_back( s.importVLX(value.getStructure()) );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::ResourceDatabase> resdb = new vl::ResourceDatabase;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, resdb.get());
|
|
importResourceDatabase(s, vlx, resdb.get());
|
|
return resdb;
|
|
}
|
|
|
|
void exportResourceDatabase(VLXSerializer& s, const vl::ResourceDatabase* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
vl::ref<VLXList> list = new VLXList;
|
|
*vlx << "Resources" << list.get();
|
|
|
|
for(size_t i=0; i<obj->resources().size(); ++i)
|
|
{
|
|
if ( !s.canExport(obj->resources().at(i).get()) )
|
|
{
|
|
vl::Log::debug( vl::Say("VLXClassWrapper_ResourceDatabase : skipping '%s'.\n") << obj->resources().at(i).get()->className() );
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
*list << s.exportVLX(obj->resources().at(i).get());
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::ResourceDatabase* cast_obj = obj->as<vl::ResourceDatabase>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("resdb_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportResourceDatabase(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Uniform */
|
|
struct VLXClassWrapper_Uniform: public ClassWrapper
|
|
{
|
|
void importUniform(VLXSerializer& s, const VLXStructure* vlx, vl::Uniform* uniform)
|
|
{
|
|
const VLXValue* val = vlx->getValue("Name");
|
|
if (val)
|
|
{
|
|
VL_CHECK( val->type() == VLXValue::Identifier );
|
|
uniform->setName( val->getIdentifier() );
|
|
}
|
|
else
|
|
{
|
|
s.signalImportError( vl::Say("Line %d : uniform without 'Name'.\n") << vlx->lineNumber() );
|
|
return;
|
|
}
|
|
|
|
// 'Count' is optional
|
|
int count = 1;
|
|
val = vlx->getValue("Count");
|
|
if (val)
|
|
{
|
|
VL_CHECK( val->type() == VLXValue::Integer );
|
|
count = (int)val->getInteger();
|
|
}
|
|
|
|
vl::EUniformType type = vl::UT_NONE;
|
|
val = vlx->getValue("Type");
|
|
if (val)
|
|
{
|
|
VL_CHECK( val->type() == VLXValue::Identifier );
|
|
type = vlx_EUniformType( *val, s );
|
|
}
|
|
else
|
|
{
|
|
s.signalImportError( vl::Say("Line %d : uniform without 'Type'.\n") << vlx->lineNumber() );
|
|
return;
|
|
}
|
|
|
|
val = vlx->getValue("Data");
|
|
const VLXArrayReal* arr_real = NULL;
|
|
const VLXArrayInteger* arr_int = NULL;
|
|
if (!val)
|
|
{
|
|
s.signalImportError( vl::Say("Line %d : uniform without 'Data'.\n") << vlx->lineNumber() );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (val->type() == VLXValue::ArrayReal)
|
|
arr_real = val->getArrayReal();
|
|
else
|
|
if (val->type() == VLXValue::ArrayInteger)
|
|
arr_int = val->getArrayInteger();
|
|
}
|
|
|
|
std::vector<int> int_vec;
|
|
std::vector<unsigned int> uint_vec;
|
|
std::vector<float> float_vec;
|
|
std::vector<double> double_vec;
|
|
|
|
switch(type)
|
|
{
|
|
case vl::UT_INT:
|
|
int_vec.resize(count*1); if (arr_int) arr_int->copyTo(&int_vec[0]); else int_vec[0] = (int)val->getInteger();
|
|
uniform->setUniform1i(count, &int_vec[0]);
|
|
break;
|
|
case vl::UT_INT_VEC2:
|
|
int_vec.resize(count*2); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val);
|
|
uniform->setUniform2i(count, &int_vec[0]);
|
|
break;
|
|
case vl::UT_INT_VEC3:
|
|
int_vec.resize(count*3); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val);
|
|
uniform->setUniform3i(count, &int_vec[0]);
|
|
break;
|
|
case vl::UT_INT_VEC4:
|
|
int_vec.resize(count*4); arr_int->copyTo(&int_vec[0]); VLX_IMPORT_CHECK_RETURN(int_vec.size() == arr_int->value().size(), *val);
|
|
uniform->setUniform4i(count, &int_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_UNSIGNED_INT:
|
|
uint_vec.resize(count*1); if (arr_int) arr_int->copyTo(&uint_vec[0]); else uint_vec[0] = (unsigned int)val->getInteger();
|
|
uniform->setUniform1ui(count, &uint_vec[0]);
|
|
break;
|
|
case vl::UT_UNSIGNED_INT_VEC2:
|
|
uint_vec.resize(count*2); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val);
|
|
uniform->setUniform2ui(count, &uint_vec[0]);
|
|
break;
|
|
case vl::UT_UNSIGNED_INT_VEC3:
|
|
uint_vec.resize(count*3); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val);
|
|
uniform->setUniform3ui(count, &uint_vec[0]);
|
|
break;
|
|
case vl::UT_UNSIGNED_INT_VEC4:
|
|
uint_vec.resize(count*4); arr_int->copyTo(&uint_vec[0]); VLX_IMPORT_CHECK_RETURN(uint_vec.size() == arr_int->value().size(), *val);
|
|
uniform->setUniform4ui(count, &uint_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_FLOAT:
|
|
float_vec.resize(count*1); if (arr_real) arr_real->copyTo(&float_vec[0]); else float_vec[0] = (float)val->getReal();
|
|
uniform->setUniform1f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_VEC2:
|
|
float_vec.resize(count*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniform2f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_VEC3:
|
|
float_vec.resize(count*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniform3f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_VEC4:
|
|
float_vec.resize(count*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniform4f(count, &float_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_FLOAT_MAT2:
|
|
float_vec.resize(count*2*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix2f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT3:
|
|
float_vec.resize(count*3*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix3f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT4:
|
|
float_vec.resize(count*4*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix4f(count, &float_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_FLOAT_MAT2x3:
|
|
float_vec.resize(count*2*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix2x3f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT3x2:
|
|
float_vec.resize(count*3*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix3x2f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT2x4:
|
|
float_vec.resize(count*2*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix2x4f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT4x2:
|
|
float_vec.resize(count*4*2); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix4x2f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT3x4:
|
|
float_vec.resize(count*3*4); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix3x4f(count, &float_vec[0]);
|
|
break;
|
|
case vl::UT_FLOAT_MAT4x3:
|
|
float_vec.resize(count*4*3); arr_real->copyTo(&float_vec[0]); VLX_IMPORT_CHECK_RETURN(float_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix4x3f(count, &float_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_DOUBLE:
|
|
double_vec.resize(count*1); if (arr_real) arr_real->copyTo(&double_vec[0]); else double_vec[0] = (double)val->getReal();
|
|
uniform->setUniform1d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_VEC2:
|
|
double_vec.resize(count*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniform2d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_VEC3:
|
|
double_vec.resize(count*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniform3d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_VEC4:
|
|
double_vec.resize(count*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniform4d(count, &double_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_DOUBLE_MAT2:
|
|
double_vec.resize(count*2*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix2d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT3:
|
|
double_vec.resize(count*3*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix3d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT4:
|
|
double_vec.resize(count*4*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix4d(count, &double_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_DOUBLE_MAT2x3:
|
|
double_vec.resize(count*2*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix2x3d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT3x2:
|
|
double_vec.resize(count*3*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix3x2d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT2x4:
|
|
double_vec.resize(count*2*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix2x4d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT4x2:
|
|
double_vec.resize(count*4*2); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix4x2d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT3x4:
|
|
double_vec.resize(count*3*4); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix3x4d(count, &double_vec[0]);
|
|
break;
|
|
case vl::UT_DOUBLE_MAT4x3:
|
|
double_vec.resize(count*4*3); arr_real->copyTo(&double_vec[0]); VLX_IMPORT_CHECK_RETURN(double_vec.size() == arr_real->value().size(), *val);
|
|
uniform->setUniformMatrix4x3d(count, &double_vec[0]);
|
|
break;
|
|
|
|
case vl::UT_NONE:
|
|
vl::Log::error( vl::Say("Error importing uniform : uninitialized uniform (%s).\n") << uniform->name() );
|
|
break;
|
|
|
|
default:
|
|
vl::Log::error( vl::Say("Error importing uniform : illegal uniform type (%s).\n") << uniform->name() );
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Uniform> obj = new vl::Uniform;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importUniform(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportUniform(const vl::Uniform* uniform, VLXStructure* vlx)
|
|
{
|
|
*vlx << "Name" << vlx_Identifier(uniform->name());
|
|
*vlx << "Type" << vlx_Identifier(vlx_EUniformType(uniform->type()));
|
|
*vlx << "Count" << (long long)uniform->count();
|
|
|
|
const int count = uniform->count();
|
|
vl::ref<VLXArrayInteger> arr_int = new VLXArrayInteger;
|
|
vl::ref<VLXArrayReal> arr_real = new VLXArrayReal;
|
|
|
|
switch(uniform->type())
|
|
{
|
|
case vl::UT_INT:
|
|
{
|
|
if (count == 1)
|
|
{ int val = 0; uniform->getUniform(&val); *vlx << "Data" << (long long)val; break; }
|
|
else
|
|
{ arr_int->value().resize(count*1); arr_int->copyFrom( (int*)uniform->rawData() ); break; }
|
|
}
|
|
case vl::UT_INT_VEC2: arr_int->value().resize(count*2); arr_int->copyFrom( (int*)uniform->rawData() ); break;
|
|
case vl::UT_INT_VEC3: arr_int->value().resize(count*3); arr_int->copyFrom( (int*)uniform->rawData() ); break;
|
|
case vl::UT_INT_VEC4: arr_int->value().resize(count*4); arr_int->copyFrom( (int*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_UNSIGNED_INT:
|
|
{
|
|
if (count == 1)
|
|
{ unsigned int val = 0; uniform->getUniform(&val); *vlx << "Data" << (long long)val; break; }
|
|
else
|
|
{ arr_int->value().resize(count*1); arr_int->copyFrom( (int*)uniform->rawData() ); break; }
|
|
}
|
|
case vl::UT_UNSIGNED_INT_VEC2: arr_int->value().resize(count*2); arr_int->copyFrom( (int*)uniform->rawData() ); break;
|
|
case vl::UT_UNSIGNED_INT_VEC3: arr_int->value().resize(count*3); arr_int->copyFrom( (int*)uniform->rawData() ); break;
|
|
case vl::UT_UNSIGNED_INT_VEC4: arr_int->value().resize(count*4); arr_int->copyFrom( (int*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_FLOAT:
|
|
{
|
|
if (count == 1)
|
|
{ float val = 0; uniform->getUniform(&val); *vlx << "Data" << (double)val; break; }
|
|
else
|
|
{ arr_real->value().resize(count*1); arr_real->copyFrom( (float*)uniform->rawData() ); break; }
|
|
}
|
|
case vl::UT_FLOAT_VEC2: arr_real->value().resize(count*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_VEC3: arr_real->value().resize(count*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_VEC4: arr_real->value().resize(count*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_FLOAT_MAT2: arr_real->value().resize(count*2*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT3: arr_real->value().resize(count*3*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT4: arr_real->value().resize(count*4*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_FLOAT_MAT2x3: arr_real->value().resize(count*2*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT3x2: arr_real->value().resize(count*3*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT2x4: arr_real->value().resize(count*2*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT4x2: arr_real->value().resize(count*4*2); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT3x4: arr_real->value().resize(count*3*4); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
case vl::UT_FLOAT_MAT4x3: arr_real->value().resize(count*4*3); arr_real->copyFrom( (float*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_DOUBLE:
|
|
{
|
|
if (count == 1)
|
|
{ double val = 0; uniform->getUniform(&val); *vlx << "Data" << (double)val; break; }
|
|
else
|
|
{ arr_real->value().resize(count*1); arr_real->copyFrom( (double*)uniform->rawData() ); break; }
|
|
}
|
|
case vl::UT_DOUBLE_VEC2: arr_real->value().resize(count*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_VEC3: arr_real->value().resize(count*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_VEC4: arr_real->value().resize(count*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_DOUBLE_MAT2: arr_real->value().resize(count*2*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT3: arr_real->value().resize(count*3*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT4: arr_real->value().resize(count*4*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_DOUBLE_MAT2x3: arr_real->value().resize(count*2*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT3x2: arr_real->value().resize(count*3*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT2x4: arr_real->value().resize(count*2*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT4x2: arr_real->value().resize(count*4*2); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT3x4: arr_real->value().resize(count*3*4); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
case vl::UT_DOUBLE_MAT4x3: arr_real->value().resize(count*4*3); arr_real->copyFrom( (double*)uniform->rawData() ); break;
|
|
|
|
case vl::UT_NONE:
|
|
vl::Log::error( vl::Say("Error exporting uniform : uninitialized uniform (%s).\n") << uniform->name() );
|
|
break;
|
|
|
|
default:
|
|
vl::Log::error( vl::Say("Error exporting uniform : illegal uniform type (%s).\n") << uniform->name() );
|
|
break;
|
|
}
|
|
|
|
if (!arr_int->value().empty())
|
|
*vlx << "Data" << arr_int.get();
|
|
else
|
|
if (!arr_real->value().empty())
|
|
*vlx << "Data" << arr_real.get();
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Uniform* cast_obj = obj->as<vl::Uniform>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("uniform_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportUniform(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Shader */
|
|
struct VLXClassWrapper_Shader: public ClassWrapper
|
|
{
|
|
void importShader(VLXSerializer& s, const VLXStructure* vlx, vl::Shader* sh)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
sh->setObjectName( name->getString() );
|
|
|
|
// enables
|
|
const VLXValue* enables = vlx->getValue("Enables");
|
|
if (enables)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( enables->type() == VLXValue::List, *enables )
|
|
const VLXList* list = enables->getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Identifier, list->value()[i] );
|
|
vl::EEnable en = vlx_EEnable( list->value()[i], s );
|
|
VLX_IMPORT_CHECK_RETURN( en != vl::EN_UnknownEnable, list->value()[i] );
|
|
sh->enable(en);
|
|
}
|
|
}
|
|
|
|
// render states
|
|
const VLXValue* renderstates = vlx->getValue("RenderStates");
|
|
if (renderstates)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( renderstates->type() == VLXValue::List, *renderstates )
|
|
const VLXList* list = renderstates->getList();
|
|
int index = -1;
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure || list->value()[i].type() == VLXValue::Integer, list->value()[i] );
|
|
if (list->value()[i].type() == VLXValue::Integer)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( index == -1, list->value()[i] );
|
|
index = (int)list->value()[i].getInteger();
|
|
}
|
|
else
|
|
{
|
|
vl::RenderState* renderstate = s.importVLX( list->value()[i].getStructure() )->as<vl::RenderState>();
|
|
VLX_IMPORT_CHECK_RETURN( renderstate != NULL, list->value()[i] )
|
|
VLX_IMPORT_CHECK_RETURN( (index == -1 && !renderstate->isOfType(vl::RenderStateIndexed::Type())) || (index >= 0 && renderstate->isOfType(vl::RenderStateIndexed::Type())), list->value()[i] )
|
|
sh->setRenderState(renderstate, index);
|
|
// consume index in any case
|
|
index = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// uniforms
|
|
const VLXValue* uniforms = vlx->getValue("Uniforms");
|
|
if (uniforms)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( uniforms->type() == VLXValue::List, *uniforms )
|
|
const VLXList* list = uniforms->getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] );
|
|
vl::Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as<vl::Uniform>();
|
|
VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] )
|
|
sh->setUniform(uniform);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Shader> obj = new vl::Shader;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importShader(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportShader(VLXSerializer& s, const vl::Shader* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
|
|
// uniforms
|
|
VLXValue uniforms;
|
|
uniforms.setList( new VLXList );
|
|
if (obj->getUniformSet())
|
|
{
|
|
for(size_t i=0; i<obj->uniforms().size(); ++i)
|
|
*uniforms.getList() << s.exportVLX(obj->uniforms()[i].get());
|
|
}
|
|
*vlx << "Uniforms" << uniforms;
|
|
|
|
// enables
|
|
vl::ref<VLXList> enables = new VLXList;
|
|
if (obj->getEnableSet() )
|
|
{
|
|
for(size_t i=0; i<obj->getEnableSet()->enables().size(); ++i)
|
|
*enables << vlx_Identifier(vlx_EEnable(obj->getEnableSet()->enables()[i]));
|
|
}
|
|
*vlx << "Enables" << enables.get();
|
|
|
|
// renderstates
|
|
VLXValue renderstates;
|
|
renderstates.setList( new VLXList );
|
|
if (obj->getRenderStateSet())
|
|
{
|
|
for(size_t i=0; i<obj->getRenderStateSet()->renderStatesCount(); ++i)
|
|
{
|
|
const vl::RenderState* rs = obj->getRenderStateSet()->renderStates()[i].mRS.get();
|
|
if ( !s.canExport(rs) )
|
|
{
|
|
vl::Log::debug( vl::Say("VLXClassWrapper_Shader : skipping '%s'.\n") << rs->className() );
|
|
continue;
|
|
}
|
|
int index = obj->getRenderStateSet()->renderStates()[i].mIndex;
|
|
if (index != -1)
|
|
*renderstates.getList() << (long long)index;
|
|
*renderstates.getList() << s.exportVLX(rs);
|
|
}
|
|
}
|
|
*vlx << "RenderStates" << renderstates;
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Shader* cast_obj = obj->as<vl::Shader>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("shader_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportShader(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::DistanceLODEvaluator and vl::PixelLODEvaluator */
|
|
struct VLXClassWrapper_LODEvaluator: public ClassWrapper
|
|
{
|
|
void importLODEvaluator(VLXSerializer& s, const VLXStructure* vlx, vl::LODEvaluator* obj)
|
|
{
|
|
if (obj->isOfType(vl::DistanceLODEvaluator::Type()))
|
|
{
|
|
vl::DistanceLODEvaluator* lod = obj->as<vl::DistanceLODEvaluator>();
|
|
const VLXValue* vlx_distances = vlx->getValue("DistanceRageSet");
|
|
VLX_IMPORT_CHECK_RETURN( vlx_distances != NULL, *vlx );
|
|
VLX_IMPORT_CHECK_RETURN( vlx_distances->type() == VLXValue::ArrayReal, *vlx_distances );
|
|
const VLXArrayReal* arr = vlx_distances->getArrayReal();
|
|
if (arr->value().size())
|
|
{
|
|
lod->distanceRangeSet().resize( arr->value().size() );
|
|
arr->copyTo( &lod->distanceRangeSet()[0] );
|
|
}
|
|
}
|
|
else
|
|
if (obj->isOfType(vl::PixelLODEvaluator::Type()))
|
|
{
|
|
vl::PixelLODEvaluator* lod = obj->as<vl::PixelLODEvaluator>();
|
|
const VLXValue* vlx_pixels = vlx->getValue("PixelRageSet");
|
|
VLX_IMPORT_CHECK_RETURN( vlx_pixels != NULL, *vlx );
|
|
VLX_IMPORT_CHECK_RETURN( vlx_pixels->type() == VLXValue::ArrayReal, *vlx_pixels );
|
|
const VLXArrayReal* arr = vlx_pixels->getArrayReal();
|
|
if (arr->value().size())
|
|
{
|
|
lod->pixelRangeSet().resize( arr->value().size() );
|
|
arr->copyTo( &lod->pixelRangeSet()[0] );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
if (vlx->tag() == "<vl::DistanceLODEvaluator>")
|
|
{
|
|
vl::ref<vl::LODEvaluator> obj = new vl::DistanceLODEvaluator;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importLODEvaluator(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
else
|
|
if (vlx->tag() == "<vl::PixelLODEvaluator>")
|
|
{
|
|
vl::ref<vl::LODEvaluator> obj = new vl::PixelLODEvaluator;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importLODEvaluator(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void exportLODEvaluator(VLXSerializer& s, const vl::LODEvaluator* obj, VLXStructure* vlx)
|
|
{
|
|
if (obj->classType() == vl::DistanceLODEvaluator::Type())
|
|
{
|
|
const vl::DistanceLODEvaluator* lod = obj->as<vl::DistanceLODEvaluator>();
|
|
VLXValue distances( new VLXArrayReal );
|
|
distances.getArrayReal()->value().resize( lod->distanceRangeSet().size() );
|
|
if (lod->distanceRangeSet().size() != 0)
|
|
distances.getArrayReal()->copyFrom( &lod->distanceRangeSet()[0] );
|
|
*vlx << "DistanceRageSet" << distances;
|
|
}
|
|
else
|
|
if (obj->classType() == vl::PixelLODEvaluator::Type())
|
|
{
|
|
const vl::PixelLODEvaluator* lod = obj->as<vl::PixelLODEvaluator>();
|
|
VLXValue pixels( new VLXArrayReal );
|
|
pixels.getArrayReal()->value().resize( lod->pixelRangeSet().size() );
|
|
if (lod->pixelRangeSet().size() != 0)
|
|
pixels.getArrayReal()->copyFrom( &lod->pixelRangeSet()[0] );
|
|
*vlx << "PixelRageSet" << pixels;
|
|
}
|
|
else
|
|
{
|
|
s.signalExportError("vl::LODEvaluator type not supported for export.\n");
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::LODEvaluator* cast_obj = obj->as<vl::LODEvaluator>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("lodeval_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportLODEvaluator(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Effect */
|
|
struct VLXClassWrapper_Effect: public ClassWrapper
|
|
{
|
|
void importEffect(VLXSerializer& s, const VLXStructure* vlx, vl::Effect* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
const std::vector<VLXStructure::KeyValue>& values = vlx->value();
|
|
for(size_t i=0; i<values.size(); ++i)
|
|
{
|
|
const std::string& key = values[i].key();
|
|
const VLXValue& value = values[i].value();
|
|
if (key == "RenderRank")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
|
|
obj->setRenderRank( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "EnableMask")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
|
|
obj->setEnableMask( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "ActiveLod")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
|
|
obj->setActiveLod( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "LODEvaluator")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
|
|
vl::LODEvaluator* lod_eval = s.importVLX( value.getStructure() )->as<vl::LODEvaluator>();
|
|
VLX_IMPORT_CHECK_RETURN( lod_eval, value )
|
|
obj->setLODEvaluator(lod_eval);
|
|
}
|
|
else
|
|
if (key == "Lods")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* lod_list = value.getList();
|
|
for(size_t ilod=0; ilod< lod_list->value().size(); ++ilod)
|
|
{
|
|
const VLXValue& lod_shaders = lod_list->value()[ilod];
|
|
VLX_IMPORT_CHECK_RETURN( lod_shaders.type() == VLXValue::List, lod_shaders )
|
|
obj->lod((int)ilod) = new vl::ShaderPasses;
|
|
for( size_t ish=0; ish<lod_shaders.getList()->value().size(); ++ish)
|
|
{
|
|
const VLXValue& vlx_sh = lod_shaders.getList()->value()[ish];
|
|
VLX_IMPORT_CHECK_RETURN( vlx_sh.type() == VLXValue::Structure, vlx_sh )
|
|
vl::Shader* shader = s.importVLX( vlx_sh.getStructure() )->as<vl::Shader>();
|
|
VLX_IMPORT_CHECK_RETURN( shader, vlx_sh )
|
|
obj->lod((int)ilod)->push_back( shader );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Effect> obj = new vl::Effect;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importEffect(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
VLXValue export_ShaderPasses(VLXSerializer& s, const vl::ShaderPasses* sh_seq)
|
|
{
|
|
VLXValue value( new VLXList(vlx_makeTag(sh_seq).c_str()) );
|
|
for(int i=0; i<sh_seq->size(); ++i)
|
|
*value.getList() << s.exportVLX(sh_seq->at(i));
|
|
return value;
|
|
}
|
|
|
|
void exportEffect(VLXSerializer& s, const vl::Effect* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "RenderRank" << (long long)obj->renderRank();
|
|
*vlx << "EnableMask" << (long long)obj->enableMask();
|
|
*vlx << "ActiveLod" << (long long)obj->activeLod();
|
|
|
|
if (obj->lodEvaluator())
|
|
*vlx << "LODEvaluator" << s.exportVLX(obj->lodEvaluator());
|
|
|
|
// shaders
|
|
vl::ref<VLXList> lod_list = new VLXList;
|
|
for(int i=0; obj->lod(i) && i<VL_MAX_EFFECT_LOD; ++i)
|
|
*lod_list << export_ShaderPasses(s, obj->lod(i).get());
|
|
*vlx << "Lods" << lod_list.get();
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Effect* cast_obj = obj->as<vl::Effect>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("effect_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportEffect(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Actor */
|
|
struct VLXClassWrapper_Actor: public ClassWrapper
|
|
{
|
|
void importActor(VLXSerializer& s, const VLXStructure* vlx, vl::Actor* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
const std::vector<VLXStructure::KeyValue>& values = vlx->value();
|
|
for(size_t i=0; i<values.size(); ++i)
|
|
{
|
|
const std::string& key = values[i].key();
|
|
const VLXValue& value = values[i].value();
|
|
if (key == "RenderRank")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
|
|
obj->setRenderRank( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "RenderBlock")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
|
|
obj->setRenderBlock( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "EnableMask")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value )
|
|
obj->setEnableMask( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "IsOccludee")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value )
|
|
obj->setOccludee( value.getBool() );
|
|
}
|
|
else
|
|
if (key == "Enabled")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value )
|
|
obj->setEnabled( value.getBool() );
|
|
}
|
|
else
|
|
if (key == "Lods")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* list = value.getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
const VLXValue& lod = list->value()[i];
|
|
VLX_IMPORT_CHECK_RETURN( lod.type() == VLXValue::Structure, lod )
|
|
vl::Renderable* rend = s.importVLX( lod.getStructure() )->as<vl::Renderable>();
|
|
VLX_IMPORT_CHECK_RETURN( rend != NULL, lod )
|
|
obj->setLod(i, rend);
|
|
}
|
|
}
|
|
else
|
|
if (key == "Effect")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
|
|
vl::Effect* fx = s.importVLX(value.getStructure())->as<vl::Effect>();
|
|
VLX_IMPORT_CHECK_RETURN( fx != NULL, value )
|
|
obj->setEffect(fx);
|
|
}
|
|
else
|
|
if (key == "Transform")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
|
|
vl::Transform* tr = s.importVLX(value.getStructure())->as<vl::Transform>();
|
|
VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
|
|
obj->setTransform(tr);
|
|
}
|
|
else
|
|
if (key == "Uniforms")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* list = value.getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] )
|
|
vl::Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as<vl::Uniform>();
|
|
VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] )
|
|
obj->setUniform(uniform);
|
|
}
|
|
}
|
|
// bounding volumes are not serialized, they are computed based on the geometry's bounds
|
|
// else if (key == "AABB") {}
|
|
// else if (key == "Sphere") {}
|
|
else
|
|
if (key == "LODEvaluator")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
|
|
if (s.canImport( value.getStructure() ) )
|
|
{
|
|
vl::LODEvaluator* lod = s.importVLX( value.getStructure() )->as<vl::LODEvaluator>();
|
|
VLX_IMPORT_CHECK_RETURN( lod != NULL, value )
|
|
obj->setLODEvaluator(lod);
|
|
}
|
|
}
|
|
else
|
|
if (key == "ActorEventCallbacks")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* list = value.getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
const VLXValue& elem = list->value()[i];
|
|
VLX_IMPORT_CHECK_RETURN( elem.type() == VLXValue::Structure, elem )
|
|
if (s.canImport(elem.getStructure()))
|
|
{
|
|
vl::ActorEventCallback* cb = s.importVLX( elem.getStructure() )->as<vl::ActorEventCallback>();
|
|
VLX_IMPORT_CHECK_RETURN( cb != NULL, elem )
|
|
obj->actorEventCallbacks()->push_back(cb);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Actor> obj = new vl::Actor;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importActor(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportActor(VLXSerializer& s, const vl::Actor* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "EnableMask" << (long long)obj->enableMask();
|
|
*vlx << "RenderBlock" << (long long)obj->renderBlock();
|
|
*vlx << "RenderRank" << (long long)obj->renderRank();
|
|
*vlx << "IsOccludee" << obj->isOccludee();
|
|
*vlx << "Enabled" << obj->isEnabled();
|
|
|
|
VLXValue renderables;
|
|
renderables.setList( new VLXList );
|
|
for(size_t i=0; i<VL_MAX_ACTOR_LOD && obj->lod(i); ++i)
|
|
*renderables.getList() << s.exportVLX(obj->lod(i));
|
|
*vlx << "Lods" << renderables;
|
|
|
|
// bounding volumes are not serialized, they are computed based on the geometry's bounds
|
|
// *vlx << "AABB" << export_AABB(obj->boundingBox());
|
|
// *vlx << "Sphere" << export_Sphere(obj->boundingSphere());
|
|
|
|
if (obj->effect())
|
|
*vlx << "Effect" << s.exportVLX(obj->effect());
|
|
if (obj->transform())
|
|
*vlx << "Transform" << s.exportVLX(obj->transform());
|
|
|
|
VLXValue uniforms;
|
|
uniforms.setList( new VLXList );
|
|
for(size_t i=0; obj->getUniformSet() && i<obj->uniforms().size(); ++i)
|
|
*uniforms.getList() << s.exportVLX(obj->uniforms()[i].get());
|
|
*vlx << "Uniforms" << uniforms;
|
|
|
|
if (obj->lodEvaluator())
|
|
*vlx << "LODEvaluator" << s.exportVLX(obj->lodEvaluator());
|
|
|
|
// mic fixme:
|
|
// Scissor: scissors might go away from the vl::Actor
|
|
|
|
VLXValue callbacks;
|
|
callbacks.setList( new VLXList );
|
|
for(int i=0; i<obj->actorEventCallbacks()->size(); ++i)
|
|
*callbacks.getList() << s.exportVLX(obj->actorEventCallbacks()->at(i));
|
|
*vlx << "ActorEventCallbacks" << callbacks;
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Actor* cast_obj = obj->as<vl::Actor>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("actor_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportActor(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Camera */
|
|
struct VLXClassWrapper_Camera: public ClassWrapper
|
|
{
|
|
void importCamera(VLXSerializer& s, const VLXStructure* vlx, vl::Camera* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "ViewMatrix")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value);
|
|
obj->setViewMatrix( vlx_mat4(value.getList()) );
|
|
// VLX_IMPORT_CHECK_RETURN( !obj->viewMatrix().isNull(), value )
|
|
}
|
|
else
|
|
if (key == "ProjectionMatrix")
|
|
{
|
|
vl::EProjectionMatrixType ptype = vl::PMT_UserProjection;
|
|
const VLXValue* pmtype = vlx->getValue("ProjectionMatrixType");
|
|
if ( pmtype )
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( pmtype->type() == VLXValue::Identifier, *pmtype );
|
|
ptype = vlx_EProjectionMatrixType( *pmtype, s );
|
|
}
|
|
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value);
|
|
obj->setProjectionMatrix( vlx_mat4(value.getList()), ptype );
|
|
// VLX_IMPORT_CHECK_RETURN( !obj->projectionMatrix().isNull(), value )
|
|
}
|
|
else
|
|
if (key == "Viewport")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
|
|
vl::Viewport* viewp = s.importVLX( value.getStructure() )->as<vl::Viewport>();
|
|
VLX_IMPORT_CHECK_RETURN( viewp != NULL, value )
|
|
obj->setViewport(viewp);
|
|
}
|
|
else
|
|
if (key == "FOV")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setFOV( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "NearPlane")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setNearPlane( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "FarPlane")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setFarPlane( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "Left")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setLeft( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "Right")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setRight( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "Bottom")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setBottom( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "Top")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setTop( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "BoundTransform")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
|
|
vl::Transform* tr= s.importVLX( value.getStructure() )->as<vl::Transform>();
|
|
VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
|
|
obj->bindTransform(tr);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Camera> obj = new vl::Camera;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importCamera(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportCamera(VLXSerializer& s, const vl::Camera* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "ViewMatrix" << vlx_toValue(obj->viewMatrix());
|
|
*vlx << "ProjectionMatrix" << vlx_toValue(obj->projectionMatrix());
|
|
*vlx << "ProjectionMatrixType" << vlx_Identifier(vlx_EProjectionMatrixType(obj->projectionMatrixType()));
|
|
*vlx << "Viewport" << s.exportVLX(obj->viewport());
|
|
*vlx << "NearPlane" << (double)obj->nearPlane();
|
|
*vlx << "FarPlane" << (double)obj->farPlane();
|
|
*vlx << "FOV" << (double)obj->fov();
|
|
*vlx << "Left" << (double)obj->left();
|
|
*vlx << "Right" << (double)obj->right();
|
|
*vlx << "Bottom" << (double)obj->bottom();
|
|
*vlx << "Top" << (double)obj->top();
|
|
if (obj->boundTransform())
|
|
*vlx << "BoundTransfrm" << s.exportVLX(obj->boundTransform());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Camera* cast_obj = obj->as<vl::Camera>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("camera_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportCamera(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Viewport */
|
|
struct VLXClassWrapper_Viewport: public ClassWrapper
|
|
{
|
|
void importViewport(VLXSerializer& s, const VLXStructure* vlx, vl::Viewport* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "ClearColor")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setClearColor( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "ClearColorInt")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger, value );
|
|
obj->setClearColorInt( vlx_ivec4( value.getArrayInteger() ) );
|
|
}
|
|
else
|
|
if (key == "ClearColorUInt")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayInteger, value );
|
|
obj->setClearColorUInt( vlx_uivec4( value.getArrayInteger() ) );
|
|
}
|
|
else
|
|
if (key == "ClearDepth")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
|
|
obj->setClearDepth( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "ClearStecil")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setClearStencil( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "ClearColorMode")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setClearColorMode( vlx_EClearColorMode( value, s) );
|
|
}
|
|
else
|
|
if (key == "ClearFlags")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setClearFlags( vlx_EClearFlags( value, s ) );
|
|
}
|
|
else
|
|
if (key == "X")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setX( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "Y")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setY( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "Width")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setWidth( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "Height")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setHeight( (int)value.getInteger() );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Viewport> obj = new vl::Viewport;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importViewport(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportViewport(const vl::Viewport* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "ClearColor" << vlx_toValue((vl::vec4)obj->clearColor());
|
|
*vlx << "ClearColorInt" << vlx_toValue(obj->clearColorInt());
|
|
*vlx << "ClearColorUInt" << vlx_toValue(obj->clearColorUInt());
|
|
*vlx << "ClearDepth" << (double)obj->clearDepth();
|
|
*vlx << "ClearStecil" << (long long)obj->clearStencil();
|
|
*vlx << "ClearColorMode" << vlx_Identifier(vlx_EClearColorMode(obj->clearColorMode()));
|
|
*vlx << "ClearFlags" << vlx_Identifier(vlx_EClearFlags(obj->clearFlags()));
|
|
*vlx << "X" << (long long)obj->x();
|
|
*vlx << "Y" << (long long)obj->y();
|
|
*vlx << "Width" << (long long)obj->width();
|
|
*vlx << "Height" << (long long)obj->height();
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Viewport* cast_obj = obj->as<vl::Viewport>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("viewport_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportViewport(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Transform */
|
|
struct VLXClassWrapper_Transform: public ClassWrapper
|
|
{
|
|
void importTransform(VLXSerializer& s, const VLXStructure* vlx, vl::Transform* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "LocalMatrix")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
obj->setLocalAndWorldMatrix( vlx_mat4( value.getList() ) );
|
|
}
|
|
else
|
|
// let the "Children" property take care of children binding
|
|
/*
|
|
if (key == "Parent")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
|
|
vl::Transform* tr = s.importVLX( value.getStructure() )->as<vl::Transform>();
|
|
VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
|
|
tr->addChild(obj);
|
|
}
|
|
else
|
|
*/
|
|
if (key == "Children")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* list = value.getList();
|
|
for(size_t ich=0; ich<list->value().size(); ++ich)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[ich].type() == VLXValue::Structure, list->value()[ich] )
|
|
const VLXStructure* vlx_tr = list->value()[ich].getStructure();
|
|
vl::Transform* child = s.importVLX( vlx_tr )->as<vl::Transform>();
|
|
VLX_IMPORT_CHECK_RETURN( child != NULL, *vlx_tr )
|
|
obj->addChild(child);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Transform> obj = new vl::Transform;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importTransform(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportTransform(VLXSerializer& s, const vl::Transform* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "LocalMatrix" << vlx_toValue(obj->localMatrix());
|
|
|
|
// not needed
|
|
/*if (obj->parent())
|
|
*vlx << "Parent" << s.exportVLX(obj->parent());*/
|
|
|
|
VLXValue childs;
|
|
childs.setList( new VLXList );
|
|
for(size_t i=0; i<obj->childrenCount(); ++i)
|
|
childs.getList()->value().push_back( s.exportVLX(obj->children()[i].get()) );
|
|
*vlx << "Children" << childs;
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Transform* cast_obj = obj->as<vl::Transform>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("transform_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportTransform(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Light */
|
|
struct VLXClassWrapper_Light: public ClassWrapper
|
|
{
|
|
void importLight(VLXSerializer& s, const VLXStructure* vlx, vl::Light* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "Ambient")
|
|
{
|
|
// note: what if the user specifies ( 1 0 0 0 ) -> becomes a ArrayInteger and an error is issued.
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
|
|
obj->setAmbient( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "Diffuse")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
|
|
obj->setDiffuse( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "Specular")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
|
|
obj->setSpecular( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "Position")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
|
|
obj->setPosition( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "SpotDirection")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
|
|
obj->setSpotDirection( (vl::fvec3)vlx_vec3( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "SpotExponent")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setSpotExponent( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "SpotCutoff")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setSpotCutoff( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "ConstantAttenuation")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setConstantAttenuation( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "LinearAttenuation")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setLinearAttenuation( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "QuadraticAttenuation")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->setQuadraticAttenuation( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "BoundTransform")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
|
|
vl::Transform* tr= s.importVLX( value.getStructure() )->as<vl::Transform>();
|
|
VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
|
|
obj->bindTransform(tr);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Light> obj = new vl::Light;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importLight(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportLight(VLXSerializer& s, const vl::Light* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "Ambient" << vlx_toValue((vl::vec4)obj->ambient());
|
|
*vlx << "Diffuse" << vlx_toValue((vl::vec4)obj->diffuse());
|
|
*vlx << "Specular" << vlx_toValue((vl::vec4)obj->specular());
|
|
*vlx << "Position" << vlx_toValue((vl::vec4)obj->position());
|
|
*vlx << "SpotDirection" << vlx_toValue((vl::vec3)obj->spotDirection());
|
|
*vlx << "SpotExponent" << obj->spotExponent();
|
|
*vlx << "SpotCutoff" << obj->spotCutoff();
|
|
*vlx << "ConstantAttenuation" << obj->constantAttenuation();
|
|
*vlx << "LinearAttenuation" << obj->linearAttenuation();
|
|
*vlx << "QuadraticAttenuation" << obj->quadraticAttenuation();
|
|
if (obj->boundTransform())
|
|
*vlx << "BoundTransform" << s.exportVLX(obj->boundTransform());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Light* cast_obj = obj->as<vl::Light>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("light_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportLight(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::ClipPlane*/
|
|
struct VLXClassWrapper_ClipPlane: public ClassWrapper
|
|
{
|
|
void importClipPlane(VLXSerializer& s, const VLXStructure* vlx, vl::ClipPlane* obj)
|
|
{
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "PlaneNormal")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value )
|
|
obj->plane().setNormal( vlx_vec3( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "PlaneOrigin")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value )
|
|
obj->plane().setOrigin( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "BoundTransform")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value)
|
|
vl::Transform* tr= s.importVLX( value.getStructure() )->as<vl::Transform>();
|
|
VLX_IMPORT_CHECK_RETURN( tr != NULL, value )
|
|
obj->bindTransform(tr);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::ClipPlane> obj = new vl::ClipPlane;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importClipPlane(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportClipPlane(VLXSerializer& s, const vl::ClipPlane* clip, VLXStructure* vlx)
|
|
{
|
|
*vlx << "PlaneNormal" << vlx_toValue(clip->plane().normal());
|
|
*vlx << "PlaneOrigin" << clip->plane().origin();
|
|
if (clip->boundTransform())
|
|
*vlx << "BoundTransform" << s.exportVLX(clip->boundTransform());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::ClipPlane* cast_obj = obj->as<vl::ClipPlane>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("clipplane_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportClipPlane(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::GLSLProgram */
|
|
struct VLXClassWrapper_GLSLProgram: public ClassWrapper
|
|
{
|
|
void importGLSLProgram(VLXSerializer& s, const VLXStructure* vlx, vl::GLSLProgram* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "AttachShader")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value )
|
|
const VLXStructure* st = value.getStructure();
|
|
vl::GLSLShader* glsl_sh = s.importVLX(st)->as<vl::GLSLShader>();
|
|
VLX_IMPORT_CHECK_RETURN( glsl_sh != NULL, *st )
|
|
obj->attachShader(glsl_sh);
|
|
}
|
|
else
|
|
if (key == "FragDataLocation")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* list = value.getList();
|
|
VLX_IMPORT_CHECK_RETURN( list->value().size() == 2, *list )
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[0].type() == VLXValue::Identifier, *list )
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[1].type() == VLXValue::Integer, *list )
|
|
const char* name = list->value()[0].getIdentifier().c_str();
|
|
int index = (int)list->value()[1].getInteger();
|
|
obj->bindFragDataLocation(index, name);
|
|
}
|
|
// MIC FIXME
|
|
//else
|
|
//if (key == "AttribLocation")
|
|
//{
|
|
// VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
// const VLXList* list = value.getList();
|
|
// VLX_IMPORT_CHECK_RETURN( list->value().size() == 2, *list )
|
|
// VLX_IMPORT_CHECK_RETURN( list->value()[0].type() == VLXValue::Identifier, *list )
|
|
// VLX_IMPORT_CHECK_RETURN( list->value()[1].type() == VLXValue::Integer, *list )
|
|
// const char* name = list->value()[0].getIdentifier().c_str();
|
|
// int index = (int)list->value()[1].getInteger();
|
|
// obj->addAutoAttribLocation(index, name);
|
|
//}
|
|
else
|
|
if (key == "Uniforms")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::List, value )
|
|
const VLXList* list = value.getList();
|
|
for(size_t i=0; i<list->value().size(); ++i)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( list->value()[i].type() == VLXValue::Structure, list->value()[i] )
|
|
vl::Uniform* uniform = s.importVLX( list->value()[i].getStructure() )->as<vl::Uniform>();
|
|
VLX_IMPORT_CHECK_RETURN( uniform != NULL, list->value()[i] )
|
|
obj->setUniform(uniform);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::GLSLProgram> obj = new vl::GLSLProgram;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importGLSLProgram(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportGLSLProgram(VLXSerializer& s, const vl::GLSLProgram* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
|
|
// export obj shaders
|
|
for(int i=0; i<obj->shaderCount(); ++i)
|
|
*vlx << "AttachShader" << s.exportVLX(obj->shader(i));
|
|
|
|
// export uniforms
|
|
VLXValue uniforms;
|
|
uniforms.setList( new VLXList );
|
|
for(size_t i=0; obj->getUniformSet() && i<obj->getUniformSet()->uniforms().size(); ++i)
|
|
*uniforms.getList() << s.exportVLX(obj->getUniformSet()->uniforms()[i].get());
|
|
*vlx << "Uniforms" << uniforms;
|
|
|
|
// frag data location
|
|
for(std::map<std::string, int>::const_iterator it = obj->fragDataLocations().begin(); it != obj->fragDataLocations().end(); ++it)
|
|
{
|
|
VLXList* location = new VLXList;
|
|
*location << vlx_Identifier(it->first); // Name
|
|
*location << (long long)it->second; // Location
|
|
*vlx << "FragDataLocation" << location;
|
|
}
|
|
|
|
//// auto attrib locations
|
|
// MIC FIXME
|
|
//for(std::map<std::string, int>::const_iterator it = obj->autoAttribLocations().begin(); it != obj->autoAttribLocations().end(); ++it)
|
|
//{
|
|
// VLXList* location = new VLXList;
|
|
// *location << vlx_Identifier(it->first); // Name
|
|
// *location << (long long)it->second; // Location
|
|
// *vlx << "AttribLocation" << location;
|
|
//}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::GLSLProgram* cast_obj = obj->as<vl::GLSLProgram>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("glslprog_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportGLSLProgram(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::GLSLVertexShader, vl::GLSLFragmentShader, vl::GLSLGeometryShader, vl::GLSLTessControlShader, vl::GLSLTessEvaluationShader. */
|
|
struct VLXClassWrapper_GLSLShader: public ClassWrapper
|
|
{
|
|
void importGLSLShader(VLXSerializer& s, const VLXStructure* vlx, vl::GLSLShader* obj)
|
|
{
|
|
const VLXValue* path = vlx->getValue("Path");
|
|
const VLXValue* source = vlx->getValue("Source");
|
|
VLX_IMPORT_CHECK_RETURN( path != NULL || source != NULL, *vlx )
|
|
if (path)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( path->type() == VLXValue::String, *path )
|
|
std::string resolved_path = path->getString();
|
|
s.resolvePath(resolved_path);
|
|
obj->setSource(resolved_path.c_str()); // this automatically loads the source and sets the path
|
|
}
|
|
else
|
|
if (source)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( source->type() == VLXValue::RawtextBlock, *source )
|
|
obj->setSource(source->getRawtextBlock()->value().c_str());
|
|
}
|
|
else
|
|
{
|
|
vl::Log::warning( vl::Say("Line %n : no source or path specified for glsl shader.\n") << vlx->lineNumber() );
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::GLSLShader> obj = NULL;
|
|
if (vlx->tag() == "<vl::GLSLVertexShader>")
|
|
obj = new vl::GLSLVertexShader;
|
|
else
|
|
if (vlx->tag() == "<vl::GLSLFragmentShader>")
|
|
obj = new vl::GLSLFragmentShader;
|
|
else
|
|
if (vlx->tag() == "<vl::GLSLGeometryShader>")
|
|
obj = new vl::GLSLGeometryShader;
|
|
else
|
|
if (vlx->tag() == "<vl::GLSLTessControlShader>")
|
|
obj = new vl::GLSLTessControlShader;
|
|
else
|
|
if (vlx->tag() == "<vl::GLSLTessEvaluationShader>")
|
|
obj = new vl::GLSLTessEvaluationShader;
|
|
else
|
|
{
|
|
s.signalImportError( vl::Say("Line %n : shader type '%s' not supported.\n") << vlx->tag() );
|
|
return NULL;
|
|
}
|
|
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importGLSLShader(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportGLSLShader(const vl::GLSLShader* glslsh, VLXStructure* vlx)
|
|
{
|
|
if (!glslsh->path().empty())
|
|
*vlx << "Path" << vlx_String(glslsh->path().toStdString());
|
|
else
|
|
if (!glslsh->source().empty())
|
|
*vlx << "Source" << vlx_Rawtext(glslsh->source());
|
|
else
|
|
if (glslsh->handle())
|
|
*vlx << "Source" << vlx_Rawtext(glslsh->getShaderSource());
|
|
else
|
|
*vlx << "Source" << vlx_Identifier("NO_SOURCE_FOUND");
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::GLSLShader* cast_obj = obj->as<vl::GLSLShader>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("glslsh_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportGLSLShader(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::VertexAttrib */
|
|
struct VLXClassWrapper_VertexAttrib: public ClassWrapper
|
|
{
|
|
void importVertexAttrib(VLXSerializer& s, const VLXStructure* vlx, vl::VertexAttrib* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
const VLXValue* value = vlx->getValue("Value");
|
|
VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
|
|
obj->setValue( (vl::fvec4)vlx_vec4( value->getArrayReal() ) );
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::VertexAttrib> obj = new vl::VertexAttrib;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importVertexAttrib(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportVertexAttrib(const vl::VertexAttrib* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
*vlx << "Value" << vlx_toValue((vl::vec4)obj->value());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::VertexAttrib* cast_obj = obj->as<vl::VertexAttrib>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("vertexattrib_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportVertexAttrib(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Color */
|
|
struct VLXClassWrapper_Color: public ClassWrapper
|
|
{
|
|
void importColor(VLXSerializer& s, const VLXStructure* vlx, vl::Color* obj)
|
|
{
|
|
const VLXValue* value = vlx->getValue("Value");
|
|
VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
|
|
obj->setValue( (vl::fvec4)vlx_vec4( value->getArrayReal() ) );
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Color> obj = new vl::Color;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importColor(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportColor(const vl::Color* obj, VLXStructure* vlx)
|
|
{
|
|
*vlx << "Value" << vlx_toValue((vl::vec4)obj->value());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Color* cast_obj = obj->as<vl::Color>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("color_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportColor(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::SecondaryColor */
|
|
struct VLXClassWrapper_SecondaryColor: public ClassWrapper
|
|
{
|
|
void importSecondaryColor(VLXSerializer& s, const VLXStructure* vlx, vl::SecondaryColor* obj)
|
|
{
|
|
const VLXValue* value = vlx->getValue("Value");
|
|
VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
|
|
obj->setValue( (vl::fvec3)vlx_vec3( value->getArrayReal() ) );
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::SecondaryColor> obj = new vl::SecondaryColor;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importSecondaryColor(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportSecondaryColor(const vl::SecondaryColor* obj, VLXStructure* vlx)
|
|
{
|
|
*vlx << "Value" << vlx_toValue((vl::vec3)obj->value());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::SecondaryColor* cast_obj = obj->as<vl::SecondaryColor>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("seccolor_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportSecondaryColor(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Normal */
|
|
struct VLXClassWrapper_Normal: public ClassWrapper
|
|
{
|
|
void importNormal(VLXSerializer& s, const VLXStructure* vlx, vl::Normal* obj)
|
|
{
|
|
const VLXValue* value = vlx->getValue("Value");
|
|
VLX_IMPORT_CHECK_RETURN( value->type() == VLXValue::ArrayReal, *value )
|
|
obj->setValue( (vl::fvec3)vlx_vec3( value->getArrayReal() ) );
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Normal> obj = new vl::Normal;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importNormal(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportNormal(const vl::Normal* obj, VLXStructure* vlx)
|
|
{
|
|
*vlx << "Value" << vlx_toValue((vl::vec3)obj->value());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Normal* cast_obj = obj->as<vl::Normal>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("normal_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportNormal(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Material */
|
|
struct VLXClassWrapper_Material: public ClassWrapper
|
|
{
|
|
void importMaterial(VLXSerializer& s, const VLXStructure* vlx, vl::Material* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
if (key == "FrontAmbient")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setFrontAmbient( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "FrontDiffuse")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setFrontDiffuse( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "FrontEmission")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setFrontEmission( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "FrontSpecular")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setFrontSpecular( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "FrontShininess")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
|
|
obj->setFrontShininess( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "BackAmbient")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setBackAmbient( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "BackDiffuse")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setBackDiffuse( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "BackEmission")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setBackEmission( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "BackSpecular")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setBackSpecular( (vl::fvec4)vlx_vec4( value.getArrayReal() ) );
|
|
}
|
|
else
|
|
if (key == "BackShininess")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
|
|
obj->setBackShininess( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "ColorMaterialEnabled")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
|
|
obj->setColorMaterialEnabled( value.getBool() );
|
|
}
|
|
}
|
|
|
|
vl::EColorMaterial col_mat = vl::CM_AMBIENT_AND_DIFFUSE;
|
|
const VLXValue* vlx_col_mat = vlx->getValue("ColorMaterial");
|
|
if (vlx_col_mat)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( vlx_col_mat->type() == VLXValue::Identifier, *vlx_col_mat );
|
|
col_mat = vlx_EColorMaterial( *vlx_col_mat, s );
|
|
}
|
|
|
|
vl::EPolygonFace poly_face = vl::PF_FRONT_AND_BACK;
|
|
const VLXValue* vlx_poly_mat = vlx->getValue("ColorMaterialFace");
|
|
if (vlx_poly_mat)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( vlx_poly_mat->type() == VLXValue::Identifier, *vlx_poly_mat );
|
|
poly_face = vlx_EPolygonFace( *vlx_poly_mat, s );
|
|
}
|
|
|
|
obj->setColorMaterial( poly_face, col_mat );
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Material> obj = new vl::Material;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importMaterial(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportMaterial(const vl::Material* obj, VLXStructure* vlx)
|
|
{
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
|
|
*vlx << "FrontAmbient" << vlx_toValue((vl::vec4)obj->frontAmbient());
|
|
*vlx << "FrontDiffuse" << vlx_toValue((vl::vec4)obj->frontDiffuse());
|
|
*vlx << "FrontEmission" << vlx_toValue((vl::vec4)obj->frontEmission());
|
|
*vlx << "FrontSpecular" << vlx_toValue((vl::vec4)obj->frontSpecular());
|
|
*vlx << "FrontShininess" << (double)obj->frontShininess();
|
|
|
|
*vlx << "BackAmbient" << vlx_toValue((vl::vec4)obj->backAmbient());
|
|
*vlx << "BackDiffuse" << vlx_toValue((vl::vec4)obj->backDiffuse());
|
|
*vlx << "BackEmission" << vlx_toValue((vl::vec4)obj->backEmission());
|
|
*vlx << "BackSpecular" << vlx_toValue((vl::vec4)obj->backSpecular());
|
|
*vlx << "BackShininess" << (double)obj->backShininess();
|
|
|
|
*vlx << "ColorMaterial" << vlx_Identifier(vlx_EColorMaterial(obj->colorMaterial()));
|
|
*vlx << "ColorMaterialFace" << vlx_Identifier(vlx_EPolygonFace(obj->colorMaterialFace()));
|
|
|
|
*vlx << "ColorMaterialEnabled" << obj->colorMaterialEnabled();
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Material* cast_obj = obj->as<vl::Material>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("material_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportMaterial(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::DepthSortCallback */
|
|
struct VLXClassWrapper_ActorEventCallback: public ClassWrapper
|
|
{
|
|
void importActorEventCallback(VLXSerializer& s, const VLXStructure* vlx, vl::ActorEventCallback* obj)
|
|
{
|
|
if (obj->isOfType(vl::DepthSortCallback::Type()))
|
|
{
|
|
const VLXValue* vlx_sm = vlx->getValue("SortMode");
|
|
VLX_IMPORT_CHECK_RETURN( vlx_sm->type() == VLXValue::Identifier, *vlx_sm )
|
|
if (vlx_sm)
|
|
{
|
|
vl::ESortMode sm = vl::SM_SortBackToFront;
|
|
if ( vlx_sm->getIdentifier() == "SM_SortBackToFront" )
|
|
sm = vl::SM_SortBackToFront;
|
|
else
|
|
if ( vlx_sm->getIdentifier() == "SM_SortFrontToBack" )
|
|
sm = vl::SM_SortFrontToBack;
|
|
else
|
|
s.signalImportError( vl::Say("Line %n : unknown sort mode '%s'.\n") << vlx_sm->lineNumber() << vlx_sm->getIdentifier() );
|
|
obj->as<vl::DepthSortCallback>()->setSortMode(sm);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::ActorEventCallback> obj = NULL;
|
|
|
|
if (vlx->tag() == "<vl::DepthSortCallback>")
|
|
obj = new vl::DepthSortCallback;
|
|
else
|
|
{
|
|
s.signalImportError( vl::Say("Line %n : ActorEventCallback type not supported for import.\n") << vlx->lineNumber() );
|
|
return NULL;
|
|
}
|
|
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importActorEventCallback(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportActorEventCallback(VLXSerializer& s, const vl::ActorEventCallback* cb, VLXStructure* vlx)
|
|
{
|
|
if (cb->classType() == vl::DepthSortCallback::Type())
|
|
{
|
|
const vl::DepthSortCallback* dsc = cb->as<vl::DepthSortCallback>();
|
|
|
|
if (dsc->sortMode() == vl::SM_SortBackToFront)
|
|
*vlx << "SortMode" << vlx_Identifier("SM_SortBackToFront");
|
|
else
|
|
*vlx << "SortMode" << vlx_Identifier("SM_SortFrontToBack");
|
|
}
|
|
else
|
|
{
|
|
s.signalExportError("ActorEventCallback type not supported for export.\n");
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::ActorEventCallback* cast_obj = obj->as<vl::ActorEventCallback>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("actorcallback_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportActorEventCallback(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::Texture */
|
|
struct VLXClassWrapper_Texture: public ClassWrapper
|
|
{
|
|
void importTexture(VLXSerializer& s, const VLXStructure* vlx, vl::Texture* obj)
|
|
{
|
|
const VLXValue* name = vlx->getValue("ObjectName");
|
|
if (name)
|
|
obj->setObjectName( name->getString() );
|
|
|
|
obj->setSetupParams( new vl::Texture::SetupParams );
|
|
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
|
|
if (key == "Dimension")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setupParams()->setDimension( vlx_ETextureDimension( value, s ) );
|
|
}
|
|
else
|
|
if (key == "TexParameter")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value );
|
|
vl::TexParameter* tex_param = s.importVLX( value.getStructure() )->as<vl::TexParameter>();
|
|
VLX_IMPORT_CHECK_RETURN( tex_param != NULL, value );
|
|
// copy the content over
|
|
*obj->getTexParameter() = *tex_param;
|
|
}
|
|
else
|
|
if (key == "ImagePath")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::String, value );
|
|
std::string resolved_path = value.getString();
|
|
s.resolvePath( resolved_path );
|
|
obj->setupParams()->setImagePath( resolved_path.c_str() );
|
|
}
|
|
else
|
|
if (key == "Format")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setupParams()->setFormat( vlx_ETextureFormat( value, s ) );
|
|
}
|
|
else
|
|
if (key == "Width")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setupParams()->setWidth( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "Height")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setupParams()->setHeight( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "Depth")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setupParams()->setDepth( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "GenMipmaps")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
|
|
obj->setupParams()->setGenMipmaps( (int)value.getBool() );
|
|
}
|
|
else
|
|
if (key == "BufferObject")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Structure, value );
|
|
vl::BufferObject* buf_obj = s.importVLX( value.getStructure() )->as<vl::BufferObject>();
|
|
VLX_IMPORT_CHECK_RETURN( buf_obj, value );
|
|
obj->setupParams()->setBufferObject( buf_obj );
|
|
}
|
|
else
|
|
if (key == "Samples")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Integer, value );
|
|
obj->setupParams()->setSamples( (int)value.getInteger() );
|
|
}
|
|
else
|
|
if (key == "FixedSamplesLocations")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
|
|
obj->setupParams()->setFixedSamplesLocations( (int)value.getBool() );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::Texture> obj = new vl::Texture;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importTexture(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportTexture(VLXSerializer& s, const vl::Texture* obj, VLXStructure* vlx)
|
|
{
|
|
// mic fixme:
|
|
// - we should allow patterns such as initializing a texture from an image filled by a shader or procedure.
|
|
// - we should allow avoid loading twice the same image or shader source or any externa resource etc. time for a resource manager?
|
|
|
|
if (!obj->objectName().empty() && obj->objectName() != obj->className())
|
|
*vlx << "ObjectName" << vlx_String(obj->objectName());
|
|
|
|
if (obj->getTexParameter())
|
|
*vlx << "TexParameter" << s.exportVLX(obj->getTexParameter());
|
|
|
|
if (obj->setupParams())
|
|
{
|
|
const vl::Texture::SetupParams* par = obj->setupParams();
|
|
|
|
if (par)
|
|
{
|
|
*vlx << "Dimension" << vlx_Identifier(vlx_ETextureDimension(par->dimension()));
|
|
|
|
*vlx << "Format" << vlx_Identifier(vlx_ETextureFormat(par->format()));
|
|
|
|
if (!par->imagePath().empty())
|
|
*vlx << "ImagePath" << vlx_String(par->imagePath().toStdString());
|
|
else
|
|
if (par->image())
|
|
*vlx << "ImagePath" << vlx_String(par->image()->filePath().toStdString());
|
|
|
|
if (par->width())
|
|
*vlx << "Width" << (long long)par->width();
|
|
|
|
if (par->height())
|
|
*vlx << "Height" << (long long)par->height();
|
|
|
|
if (par->depth())
|
|
*vlx << "Depth" << (long long)par->depth();
|
|
|
|
*vlx << "GenMipmaps" << par->genMipmaps();
|
|
|
|
// mic fixme: implement BufferObject importer/exporter
|
|
#if 0
|
|
if (par->bufferObject())
|
|
{
|
|
*vlx << "BufferObject" << s.exportVLX(par->bufferObject());
|
|
}
|
|
#endif
|
|
|
|
if(par->samples())
|
|
{
|
|
*vlx << "Samples" << (long long)par->samples();
|
|
*vlx << "FixedSamplesLocations" << par->fixedSamplesLocations();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::Texture* cast_obj = obj->as<vl::Texture>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texture_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportTexture(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::TexParameter */
|
|
struct VLXClassWrapper_TexParameter: public ClassWrapper
|
|
{
|
|
void importTexParameter(VLXSerializer& s, const VLXStructure* vlx, vl::TexParameter* obj)
|
|
{
|
|
for(size_t i=0; i<vlx->value().size(); ++i)
|
|
{
|
|
const std::string& key = vlx->value()[i].key();
|
|
const VLXValue& value = vlx->value()[i].value();
|
|
|
|
if (key == "MinFilter")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setMinFilter( vlx_ETexParamFilter( value, s ) );
|
|
}
|
|
else
|
|
if (key == "MagFilter")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setMagFilter( vlx_ETexParamFilter( value, s ) );
|
|
}
|
|
else
|
|
if (key == "WrapS")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setWrapS( vlx_ETexParamWrap( value, s ) );
|
|
}
|
|
else
|
|
if (key == "WrapT")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setWrapT( vlx_ETexParamWrap( value, s ) );
|
|
}
|
|
else
|
|
if (key == "WrapR")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setWrapR( vlx_ETexParamWrap( value, s ) );
|
|
}
|
|
else
|
|
if (key == "CompareMode")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setCompareMode( vlx_ETexCompareMode( value, s ) );
|
|
}
|
|
else
|
|
if (key == "CompareFunc")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setCompareFunc( vlx_ETexCompareFunc( value, s ) );
|
|
}
|
|
else
|
|
if (key == "DepthTextureMode")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Identifier, value );
|
|
obj->setDepthTextureMode( vlx_EDepthTextureMode( value, s ) );
|
|
}
|
|
else
|
|
if (key == "BorderColor")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::ArrayReal, value );
|
|
obj->setBorderColor( (vl::fvec4)vlx_vec4(value.getArrayReal()) );
|
|
}
|
|
else
|
|
if (key == "Anisotropy")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Real, value );
|
|
obj->setAnisotropy( (float)value.getReal() );
|
|
}
|
|
else
|
|
if (key == "GenerateMipmap")
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN( value.type() == VLXValue::Bool, value );
|
|
obj->setGenerateMipmap( value.getBool() );
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::TexParameter> obj = new vl::TexParameter;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importTexParameter(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportTexParameter(const vl::TexParameter* texparam, VLXStructure* vlx)
|
|
{
|
|
*vlx << "MinFilter" << vlx_Identifier(vlx_ETexParamFilter(texparam->minFilter()));
|
|
*vlx << "MagFilter" << vlx_Identifier(vlx_ETexParamFilter(texparam->magFilter()));
|
|
*vlx << "WrapS" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapS()));
|
|
*vlx << "WrapT" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapT()));
|
|
*vlx << "WrapR" << vlx_Identifier(vlx_ETexParamWrap(texparam->wrapR()));
|
|
*vlx << "CompareMode" << vlx_Identifier(vlx_ETexCompareMode(texparam->compareMode()));
|
|
*vlx << "CompareFunc" << vlx_Identifier(vlx_ETexCompareFunc(texparam->compareFunc()));
|
|
*vlx << "DepthTextureMode" << vlx_Identifier(vlx_EDepthTextureMode(texparam->depthTextureMode()));
|
|
*vlx << "BorderColor" << vlx_toValue((vl::vec4)texparam->borderColor());
|
|
*vlx << "Anisotropy" << texparam->anisotropy();
|
|
*vlx << "GenerateMipmap" << texparam->generateMipmap();
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::TexParameter* cast_obj = obj->as<vl::TexParameter>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texparam_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportTexParameter(cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
/** VLX wrapper of vl::TextureSampler */
|
|
struct VLXClassWrapper_TextureSampler: public ClassWrapper
|
|
{
|
|
void importTextureSampler(VLXSerializer& s, const VLXStructure* vlx, vl::TextureSampler* obj)
|
|
{
|
|
const VLXValue* vlx_texture = vlx->getValue("Texture");
|
|
if (vlx_texture)
|
|
{
|
|
VLX_IMPORT_CHECK_RETURN(vlx_texture->type() == VLXValue::Structure, *vlx_texture);
|
|
vl::Texture* texture = s.importVLX(vlx_texture->getStructure())->as<vl::Texture>();
|
|
VLX_IMPORT_CHECK_RETURN( texture != NULL , *vlx_texture);
|
|
obj->setTexture(texture);
|
|
}
|
|
}
|
|
|
|
virtual vl::ref<vl::Object> importVLX(VLXSerializer& s, const VLXStructure* vlx)
|
|
{
|
|
vl::ref<vl::TextureSampler> obj = new vl::TextureSampler;
|
|
// register imported structure asap
|
|
s.registerImportedStructure(vlx, obj.get());
|
|
importTextureSampler(s, vlx, obj.get());
|
|
return obj;
|
|
}
|
|
|
|
void exportTextureSampler(VLXSerializer& s, const vl::TextureSampler* tex_sampler, VLXStructure* vlx)
|
|
{
|
|
if (tex_sampler->texture())
|
|
*vlx << "Texture" << s.exportVLX(tex_sampler->texture());
|
|
}
|
|
|
|
virtual vl::ref<VLXStructure> exportVLX(VLXSerializer& s, const vl::Object* obj)
|
|
{
|
|
const vl::TextureSampler* cast_obj = obj->as<vl::TextureSampler>(); VL_CHECK(cast_obj)
|
|
vl::ref<VLXStructure> vlx = new VLXStructure(vlx_makeTag(obj).c_str(), s.generateID("texsampler_"));
|
|
// register exported object asap
|
|
s.registerExportedObject(obj, vlx.get());
|
|
exportTextureSampler(s, cast_obj, vlx.get());
|
|
return vlx;
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif
|