#ifndef BILLBOARD_H #define BILLBOARD_H namespace fw { template<class D3DVersion> class Billboard : public D3DMeshSceneNode<D3DVersion> { public: typedef typename D3DMeshSceneNode<D3DVersion> D3DMeshSceneNode; Billboard(const D3DXCOLOR& colorBottom, const D3DXCOLOR& colorTop, float width, float height) : D3DMeshSceneNode("Billboard") { m_fWidth = width; m_fHeight = height; m_indices.resize(6); m_indices[0] = 0; m_indices[1] = 2; m_indices[2] = 1; m_indices[3] = 0; m_indices[4] = 3; m_indices[5] = 2; m_vertices.resize(4); m_vertices[0].texture.x = 1.0f; m_vertices[0].texture.y = 1.0f; m_vertices[0].color = colorBottom; m_vertices[1].texture.x = 1.0f; m_vertices[1].texture.y = 0.0f; m_vertices[1].color = colorTop; m_vertices[2].texture.x = 0.0f; m_vertices[2].texture.y = 0.0f; m_vertices[2].color = colorTop; m_vertices[3].texture.x = 0.0f; m_vertices[3].texture.y = 1.0f; m_vertices[3].color = colorBottom; D3DMeshSceneNode::SetVertexType(VertexLayoutType::PTC_VERTEX); D3DMeshSceneNode::SetDrawMethod(D3DMeshSceneNode::Renderable::DrawMethod::DRAW_INDEXED); D3DMeshSceneNode::SetTopology(D3D_PRIMITIVE_TOPOLOGY::D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3DMeshSceneNode::SetIndexFormat(D3DMeshSceneNode::Renderable::FORMAT_16_BIT); D3DMeshSceneNode::SetShaderTechnique( SHADER_MANAGER->GetShader("Billboard") ); D3DMeshSceneNode::VBuildMesh(m_vertices, m_indices); } virtual ~Billboard() { } virtual bool OnRender(float fTimeSinceLastFrame) override { D3DXVECTOR3 pos = D3DMeshSceneNode::GetPosition(); D3DXVECTOR3 campos = SCENE_MANAGER->GetActiveCamera()->GetPosition(); D3DXVECTOR3 target = SCENE_MANAGER->GetActiveCamera()->GetTarget(); D3DXVECTOR3 up = SCENE_MANAGER->GetActiveCamera()->GetUpVector(); D3DXVECTOR3 view = target - campos; D3DXVec3Normalize(&view, &view); D3DXVECTOR3 horizontal; D3DXVec3Cross(&horizontal, &up, &view); if (D3DXVec3Length(&horizontal) == 0) { horizontal.x = up.y; horizontal.y = up.x; horizontal.z = up.z; } D3DXVec3Normalize(&horizontal, &horizontal); horizontal *= 0.5f * m_fWidth; D3DXVECTOR3 vertical; D3DXVec3Cross(&vertical, &horizontal, &view); D3DXVec3Normalize(&vertical, &vertical); vertical *= 0.5f * m_fHeight; m_vertices[0].pos = pos + horizontal + vertical; m_vertices[1].pos = pos + horizontal - vertical; m_vertices[2].pos = pos - horizontal - vertical; m_vertices[3].pos = pos - horizontal + vertical; D3DMeshSceneNode::VUpdateMeshVertices(m_vertices); D3DMeshSceneNode::OnRender(fTimeSinceLastFrame); return true; } void SetColor(const D3DXCOLOR& colorBottom, const D3DXCOLOR& colorTop) { m_vertices[0].color = colorBottom; m_vertices[1].color = colorTop; m_vertices[2].color = colorTop; m_vertices[3].color = colorBottom; } void SetTexture(const std::string& sTextureFileName) { ShaderSceneNodeInfo param; param.SetTexture(sTextureFileName); D3DMeshSceneNode::PushCustomShaderParameter(param); } private: std::vector<PTCVertex> m_vertices; std::vector<uint16> m_indices; float m_fWidth; float m_fHeight; }; } #endif