//--------------------------------------------------------------------------------------
// Copyright (C) 2008 http://shift.delblanco.es
//--------------------------------------------------------------------------------------
// SHIFT Videogame is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//--------------------------------------------------------------------------------------
/// \file 3DMesh.h
/// Para manejar los modelos gráficos de los objetos de la escena.
/// Cada objeto de la escena puede tener asociado un modelo gráfico, todas las
/// operaciones relacionadas con los modelos gráficos se manejan desde este módulo
//--------------------------------------------------------------------------------------
#pragma once
#ifndef __C3DMESH_H__
#define __C3DMESH_H__

//--------------------------------------------------------------------------------------
// Ficheros de cabecera
//--------------------------------------------------------------------------------------
#include <vector>
class C3DMesh;
class C3DObject;

//--------------------------------------------------------------------------------------
// Constantes
//--------------------------------------------------------------------------------------
/// Tipo de geometría no transparente (tipo 0)
#define       MESH_ALPHA_NON            0
/// Tipo de geometría transparente ante cámara persecutoria (tipo 1)
#define       MESH_ALPHA_CAM            1
/// Tipo de geometría transparente siempre (tipo 2)
#define       MESH_ALPHA_YES            2

//--------------------------------------------------------------------------------------
// Tipos definidos
//--------------------------------------------------------------------------------------
/// Estructura para almacenar por cada geometría de objeto en memoria,
/// para evitar cargar dos veces la misma
typedef struct
{
    LPWSTR                          MeshPath;               ///< Path dónde se encuentra el modelo gráfico
    LPD3DXMESH						Mesh;			        ///< Geometria
    std::vector<D3DMATERIAL9>		*Mtrls;                 ///< Lista de Materiales
    std::vector<IDirect3DTexture9*>	*Textures;              ///< Lista de Texturas
    unsigned short					num;		            ///< Número de referencias que tiene la geometría del objeto
} SMeshEntry;

//--------------------------------------------------------------------------------------
/// Clase para manejar los modelos gráficos de la escena.
//--------------------------------------------------------------------------------------
class C3DMesh
{
friend C3DObject;

protected:  // Campos miembro

    bool                            m_bInit;                ///< Flag que indica si el objeto está inicializado
    IDirect3DDevice9*               m_pDevice;              ///< Puntero al dispositivo de DirectX
    C3DObject                       *m_pObject;             ///< Objeto asociado a este modelo gráfico
	int								m_iAlpha;				///< Tipo de transparencia de la geometría

    // Solo habrá una copia en memoria por cada tipo de modelo gráfico para cada una de estas estructuras
    LPWSTR                          m_awMeshPath;           ///< Path dónde se encuentra el modelo gráfico
    LPD3DXMESH						m_pMesh;			    ///< Geometria
    std::vector<D3DMATERIAL9>		*m_aMtrls;              ///< Lista de Materiales
    std::vector<IDirect3DTexture9*>	*m_aTextures;           ///< Lista de Texturas

    /// Constructor privado, sólo se podrá crear desde una instancia 3DObject
    C3DMesh();
    /// Destructor
    ~C3DMesh();

public: // Métodos públicos

    /// Inicializa el modelo gráfico
    bool initialize(C3DObject *dObject, LPCWSTR MeshPath, int dAlpha);
    /// Renderiza el modelo gráfico
    void render(bool force = false);
    /// Libera el modelo gráfico
    void Release();

    /// Función observadora del objeto asociado
    C3DObject						*getObject(void)		{return m_pObject;}

    /// Función observadora de la geometría del objeto
    LPD3DXMESH						getMesh(void)			{return m_pMesh;}

};

#endif
