VertexDeclarationParameters::VertexDeclarationParameters(const std::vector<VertexElement>& vertexElements)        
{
        for (uint32_t i = 0; i < vertexElements.size(); i++)
        {
            _elements.push_back (VertexElement(vertexElements[i]));
        }
}
VertexDeclarationParameters::VertexDeclarationParameters (const VertexDeclarationParameters& in) 
{
        for (uint32_t i = 0; i < in._elements.size(); i++)
        {
            _elements.push_back (VertexElement(in._elements[i]));
        }
};
 //-----------------------------------------------------------------------------
 void VertexDeclaration::modifyElement(unsigned short elem_index, 
     unsigned short source, size_t offset, VertexElementType theType,
     VertexElementSemantic semantic, unsigned short index)
 {
     assert(elem_index < mElementList.size() && "Index out of bounds");
     VertexElementList::iterator i = mElementList.begin();
     std::advance(i, elem_index);
     (*i) = VertexElement(source, offset, theType, semantic, index);
 }
Exemple #4
0
		bool Init( int width, int height )
		{
			mSize = Point( width, height );

			mDecl = new VertexDeclaration( );
			mDecl->AddElement( VertexElement( 0, VDeclSemantic::POSITION, VDeclType::FLOAT3, 0 ) );
			mDecl->AddElement( VertexElement( 0, VDeclSemantic::TEXCOORD, VDeclType::FLOAT2, 0 ) );
			mDecl->AddElement( VertexElement( 0, VDeclSemantic::COLOUR, VDeclType::COLOUR, 0 ) );

			mMat[0] = new Material( );
			mMat[0]->mAlphaBlend = true;
			mMat[0]->mAlphaTest = true;
			mMat[0]->mDepthWrite = true;
			mMat[0]->mDepthBuffer = false;
			mMat[0]->AddTextureStage(
				TextureStage(
					0,
					BlendMode( BlendOp::MODULATE, BlendArg::TEXTURE, BlendArg::DIFFUSE ),
					BlendMode( BlendOp::SELECTARGUMENT1, BlendArg::TEXTURE )
				)
			);

			mMat[1] = new Material( );
			mMat[1]->mAlphaBlend = true;
			mMat[1]->mAlphaTest = false;
			mMat[1]->mDepthWrite = true;
			mMat[1]->mDepthBuffer = false;
			mMat[1]->AddTextureStage(
				TextureStage(
					0,
					BlendMode( BlendOp::SELECTARGUMENT1, BlendArg::DIFFUSE ),
					BlendMode( BlendOp::SELECTARGUMENT1, BlendArg::TEXTURE )
				)
			);

			mDefaultFont = new Halia::Font( );
			mDefaultFont->Init( "Tahoma", 16 );

			return true;
		};
    void VertexDeclaration::add
    (
        VertexElementSemantic semantic, 
        VertexElementType type
    )
    {
        if( hasSemantic(semantic) )
            throw std::runtime_error("The vertex declaration have already the element with semantic \"" + VertexElementSemanticInfos::getInfos(semantic).name() + '"');

        m_declaration.push_back( VertexElement(semantic, type, m_size) );

        m_size += VertexElementTypeInfos::getInfos(type).size();
    }
Exemple #6
0
	bool SkyLight::Create(Sys_GraphicsPtr pGraphics)
	{
		m_pMaterial = pGraphics->CreateMaterialFromFile("./assets/standard/material/dr_render_directional_light.fx");

		VertexFormat vf;
		vf.AddElement(VertexElement(0, VertexElement::POSITION, G_FORMAT_R32G32B32_FLOAT));
		m_pMaterial->SetVertexFormat(vf);

		if(m_pMaterial == MaterialPtr())
		{
			return false;
		}
		return true;
	}
Exemple #7
0
	void RegisterVertexTypes()
	{
		VertexElement VDPosUV[] = 
		{	
			VertexElement(P3DVD_FLOAT3, P3DVU_POSITION), 
			VertexElement(P3DVD_FLOAT2, P3DVU_TEXCOORD),
			P3DVE_END()
		};
		
		VertexElement VDPosUVCol[] = 
		{	
			VertexElement(P3DVD_FLOAT3, P3DVU_POSITION), 
			VertexElement(P3DVD_FLOAT2, P3DVU_TEXCOORD),
			VertexElement(P3DVD_FLOAT4, P3DVU_COLOR),
			P3DVE_END()
		};

		VertexElement VDPosUVNormal[] = 
		{	
			VertexElement(P3DVD_FLOAT3, P3DVU_POSITION), 
			VertexElement(P3DVD_FLOAT2, P3DVU_TEXCOORD),
			VertexElement(P3DVD_FLOAT3, P3DVU_NORMAL), 
			P3DVE_END()
		};

		VertexElement VDStaticMesh[] = 
		{	
			VertexElement(P3DVD_FLOAT3, P3DVU_POSITION),
			P3DVE_END()
		};

		CRenderer::cGraphicsManager()->RegisterVertexDesc(VDPosUVCol, Str( _W("VDPosUV") ));
		CRenderer::cGraphicsManager()->RegisterVertexDesc(VDPosUVCol, Str( _W("VDPosUVCol") ));
		CRenderer::cGraphicsManager()->RegisterVertexDesc(VDPosUVNormal, Str( _W("VDPosUVNormal") ));
		
		// default vertex decls
		CRenderer::cGraphicsManager()->RegisterVertexDesc(VDStaticMesh, Str( _W("VDStaticMesh") ));

	}
Exemple #8
0
	bool PostEffect_SSAO::Initialize(RenderSystemPtr pRS)
	{
		
		m_pMaterial = pRS->CreateMaterialFromFile("./assets/standard/material/dr_render_ssao.fx");

		VertexElement vf[] = 
		{
			VertexElement(0, VertexElement::POSITION,G_FORMAT_R32G32B32_FLOAT),
		};
		VertexFormat format;

		format.SetElement(vf, 1);

		m_pMaterial->SetVertexFormat(format);

		m_pSSAORandomTex = pRS->CreateTextureFromFile("./assets/standard/texture/ssao_rand.jpg");
		
		m_pMaterial->SetTextureByName("tex_ssao_rand", m_pSSAORandomTex);


		int w = pRS->GetFrameBufferWidth();

		int h = pRS->GetFrameBufferHeight();
		G_FORMAT rt_format[1] = {G_FORMAT_R8G8B8A8_UNORM,};
		m_pGBlurTarget = pRS->CreateRenderTarget(1, w , h , rt_format);

		if(m_pGBlurTarget == nullptr)
		{
			return false;
		}

		m_pGBlurMaterial = pRS->CreateMaterialFromFile("./assets/standard/material/dr_render_BBlur.fx");

		if(m_pGBlurMaterial == nullptr)
		{
			return false;
		}
		
		m_pGBlurMaterial->SetVertexFormat(format);
		return true;
	}
bool PostEffect_GaussianBlur::Initialize(RenderSystemPtr pRS)
{
    m_pRS = pRS;

    m_pMaterial = pRS->CreateMaterialFromFile("./assets/standard/material/dr_render_GBlur.fx");

    if(m_pMaterial == nullptr)
    {
        return false;
    }
    VertexElement vf[] =
    {
        VertexElement(0, VertexElement::POSITION,G_FORMAT_R32G32B32_FLOAT),
    };
    VertexFormat format;

    format.SetElement(vf, 1);

    m_pMaterial->SetVertexFormat(format);


    return true;

}
	List<VertexElement> VertexDataDesc::createElements() const
	{
		UINT32 maxStreamIdx = getMaxStreamIdx();

		UINT32 numStreams = maxStreamIdx + 1;
		UINT32* streamOffsets = bs_newN<UINT32>(numStreams);
		for (UINT32 i = 0; i < numStreams; i++)
			streamOffsets[i] = 0;

		List<VertexElement> declarationElements;
		for (auto& vertElem : mVertexElements)
		{
			UINT32 streamIdx = vertElem.getStreamIdx();

			declarationElements.push_back(VertexElement(streamIdx, streamOffsets[streamIdx], vertElem.getType(),
				vertElem.getSemantic(), vertElem.getSemanticIdx(), vertElem.getInstanceStepRate()));

			streamOffsets[streamIdx] += vertElem.getSize();
		}

		bs_deleteN(streamOffsets, numStreams);

		return declarationElements;
	}
HRESULT CLucid3DRenderer::AddMesh(GraphicsDevicePtr graphicsDevice, std::wstring& contentPath, IModelContentPtr pModelContent, MeshInfo meshInfo)
{
    HRESULT hr = S_OK;
    CStringW diffuseTextureName;
    Lucid3DRenderBufferDesc renderDesc;
    ModelContentBufferDescription vertexBuffer;
    ModelContentBufferDescription indexBuffer;
    ModelContentMaterialDescription material;
    InputStreamPtr spStream;
    TexturePtr tex;
    std::string contentPathA = WideToAnsi(contentPath);

    std::string diffuseTexturePath;
    std::string specularTexturePath;
    std::string normalTexturePath;
    
    // Get vertex and index buffer descriptions for target mesh
    hr = pModelContent->GetVertexBuffer(meshInfo.vertexBufferId, vertexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to get vertex buffer");

    hr = pModelContent->GetIndexBuffer(meshInfo.indexBufferId, indexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to get index buffer");

    hr = pModelContent->GetMaterial(meshInfo.materialId, material);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to get material");

    VertexElement elements[] =
    {
        VertexElement(0, VertexChannelType::Float3, VertexChannelSemantic::Position, false),
        VertexElement(0, VertexChannelType::Float3, VertexChannelSemantic::Normal, false),
        VertexElement(0, VertexChannelType::Float3, VertexChannelSemantic::Tangent, false),
        VertexElement(0, VertexChannelType::Float3, VertexChannelSemantic::BiTangent, false),
        VertexElement(0, VertexChannelType::Float2, VertexChannelSemantic::TexCoord0, false),
    };

    hr = graphicsDevice->CreateVertexBuffer((uint)vertexBuffer.stride, vertexBuffer.numElements, elements, _countof(elements),  ResourceAccess::Read, ResourceAccess::Write, vertexBuffer.pBuffer.get()->ptr, &renderDesc.m_vertexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create vertex buffer");

    hr = graphicsDevice->CreateIndexBuffer((uint)indexBuffer.stride, (uint)indexBuffer.numElements, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, ResourceAccess::Read, ResourceAccess::Write, indexBuffer.pBuffer.get()->ptr, &renderDesc.m_indexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create index buffer");

    hr = Renderer::CreateMaterial(std::to_string((uint64)meshInfo.materialId).c_str(), &renderDesc.m_material);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create the material");

    diffuseTexturePath = (contentPathA + material.info.diffuse + ".tc").c_str();

    hr = IO::ReadExistingFile(diffuseTexturePath.c_str(), &spStream);
    if (FAILED(hr))
    {
        DEBUG_PRINT("Failed to load diffuse texture file '%s', hr = 0x%lx",diffuseTexturePath.c_str(), hr);
        goto Exit;
    }

    hr = Graphics::CreateTextureFromStream(graphicsDevice, spStream, false, ResourceAccess::Read, ResourceAccess::None, &tex);
    if (FAILED(hr))
    {
        DEBUG_PRINT("Failed to create texture from diffuse texture file '%s', hr = 0x%lx",diffuseTexturePath.c_str(), hr);
        goto Exit;
    }
    
    renderDesc.m_material->SetTexture(TextureUsage::Diffuse, tex);

    if (material.info.normal.size() != 0)
    {
        normalTexturePath = (contentPathA + material.info.normal + ".tc").c_str();

        hr = IO::ReadExistingFile(normalTexturePath.c_str(), &spStream);
        if (FAILED(hr))
        {
            DEBUG_PRINT("Failed to load normal texture file '%s', hr = 0x%lx",normalTexturePath.c_str(), hr);
            goto Exit;
        }

        hr = Graphics::CreateTextureFromStream(graphicsDevice, spStream, false, ResourceAccess::Read, ResourceAccess::None, &tex);
        if (FAILED(hr))
        {
            DEBUG_PRINT("Failed to create texture from normal texture file '%s', hr = 0x%lx",normalTexturePath.c_str(), hr);
            goto Exit;
        }
    
        renderDesc.m_material->SetTexture(TextureUsage::Normal, tex);
    }

    renderDesc.m_material->SetSpecularPower(120.0f);

    // Add the buffers to the render collection
    m_buffers.push_back(renderDesc);

Exit:

    return hr;
}
Exemple #12
0
namespace FE
{
    const VertexElement MeshVertex::Elements[3] =
    {
        VertexElement("vPosition", 0, 0, VertexElement::Format_Float3),
        VertexElement("vNormal", 1, 12, VertexElement::Format_Float3),
        VertexElement("vTexCoord", 2, 24, VertexElement::Format_Float2)
    };

    SubMesh::SubMesh(const String &name)
        : Renderable(name),
        mMaterial(NULL),
        mRenderData(NULL)
    {
    }

    SubMesh::~SubMesh()
    {
        SafeDelete(mRenderData);

        mVertices.clear();
        mIndices.clear();
    }

    void SubMesh::AddVertex(const MeshVertex & vertex)
    {
        mVertices.push_back(vertex);
    }

    void SubMesh::AddVertices(MeshVertex * vertices, unsigned int numVertices)
    {
        for (unsigned int i = 0; i < numVertices; i++)
            mVertices.push_back(vertices[i]);
    }

    void SubMesh::AddIndex(short index)
    {
        mIndices.push_back(index);
    }

    void SubMesh::AddIndices(short * indices, unsigned int numIndices)
    {
        for (unsigned int i = 0; i < numIndices; i++)
            mIndices.push_back(indices[i]);
    }

    void SubMesh::SetMaterial(Material * mat)
    {
        mMaterial = mat;
    }

    bool SubMesh::Compile(GraphicsDevice *graphicsDevice)
    {
        if (mVertices.size() == 0)
            return true;

        SafeDelete(mRenderData);        

        VertexFormat *format = graphicsDevice->CreateVertexFormat(MeshVertex::Elements, 3);

        if (!format)
        {
            LogError("Unable to create vertex format for sub mesh: %s", mName.c_str());
            return false;
        }

        mRenderData = graphicsDevice->CreateRenderData();

        if (!mRenderData)
        {
            LogError("Unable to create render data for sub mesh: %s", mName.c_str());
            return false;
        }

        mRenderData->SetVertexFormat(format);

        int vbId = -1;

        if (!mRenderData->AddVertexBuffer(BufferUsage_Static, mVertices.size(), 
            mVertices.data(), &vbId))
        {
            LogError("Unable to add vertex buffer for sub mesh: %s", mName.c_str());
            return false;
        }

        if (mIndices.size() > 0)
        {
            int ibId = 0;

            if (!mRenderData->AddIndexBuffer(BufferUsage_Static, sizeof(short),
                mIndices.size(), mIndices.data(), &ibId))
            {
                LogError("Unable to add vertex buffer for sub mesh: %s", mName.c_str());
                return false;
            }

            mRenderData->SetCurrentIB(ibId);
        }

        mRenderData->SetPrimitiveType(PrimitiveType_TriangleList);
        mRenderData->SetCurrentVB(vbId);

        mAxisAlignedBox.Min = 99999.0f;
        mAxisAlignedBox.Max = -99999.0f;

        for (unsigned int i = 0; i < mVertices.size(); i++)
            mAxisAlignedBox.Include(mVertices[i].Position);

        return true;
    }
}
bool
ScreenOrientedQuad::initialize (const Ctr::Region2f& screenLocation, bool background)
{    
    setPrimitiveType (Ctr::TriangleStrip);
    setPrimitiveCount (2);
    setVertexCount (4);

    _screenLocation = screenLocation;
    uint32_t width = 1;
    uint32_t height = 1;

    //create vertex streams and vertex declaration information
    std::vector<VertexElement>       vertexElements;
    vertexElements.push_back (VertexElement( 0, 0,  FLOAT4, METHOD_DEFAULT, POSITION, 0));
    vertexElements.push_back (VertexElement( 0, 16, FLOAT2, METHOD_DEFAULT, TEXCOORD, 0));
    vertexElements.push_back (VertexElement(0xFF,0, UNUSED,0,0,0));

    float lhx = _screenLocation.minExtent.x * width;
    float lhy = _screenLocation.minExtent.y * height;
    float screenWidth = _screenLocation.size().x * width;
    float screenHeight = _screenLocation.size().y * height;

    float z = 0;
    float w = 1;

    if (background)
    {
        z = 1;
        w = 1;
    }

    Vector4f vpos[] = {Vector4f(lhx, lhy, z, w), 
                       Vector4f(lhx, lhy + screenHeight, z, w), 
                       Vector4f(lhx+screenWidth, lhy, z, w), 
                       Vector4f(lhx+screenWidth, lhy + screenHeight, z, w) };    

    Vector2f tpos[] = {Vector2f(0, 1), Vector2f(0, 0), 
                           Vector2f(1, 1), Vector2f(1, 0) };    

    if (IVertexDeclaration* vertexDeclaration =
        Ctr::VertexDeclarationMgr::vertexDeclarationMgr()->createVertexDeclaration
        (&VertexDeclarationParameters(vertexElements)))
    {
        setVertexDeclaration (vertexDeclaration);
        _positionStream = new Ctr::VertexStream
            (Ctr::POSITION, 0, 4, 4, (float*)vpos);
        _texCoordStream = new Ctr::VertexStream
            (Ctr::TEXCOORD, 0, 2, 4, (float*)tpos);

        addStream (_positionStream);
        addStream (_texCoordStream);

        if (create())
        {
            return cache();
        }
    }
    else
    {
        safedelete (vertexDeclaration);
        return false;
    }

    return false;
}
Exemple #14
0
bool Model::BeginLoad(Stream& source)
{
    /// \todo Develop own format for Turso3D
    if (source.ReadFileID() != "UMDL")
    {
        LOGERROR(source.Name() + " is not a valid model file");
        return false;
    }

    vbDescs.Clear();
    ibDescs.Clear();
    geomDescs.Clear();

    size_t numVertexBuffers = source.Read<unsigned>();
    vbDescs.Resize(numVertexBuffers);
    for (size_t i = 0; i < numVertexBuffers; ++i)
    {
        VertexBufferDesc& vbDesc = vbDescs[i];

        vbDesc.numVertices = source.Read<unsigned>();
        unsigned elementMask = source.Read<unsigned>();
        source.Read<unsigned>(); // morphRangeStart
        source.Read<unsigned>(); // morphRangeCount

        size_t vertexSize = 0;
        if (elementMask & 1)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR3, SEM_POSITION));
            vertexSize += sizeof(Vector3);
        }
        if (elementMask & 2)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR3, SEM_NORMAL));
            vertexSize += sizeof(Vector3);
        }
        if (elementMask & 4)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_UBYTE4, SEM_COLOR));
            vertexSize += 4;
        }
        if (elementMask & 8)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR2, SEM_TEXCOORD));
            vertexSize += sizeof(Vector2);
        }
        if (elementMask & 16)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR2, SEM_TEXCOORD, 1));
            vertexSize += sizeof(Vector2);
        }
        if (elementMask & 32)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR3, SEM_TEXCOORD));
            vertexSize += sizeof(Vector3);
        }
        if (elementMask & 64)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR3, SEM_TEXCOORD, 1));
            vertexSize += sizeof(Vector3);
        }
        if (elementMask & 128)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR4, SEM_TANGENT));
            vertexSize += sizeof(Vector4);
        }
        if (elementMask & 256)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_VECTOR4, SEM_BLENDWEIGHT));
            vertexSize += sizeof(Vector4);
        }
        if (elementMask & 512)
        {
            vbDesc.vertexElements.Push(VertexElement(ELEM_UBYTE4, SEM_BLENDINDICES));
            vertexSize += 4;
        }

        vbDesc.vertexData = new unsigned char[vbDesc.numVertices * vertexSize];
        source.Read(&vbDesc.vertexData[0], vbDesc.numVertices * vertexSize);
    }

    size_t numIndexBuffers = source.Read<unsigned>();
    ibDescs.Resize(numIndexBuffers);
    for (size_t i = 0; i < numIndexBuffers; ++i)
    {
        IndexBufferDesc& ibDesc = ibDescs[i];
    
        ibDesc.numIndices = source.Read<unsigned>();
        ibDesc.indexSize = source.Read<unsigned>();
        ibDesc.indexData = new unsigned char[ibDesc.numIndices * ibDesc.indexSize];
        source.Read(&ibDesc.indexData[0], ibDesc.numIndices * ibDesc.indexSize);
    }

    size_t numGeometries = source.Read<unsigned>();

    geomDescs.Resize(numGeometries);
    boneMappings.Resize(numGeometries);
    for (size_t i = 0; i < numGeometries; ++i)
    {
        // Read bone mappings
        size_t boneMappingCount = source.Read<unsigned>();
        boneMappings[i].Resize(boneMappingCount);
        /// \todo Should read as a batch
        for (size_t j = 0; j < boneMappingCount; ++j)
            boneMappings[i][j] = source.Read<unsigned>();

        size_t numLodLevels = source.Read<unsigned>();
        geomDescs[i].Resize(numLodLevels);

        for (size_t j = 0; j < numLodLevels; ++j)
        {
            GeometryDesc& geomDesc = geomDescs[i][j];

            geomDesc.lodDistance = source.Read<float>();
            source.Read<unsigned>(); // Primitive type
            geomDesc.primitiveType = TRIANGLE_LIST; // Always assume triangle list for now
            geomDesc.vbRef = source.Read<unsigned>();
            geomDesc.ibRef = source.Read<unsigned>();
            geomDesc.drawStart = source.Read<unsigned>();
            geomDesc.drawCount = source.Read<unsigned>();
        }
    }

    // Read (skip) morphs
    size_t numMorphs = source.Read<unsigned>();
    if (numMorphs)
    {
        LOGERROR("Models with vertex morphs are not supported for now");
        return false;
    }

    // Read skeleton
    size_t numBones = source.Read<unsigned>();
    bones.Resize(numBones);
    for (size_t i = 0; i < numBones; ++i)
    {
        Bone& bone = bones[i];
        bone.name = source.Read<String>();
        bone.parentIndex = source.Read<unsigned>();
        bone.initialPosition = source.Read<Vector3>();
        bone.initialRotation = source.Read<Quaternion>();
        bone.initialScale = source.Read<Vector3>();
        bone.offsetMatrix = source.Read<Matrix3x4>();

        unsigned char boneCollisionType = source.Read<unsigned char>();
        if (boneCollisionType & 1)
            bone.radius = source.Read<float>();
        if (boneCollisionType & 2)
            bone.boundingBox = source.Read<BoundingBox>();

        if (bone.parentIndex == i)
            rootBoneIndex = i;
    }

    // Read bounding box
    boundingBox = source.Read<BoundingBox>();

    return true;
}
Exemple #15
0
void Mesh::addVetexAttribute(unsigned int usage, unsigned int count)
{
    _vertexFormat.push_back(VertexElement(usage, count));
}
Exemple #16
0
namespace Urho3D
{

// The extern keyword is required when building Urho3D.dll for Windows platform
// The keyword is not required for other platforms but it does no harm, aside from warning from static analyzer

extern URHO3D_API const StringHash VSP_AMBIENTSTARTCOLOR("AmbientStartColor");
extern URHO3D_API const StringHash VSP_AMBIENTENDCOLOR("AmbientEndColor");
extern URHO3D_API const StringHash VSP_BILLBOARDROT("BillboardRot");
extern URHO3D_API const StringHash VSP_CAMERAPOS("CameraPos");
extern URHO3D_API const StringHash VSP_CLIPPLANE("ClipPlane");
extern URHO3D_API const StringHash VSP_NEARCLIP("NearClip");
extern URHO3D_API const StringHash VSP_FARCLIP("FarClip");
extern URHO3D_API const StringHash VSP_DEPTHMODE("DepthMode");
extern URHO3D_API const StringHash VSP_DELTATIME("DeltaTime");
extern URHO3D_API const StringHash VSP_ELAPSEDTIME("ElapsedTime");
extern URHO3D_API const StringHash VSP_FRUSTUMSIZE("FrustumSize");
extern URHO3D_API const StringHash VSP_GBUFFEROFFSETS("GBufferOffsets");
extern URHO3D_API const StringHash VSP_LIGHTDIR("LightDir");
extern URHO3D_API const StringHash VSP_LIGHTPOS("LightPos");
extern URHO3D_API const StringHash VSP_NORMALOFFSETSCALE("NormalOffsetScale");
extern URHO3D_API const StringHash VSP_MODEL("Model");
extern URHO3D_API const StringHash VSP_VIEW("View");
extern URHO3D_API const StringHash VSP_VIEWINV("ViewInv");
extern URHO3D_API const StringHash VSP_VIEWPROJ("ViewProj");
extern URHO3D_API const StringHash VSP_UOFFSET("UOffset");
extern URHO3D_API const StringHash VSP_VOFFSET("VOffset");
extern URHO3D_API const StringHash VSP_ZONE("Zone");
extern URHO3D_API const StringHash VSP_LIGHTMATRICES("LightMatrices");
extern URHO3D_API const StringHash VSP_SKINMATRICES("SkinMatrices");
extern URHO3D_API const StringHash VSP_VERTEXLIGHTS("VertexLights");
extern URHO3D_API const StringHash PSP_AMBIENTCOLOR("AmbientColor");
extern URHO3D_API const StringHash PSP_CAMERAPOS("CameraPosPS");
extern URHO3D_API const StringHash PSP_DELTATIME("DeltaTimePS");
extern URHO3D_API const StringHash PSP_DEPTHRECONSTRUCT("DepthReconstruct");
extern URHO3D_API const StringHash PSP_ELAPSEDTIME("ElapsedTimePS");
extern URHO3D_API const StringHash PSP_FOGCOLOR("FogColor");
extern URHO3D_API const StringHash PSP_FOGPARAMS("FogParams");
extern URHO3D_API const StringHash PSP_GBUFFERINVSIZE("GBufferInvSize");
extern URHO3D_API const StringHash PSP_LIGHTCOLOR("LightColor");
extern URHO3D_API const StringHash PSP_LIGHTDIR("LightDirPS");
extern URHO3D_API const StringHash PSP_LIGHTPOS("LightPosPS");
extern URHO3D_API const StringHash PSP_NORMALOFFSETSCALE("NormalOffsetScalePS");
extern URHO3D_API const StringHash PSP_MATDIFFCOLOR("MatDiffColor");
extern URHO3D_API const StringHash PSP_MATEMISSIVECOLOR("MatEmissiveColor");
extern URHO3D_API const StringHash PSP_MATENVMAPCOLOR("MatEnvMapColor");
extern URHO3D_API const StringHash PSP_MATSPECCOLOR("MatSpecColor");
extern URHO3D_API const StringHash PSP_NEARCLIP("NearClipPS");
extern URHO3D_API const StringHash PSP_FARCLIP("FarClipPS");
extern URHO3D_API const StringHash PSP_SHADOWCUBEADJUST("ShadowCubeAdjust");
extern URHO3D_API const StringHash PSP_SHADOWDEPTHFADE("ShadowDepthFade");
extern URHO3D_API const StringHash PSP_SHADOWINTENSITY("ShadowIntensity");
extern URHO3D_API const StringHash PSP_SHADOWMAPINVSIZE("ShadowMapInvSize");
extern URHO3D_API const StringHash PSP_SHADOWSPLITS("ShadowSplits");
extern URHO3D_API const StringHash PSP_LIGHTMATRICES("LightMatricesPS");
extern URHO3D_API const StringHash PSP_VSMSHADOWPARAMS("VSMShadowParams");
extern URHO3D_API const StringHash PSP_ROUGHNESS("Roughness");
extern URHO3D_API const StringHash PSP_METALLIC("Metallic");
extern URHO3D_API const StringHash PSP_LIGHTRAD("LightRad");
extern URHO3D_API const StringHash PSP_LIGHTLENGTH("LightLength");
extern URHO3D_API const StringHash PSP_ZONEMIN("ZoneMin");
extern URHO3D_API const StringHash PSP_ZONEMAX("ZoneMax");

extern URHO3D_API const Vector3 DOT_SCALE(1 / 3.0f, 1 / 3.0f, 1 / 3.0f);

extern URHO3D_API const VertexElement LEGACY_VERTEXELEMENTS[] =
{
    VertexElement(TYPE_VECTOR3, SEM_POSITION, 0, false),     // Position
    VertexElement(TYPE_VECTOR3, SEM_NORMAL, 0, false),       // Normal
    VertexElement(TYPE_UBYTE4_NORM, SEM_COLOR, 0, false),    // Color
    VertexElement(TYPE_VECTOR2, SEM_TEXCOORD, 0, false),     // Texcoord1
    VertexElement(TYPE_VECTOR2, SEM_TEXCOORD, 1, false),     // Texcoord2
    VertexElement(TYPE_VECTOR3, SEM_TEXCOORD, 0, false),     // Cubetexcoord1
    VertexElement(TYPE_VECTOR3, SEM_TEXCOORD, 1, false),     // Cubetexcoord2
    VertexElement(TYPE_VECTOR4, SEM_TANGENT, 0, false),      // Tangent
    VertexElement(TYPE_VECTOR4, SEM_BLENDWEIGHTS, 0, false), // Blendweights
    VertexElement(TYPE_UBYTE4, SEM_BLENDINDICES, 0, false),  // Blendindices
    VertexElement(TYPE_VECTOR4, SEM_TEXCOORD, 4, true),      // Instancematrix1
    VertexElement(TYPE_VECTOR4, SEM_TEXCOORD, 5, true),      // Instancematrix2
    VertexElement(TYPE_VECTOR4, SEM_TEXCOORD, 6, true),      // Instancematrix3
    VertexElement(TYPE_INT, SEM_OBJECTINDEX, 0, false)      // Objectindex
};

extern URHO3D_API const unsigned ELEMENT_TYPESIZES[] =
{
    sizeof(int),
    sizeof(float),
    2 * sizeof(float),
    3 * sizeof(float),
    4 * sizeof(float),
    sizeof(unsigned),
    sizeof(unsigned)
};


}
void CitySceneGenerator::generate(Scene* scene) {
	auto renderer = scene->renderer();
	auto material = std::make_shared<PhongMaterial>(renderer);
	material->setShader(renderer->shaderManager()->getGlslProgram("phong"));

	PhongMaterialData materialData = { glm::vec4(0.0f, 0.1f, 0.0f, 1.0f), 
		glm::vec4(0.8f, 0.3f, 0.1f, 1.0f), glm::vec4(0.3f, 0.3f, 0.3f, 1.0f), 5.0f };

	material->properties()->setData(materialData);
	material->properties()->flushData();

	auto mesh = std::make_shared<Mesh>();
	mesh->setPrimitiveType(PrimitiveType::TriangleList);

	size_t buildingVerticesCount = sizeof(buildingVertices) / sizeof(*buildingVertices);
	std::vector<char> vertices(reinterpret_cast<const char*>(buildingVertices), 
		reinterpret_cast<const char*>(buildingVertices) + sizeof(buildingVertices));
	std::vector<VertexElement> layout = {
		VertexElement(3, VertexElementType::Float),
		VertexElement(3, VertexElementType::Float)
	};
	mesh->loadVertices(vertices, buildingVerticesCount, layout);

	size_t buildingIndicesCount = sizeof(buildingIndices) / sizeof(*buildingIndices);
	std::vector<uint32_t> indices(reinterpret_cast<const unsigned*>(buildingIndices), 
		reinterpret_cast<const unsigned*>(buildingIndices) + buildingIndicesCount);
	mesh->loadIndices(indices);

	size_t numBuildings = 1000;
	float citySize = 500.0f;
	float minBuildingSize = 10.0f;
	float maxBuildingSize = 60.0f;
	float minHeightToWidthRatio = 8.0f;
	float maxHeightToWidthRatio = 16.0f;

	std::uniform_real_distribution<float> angleDist(0.0f, 360.0f);
	std::uniform_real_distribution<float> positionDist(-citySize, citySize);
	std::uniform_real_distribution<float> canonicalDist;

	std::vector<std::shared_ptr<BaseSceneObject>> buildings;
	for (size_t i = 0; i < numBuildings; i++) {
		auto building = std::make_shared<Building>(mesh, material);

		// set random position
		glm::mat4 model = glm::translate(glm::mat4(1.0f),
			glm::vec3(positionDist(m_rng), positionDist(m_rng), 0.0f)
		);

		// rotate around z with random angle
		model = glm::rotate(model, angleDist(m_rng), glm::vec3(0.0f, 0.0f, 1.0f));

		glm::vec3 scale;
		// multiplying uniform distribution will generate beta distribution
		scale.x = canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng)
			* (maxBuildingSize - minBuildingSize) + minBuildingSize;
		scale.y = scale.x;
		scale.z = canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * scale.x
			* (maxHeightToWidthRatio - minHeightToWidthRatio) + minHeightToWidthRatio;
		model = glm::scale(model, scale);

		building->setModelMatrix(model);
		building->calculateBBox();

		buildings.push_back(building);
	}

	scene->setStaticGeometry(std::move(buildings));
}
Exemple #18
0
    // Helper function for common constructor code-paths
    void Obj::constructionHelper(const AssetLibrary &assetLibrary, const char *path, const char *fileName, int expectedVertexDataNum, int expectedFaceNum) {
	// Save the path of the file that will be opened
	objPath = std::string(path);
        OMLOGI("Opening input stream for %s%s", path, fileName);
        std::unique_ptr<std::istream> input = assetLibrary.getAssetStream(path, fileName);

        OMLOGI("Initializing data vectors (expectedVertexDataNum:%d, expectedFaceNum:%d)", expectedVertexDataNum, expectedFaceNum);
        // Initialize vectors with some meaningful default sizes
        vs = std::vector<VertexElement>();
        vs.reserve(expectedVertexDataNum);
        vts = std::vector<VertexTextureElement>();
        vts.reserve(expectedVertexDataNum);
        vns = std::vector<VertexNormalElement>();
        vns.reserve(expectedVertexDataNum);
        fs = std::vector<FaceElement>();
        fs.reserve(expectedFaceNum);

        // We are holding the current material in this variable
        // Can be updated by usemtl descriptors!
        TextureDataHoldingMaterial currentMaterial;
        // We are holding the name of the current object/group here. In case there is no group
        // this can be safely the empty string.
        std::string currentObjectGroupName;
        // This holds the current pointer to the start of the faces in case of the material and/or
        // object grouping...
        int currentObjectMaterialFacesPointer = 0;
        // We hold the pointer to the last of the faces for pointer arithmetics common to the
        // various cases below
        int currentLastFacesPointer = 0;

        // Parse the given file line-by-line
        OMLOGI("Reading obj data file line-by-line");
        char line[DEFAULT_LINE_PARSE_LEN];
        while(input->getline(line, DEFAULT_LINE_PARSE_LEN)) {
            currentLastFacesPointer =( int)fs.size();;
            if(VertexElement::isParsable(line)) {
                // v
                VertexElement v = VertexElement((const char*)line);
                vs.push_back(v);
#ifdef DEBUG
OMLOGI(" - Added VertexElement: (%f, %f, %f)", v.x, v.y, v.z);
#endif
            } else if(VertexTextureElement::isParsable(line)) {
                // vt
                vts.push_back(VertexTextureElement((const char*)line));
            } else if(VertexNormalElement::isParsable(line)) {
                // vn
                vns.push_back(VertexNormalElement((const char*)line));
            } else if(FaceElement::isParsable(line)) {
		// TODO: implement N-gons here 
                // f
                fs.push_back(FaceElement((const char*)line));
            } else if(MtlLib::isParsable(line)) {
                // mtllib
                mtlLib = MtlLib(line, path, assetLibrary);
            } else if(UseMtl::isParsable(line)) {
                // usemtl
                // End the collection of the currentObjectMaterialFaceGroup
                extendObjectMaterialGroups(currentObjectGroupName,
                                           currentMaterial,
                                           currentObjectMaterialFacesPointer,
                                           currentLastFacesPointer - currentObjectMaterialFacesPointer);

                // Rem.: This copy is cheap as it does not contain texture data etc!
                currentMaterial = mtlLib.getNonLoadedMaterialFor(UseMtl::fetchMtlName(line));
#ifdef DEBUG
OMLOGI(" - Using current-material: %s", currentMaterial.name);
#endif
                // Set the current face start pointer to the current position
                // so that the faces will be "collected" for the group
                // BEWARE: This let us overindex the array if no faces are coming!!!
                //         We need to check this overindexint below!
                currentObjectMaterialFacesPointer = (int)fs.size();
            } else if(ObjectGroupElement::isParsable(line)) {
                // o
                // End the collection of the currentObjectMaterialFaceGroup
                extendObjectMaterialGroups(currentObjectGroupName,
                                           currentMaterial,
                                           currentObjectMaterialFacesPointer,
                                           currentLastFacesPointer - currentObjectMaterialFacesPointer);
                currentObjectGroupName = ObjectGroupElement::getObjectGroupName(line);
#ifdef DEBUG
OMLOGI(" - Start of object group: %s", currentObjectGroupName);
#endif
                // Set the current face start pointer to the current position
                // so that the faces will be "collected" for the group
                // BEWARE: This let us overindex the array if no faces are coming!!!
                //         We need to check this overindexint below!
                currentObjectMaterialFacesPointer = (int)fs.size();
            } else {
                OMLOGW("Cannot parse line: %s", line);
            }
        }
        // End the collection of the currentObjectMaterialFaceGroup by extending with the elements
        // of the last obj/material group (and pointer update is necessary here too!)
        currentLastFacesPointer = (int)fs.size();
        extendObjectMaterialGroups(currentObjectGroupName,
                                   currentMaterial,
                                   currentObjectMaterialFacesPointer,
                                   currentLastFacesPointer - currentObjectMaterialFacesPointer);

        OMLOGI("Finished loading of Obj data.");
        OMLOGI(" - Read vertices: %d", (int)vs.size());
        OMLOGI(" - Read vertex-textures: %d", (int)vts.size());
        OMLOGI(" - Read vertex-normals: %d", (int)vns.size());
        OMLOGI(" - Read faces: %d", (int)fs.size());
        OMLOGI(" - Read materials: %d", mtlLib.getMaterialCount());
        OMLOGI(" - Read object/material groups: %d", (int)objectMaterialGroups.size());
    }
	void VertexDeclaration::AddElement(eVertexSemantic semantic, eVertexType type)
	{
		mElements.PushBack(VertexElement(semantic, type));
	}
HRESULT CLucid3DRenderer::AddContent(GraphicsDevicePtr graphicsDevice, std::wstring& contentPath, ITextureContentPtr pTextureContent)
{
    Clear();

    HRESULT hr = S_OK;
    std::string textureName;
    std::wstring textureNameW;
    Lucid3DRenderBufferDesc renderDesc;
    InputStreamPtr spStream;
    TexturePtr tex;
    WCHAR szTempPath[MAX_PATH] = {0};
    WCHAR szTempFile[MAX_PATH] = {0};

    pTextureContent->GetTextureName(textureNameW);
    textureName = WideToAnsi(textureNameW);

    XMProjSpaceVertex vertices[] = 
    {
        { XMFLOAT2(-1, 1), XMFLOAT2(0, 0) },
        { XMFLOAT2(1, 1), XMFLOAT2(1, 0) },
        { XMFLOAT2(1, -1), XMFLOAT2(1, 1) },
        { XMFLOAT2(-1, -1), XMFLOAT2(0, 1) },
    };

    uint32 indices[] = { 0, 1, 2, 0, 2, 3 };

    VertexElement layout[] =
    {
        VertexElement(0, VertexChannelType::Float2, VertexChannelSemantic::Position, false),
        VertexElement(0, VertexChannelType::Float2, VertexChannelSemantic::TexCoord0, false),
    };

    hr = graphicsDevice->CreateVertexBuffer(sizeof(XMProjSpaceVertex), _countof(vertices), layout, _countof(layout), ResourceAccess::Read, ResourceAccess::None, vertices, &renderDesc.m_vertexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create vertex buffer");

    hr = graphicsDevice->CreateIndexBuffer(sizeof(indices[0]), _countof(indices), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, ResourceAccess::Read, ResourceAccess::None, indices, &renderDesc.m_indexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create index buffer");

    hr = Renderer::CreateMaterial(textureName.c_str(), &renderDesc.m_material);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create the material");

    // HACK: HACK: Coop, I'm not familiar enough with this to do the 'right' way of loading the .tc
    // so I'm hacking it up good :) you can fix this later if you want
    GetTempPath(ARRAYSIZE(szTempPath), szTempPath);
    GetTempFileName(szTempPath, L"", 0, szTempFile);
    pTextureContent->SaveToFile(szTempFile);

    hr = IO::ReadExistingFile(WideToAnsi(std::wstring(szTempFile)).c_str(), &spStream);
    if (FAILED(hr))
    {
        DEBUG_PRINT("Failed to load diffuse texture file '%s', hr = 0x%lx",szTempFile, hr);
        goto Exit;
    }

    hr = Graphics::CreateTextureFromStream(graphicsDevice, spStream, false, ResourceAccess::Read, ResourceAccess::None, &tex);
    if (FAILED(hr))
    {
        DEBUG_PRINT("Failed to create texture from diffuse texture file '%s', hr = 0x%lx", szTempFile, hr);
        goto Exit;
    }

    renderDesc.m_material->SetTexture(TextureUsage::Diffuse, tex);

    // Add the buffers to the render collection
    m_buffers.push_back(renderDesc);

Exit:

    return hr;
}
HRESULT CLucid3DRenderer::AddContent(GraphicsDevicePtr graphicsDevice, std::wstring& contentPath, ISpriteFontContentPtr pSpriteFontContent)
{
    Clear();

    HRESULT hr = S_OK;
    std::string spriteFontName;
    std::wstring spriteFontNameW;
    Lucid3DRenderBufferDesc renderDesc;
    InputStreamPtr spStream;
    TexturePtr tex;

    BYTE* pData = nullptr;
    DWORD cbData = 0;

    pSpriteFontContent->GetSpriteFontName(spriteFontNameW);
    spriteFontName = WideToAnsi(spriteFontNameW);

    XMProjSpaceVertex vertices[] = 
    {
        { XMFLOAT2(-1, 1), XMFLOAT2(0, 0) },
        { XMFLOAT2(1, 1), XMFLOAT2(1, 0) },
        { XMFLOAT2(1, -1), XMFLOAT2(1, 1) },
        { XMFLOAT2(-1, -1), XMFLOAT2(0, 1) },
    };

    uint32 indices[] = { 0, 1, 2, 0, 2, 3 };

    VertexElement layout[] =
    {
        VertexElement(0, VertexChannelType::Float2, VertexChannelSemantic::Position, false),
        VertexElement(0, VertexChannelType::Float2, VertexChannelSemantic::TexCoord0, false),
    };

    hr = graphicsDevice->CreateVertexBuffer(sizeof(XMProjSpaceVertex), _countof(vertices), layout, _countof(layout), ResourceAccess::Read, ResourceAccess::None, vertices, &renderDesc.m_vertexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create vertex buffer");

    hr = graphicsDevice->CreateIndexBuffer(sizeof(indices[0]), _countof(indices), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, ResourceAccess::Read, ResourceAccess::None, indices, &renderDesc.m_indexBuffer);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create index buffer");

    hr = Renderer::CreateMaterial(spriteFontName.c_str(), &renderDesc.m_material);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to create the material");

    // Get a stream to the DDS data stored in the spritefont content
    hr = pSpriteFontContent->GetTextureData(&pData, &cbData);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to get texture data from spritefont content");

    hr = IO::CreateInputStreamOnBuffer(pData, cbData, &spStream);
    GOTO_EXIT_IF_FAILED_MESSAGE(hr, "Failed to get create lucid memory stream for texture data from spritefont content");

    hr = Graphics::CreateTextureFromStream(graphicsDevice, spStream, false, ResourceAccess::Read, ResourceAccess::None, &tex);
    if (FAILED(hr))
    {
        DEBUG_PRINT("Failed to create texture from spritefont texture data, hr = 0x%lx", hr);
        goto Exit;
    }

    renderDesc.m_material->SetTexture(TextureUsage::Diffuse, tex);

    // Add the buffers to the render collection
    m_buffers.push_back(renderDesc);

Exit:

    SAFE_DELETE_ARRAY(pData);

    return hr;
}
Exemple #22
0
	bool DX9RenderSystem::Init( HWND hwnd, int width, int height, bool fullscreen, int msquality )
	{
		mSize.x = width;
		mSize.y = height;

		mD3d = Direct3DCreate9( D3D_SDK_VERSION );

		D3DPRESENT_PARAMETERS pp = { 0 };
		pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
		pp.EnableAutoDepthStencil = TRUE;
		pp.AutoDepthStencilFormat = D3DFMT_D24X8;
		pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

		if( msquality >= 0 )
		{
			pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE;
			pp.MultiSampleQuality = msquality;
		}

		if( fullscreen )
		{
			pp.Windowed = false;
			pp.BackBufferCount = 1;
			pp.BackBufferWidth = width;
			pp.BackBufferHeight = height;
			pp.BackBufferFormat = D3DFMT_X8R8G8B8;
		}
		else
		{
			D3DDISPLAYMODE currentmode;
			if( FAILED(mD3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &currentmode )) )
				return false;

			// Set up windowed formatting
			pp.Windowed = true;
			pp.BackBufferCount = 1;
			pp.BackBufferFormat = currentmode.Format;
		}

		UINT adapterid = D3DADAPTER_DEFAULT;	
		D3DDEVTYPE rendertype = D3DDEVTYPE_HAL;

		int adaptercount = (int)mD3d->GetAdapterCount( );
		for( int i = 0; i < adaptercount; i++ )
		{
			D3DADAPTER_IDENTIFIER9 info;
			mD3d->GetAdapterIdentifier( i, 0, &info );
			
			if( strstr( info.Description, "PerfHUD" ) )
			{
				adapterid = i;
				rendertype = D3DDEVTYPE_REF;
				printf( "PerfHUD found on adapter %d (%s)\n", i, info.Description );
			}
		}

		if( FAILED(mD3d->CreateDevice( adapterid, rendertype, hwnd,
			D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &mDevice )) )
			return false;

		for( int i = 0; i < 8; i++ )
			mDevice->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC );

		// Initialize 2d Rendering Stuff
		m2dDecl = new VertexDeclaration( );
		m2dDecl->AddElement( VertexElement( 0, VDeclSemantic::POSITION, VDeclType::FLOAT3, 0 ) );
		m2dDecl->AddElement( VertexElement( 0, VDeclSemantic::TEXCOORD, VDeclType::FLOAT2, 0 ) );
		m2dDecl->AddElement( VertexElement( 0, VDeclSemantic::COLOUR, VDeclType::COLOUR, 0 ) );

		m2dMat = new Material( );
		m2dMat->mAlphaBlend = true;
		m2dMat->mAlphaTest = true;
		m2dMat->mDepthWrite = true;
		m2dMat->mDepthBuffer = false;
		m2dMat->AddTextureStage(
			TextureStage(
				0,
				BlendMode( BlendOp::SELECTARGUMENT1, BlendArg::TEXTURE, BlendArg::DIFFUSE ),
				BlendMode( BlendOp::SELECTARGUMENT1, BlendArg::TEXTURE, BlendArg::DIFFUSE )
			)
		);

		return true;
	};
void SkyBox::load( const he::String& asset )
{
    HE_ASSERT(m_Drawable == nullptr, "Skybox is loaded twice!");
    m_Drawable = HENew(Drawable)();
    m_Drawable->setLocalScale(vec3(1000000000)); // bounds must be huge
    //////////////////////////////////////////////////////////////////////////
    /// Load Model
    //////////////////////////////////////////////////////////////////////////
    ModelMesh* const cube(
        ResourceFactory<gfx::ModelMesh>::getInstance()->get(ResourceFactory<gfx::ModelMesh>::getInstance()->create()));
    cube->setName(he::String("skybox-") + asset);
    he::PrimitiveList<vec3> vertices(8);
    vertices.add(vec3(-1,  1, -1));
    vertices.add(vec3( 1,  1, -1));
    vertices.add(vec3(-1, -1, -1));
    vertices.add(vec3( 1, -1, -1));

    vertices.add(vec3(-1,  1,  1));
    vertices.add(vec3( 1,  1,  1));
    vertices.add(vec3(-1, -1,  1));
    vertices.add(vec3( 1, -1,  1));

    he::PrimitiveList<uint16> indices(36);
    indices.add(0); indices.add(1); indices.add(2); //front
    indices.add(1); indices.add(3); indices.add(2);

    indices.add(5); indices.add(4); indices.add(7); //back
    indices.add(4); indices.add(6); indices.add(7);

    indices.add(4); indices.add(0); indices.add(6); //left
    indices.add(0); indices.add(2); indices.add(6);

    indices.add(1); indices.add(5); indices.add(3); //right
    indices.add(5); indices.add(7); indices.add(3);

    indices.add(4); indices.add(5); indices.add(0); //top
    indices.add(5); indices.add(1); indices.add(0);

    indices.add(3); indices.add(7); indices.add(2); //bottom
    indices.add(7); indices.add(6); indices.add(2);

    VertexLayout layout;
    layout.addElement(VertexElement(eShaderAttribute_Position, eShaderAttributeType_Float, eShaderAttributeTypeComponents_3, 0));
    cube->init(layout, MeshDrawMode_Triangles);
    cube->setVertices(&vertices[0], static_cast<uint32>(vertices.size()), MeshUsage_Static, false);
    cube->setIndices(&indices[0], static_cast<uint32>(indices.size()), IndexStride_UShort, MeshUsage_Static);
    cube->setLoaded(eLoadResult_Success);
    m_Drawable->setModelMesh(cube);
    cube->release();

    Material* const material(CONTENT->loadMaterial("engine/sky.material"));
    m_Drawable->setMaterial(material);
    material->release();

    const int8 cubeMap(m_Drawable->getMaterial()->findParameter(HEFS::strcubeMap));
    if (cubeMap >= 0)
    {
        const TextureCube* cube(CONTENT->asyncLoadTextureCube(asset));
        m_Drawable->getMaterial()->getParameter(cubeMap).setTextureCube(cube);
        cube->release();
    }
}