void PrimitiveShapeRenderer::RenderWireframeBox( const Vector3& vEdgeLengths, const Matrix34& world_pose, const SFloatRGBAColor& wireframe_color )
{
	if( !sg_NoLightingShader.IsLoaded() )
		sg_NoLightingShader = GetNoLightingShader();

	// Wireframes are always rendered without lighting
	ShaderManager *pShaderMgr = sg_NoLightingShader.GetShaderManager();

//	ShaderManager *pShaderMgr = GetShaderManagerForPrimitiveShape();

	if( !pShaderMgr )
		return;

	ShaderManager& shader_mgr = *pShaderMgr;

	Result::Name res = shader_mgr.SetTexture( 0, GetSingleColorWhiteTexture() );
	res = shader_mgr.SetTexture( 1, GetSingleColorWhiteTexture() );

	Vector3 r( vEdgeLengths * 0.5f );
	shader_mgr.SetWorldTransform( ToMatrix44(world_pose) * Matrix44Scaling(r.x,r.y,r.z) );

//	Vector3 radii = vEdgeLengths * 0.5f;
	Vector3 vertices[8] =
	{
		Vector3( 1, 1, 1),// * radii,
		Vector3( 1, 1,-1),// * radii,
		Vector3(-1, 1,-1),// * radii,
		Vector3(-1, 1, 1),// * radii,
		Vector3( 1,-1, 1),// * radii,
		Vector3( 1,-1,-1),// * radii,
		Vector3(-1,-1,-1),// * radii,
		Vector3(-1,-1, 1),// * radii,
	};
/*
	uint indices[24] =
	{
		0, 1, 1, 2, 2, 3, 3, 0,
		0, 1, 1, 2, 2, 3, 3, 0,
		0, 1, 1, 2, 2, 3, 3, 0
	};

	GetPrimitiveRenderer().DrawIndexedLines( vertices, 8, indices, 24, wireframe_color );
*/
	Vector3 *v = vertices;
	const Vector3 points[24] =
	{
		v[0], v[1], v[1], v[2], v[2], v[3], v[3], v[0],
		v[0], v[4], v[1], v[5], v[2], v[6], v[3], v[7],
		v[4], v[5], v[5], v[6], v[6], v[7], v[7], v[4],
	};

	shader_mgr.Begin();

	const int num_edges = 12;
	for( int i=0; i<num_edges; i++ )
	{
		GetPrimitiveRenderer().DrawLine( points[i*2], points[i*2+1], wireframe_color, wireframe_color );
	}
}
ShaderManager *PrimitiveShapeRenderer::GetShaderManagerForPrimitiveShape()
{
	ShaderManager *pShaderMgr = m_Shader.GetShaderManager();

	if( pShaderMgr )
		return pShaderMgr;

	if( !sg_NoLightingShader.IsLoaded() )
		sg_NoLightingShader = GetNoLightingShader();

	return sg_NoLightingShader.GetShaderManager();
}
// Initializes CCopyEntity::m_pMeshRenderMethod
// - Initialize the mesh render method
// - Initialize shader parameter loaders
// - Create alpha entities
// - Creates a shader
void BaseEntity::InitEntityGraphics( CCopyEntity &entity,
                                      ShaderHandle& shader,
                                      ShaderTechniqueHandle& tech )
{
	if( shader.IsLoaded()
	 && tech.GetTechniqueName()
	 && 0 < strlen(tech.GetTechniqueName()) )
	{
		CreateMeshRenderMethod( EntityHandle<>( entity.Self() ), shader, tech );
	}
	else
	{
		InitMeshRenderMethod( entity );
	}

	// create transparent parts of the model as separate entities
	if( m_EntityFlag & BETYPE_SUPPORT_TRANSPARENT_PARTS )
	{
		// Remove any previous alpha entities
		int next_child_index = 0;
		while( next_child_index < entity.GetNumChildren() )
//		for( int i=0; i<entity.GetNumChildren(); i++ )
		{
			shared_ptr<CCopyEntity> pChild = entity.m_aChild[next_child_index].Get();
			if( IsValidEntity(pChild.get())
			 && pChild->GetEntityTypeID() == CCopyEntityTypeID::ALPHA_ENTITY )
			{
				CCopyEntity *pChildRawPtr = pChild.get();
				m_pStage->TerminateEntity( pChildRawPtr );
			}
			else
				next_child_index += 1;
		}

		CreateAlphaEntities( &entity );
	}

	shared_ptr<BasicMesh> pMesh = entity.m_MeshHandle.GetMesh();
	if( !pMesh )
		return;

	BasicMesh& mesh = *pMesh;
	const int num_mesh_materials = mesh.GetNumMaterials();

	std::vector<GenericShaderDesc> shader_descs;
	shader_descs.resize( num_mesh_materials );

	std::vector<int> mirror_subsets_indices;
//	std::vector<int> non_mirror_subsets_indices;

	if( m_MeshProperty.m_MeshDesc.IsValid() )
//	if( true )
	{
		// The mesh is specified in the base entity
	}
	else
	{
		// base entity has no mesh
		// - entity's mesh is individual
		shader_descs.resize( num_mesh_materials );
		for( int i=0; i<num_mesh_materials; i++ )
		{
			// Fill out the shader desc based on the parameter values of the material

			// reflection
			bool registered_as_mirror = RegisterAsMirrorIfReflective( entity, mesh, i, shader_descs[i] );
			if( registered_as_mirror )
				mirror_subsets_indices.push_back( i );

			// specularity
			if( 0.001f < mesh.GetMaterial(i).m_Mat.fSpecularity )
				shader_descs[i].Specular = SpecularSource::UNIFORM;
			else
				shader_descs[i].Specular = SpecularSource::NONE;
		}

		vector< pair< GenericShaderDesc, vector<unsigned int> > > grouped_descs;
		group_elements( shader_descs, grouped_descs );

		// Do a NULL check just in case
		// The mesh render method is initialized by InitMeshRenderMethod() above.
		if( !entity.m_pMeshRenderMethod )
			entity.m_pMeshRenderMethod.reset( new MeshContainerRenderMethod );

		bool shader_loaded = false;
		if( grouped_descs.size() == 1 )
		{
			SubsetRenderMethod& render_method = entity.m_pMeshRenderMethod->PrimaryMeshRenderMethod();

			render_method.m_Technique.SetTechniqueName( "Default" );
			render_method.m_ShaderDesc.pShaderGenerator.reset( new GenericShaderGenerator( grouped_descs[0].first ) );

//			shader_loaded = render_method.Load();
			shader_loaded = render_method.m_Shader.Load( render_method.m_ShaderDesc );
		}
		else
		{
			LOG_PRINT_WARNING( "Mesh materials need different shaders. This situation is not supported yet (the total number of materials: " + to_string(num_mesh_materials) + ")." );
		}
	}
}