
#ifndef TGRASS_INS_H_INCLUDED
#define TGRASS_INS_H_INCLUDED

/*
OBJET       herbe 2eme methode > instanciation

DATE        07/2025

AUTEUR      philippe Thebaud

COMMENTAIRE plus rapide que la méthode par shader geometry
*/


#include <GL/glew.h>
#include <string>
#include <vector>
#include <fstream>

#include "../ECO/OUtils.h"
#include "../ECO/OTextureList.h"
#include "../ECO/shader/OShader.h"
#include "../ECO/OSurface.h"
#include "../ECO/OCollision.h"
#include "../ECO/OMesh_obj.h"


/*
le mesh.obj (sol) doit être aligné sur l'abscisse et l'ordonnée (pas de rotation)
préférentiellement avec une échelle métrique (10 x 10 pas 10.1 x 10.5)

le mesh doit avoir des coordonnées de texture, calées en 0.0 > 1.1 (pas de portion !)
la texture peut être une simple couleur (elle n'est pas prise en compte)

le decalage est la position finale de la carte

// donnees/image/herbe_ne.png donnees/mesh/zone/zone_ne.obj / decalage pos.xyz / echelle densite /
// image png du masque (RVB) / mesh obj (calé en 0,0,0 ; avec texture 0->1) / position finale / densité de l'herbe
*/
bool Tgrass_ins_make(std::string filepng, std::string filecol, OVec3_f decalage, float taille = 1.0f, float densite = 0.05f);
bool Tgrass_ins_make(std::string flux);


// code flux load save
#define FLUX_GRASS2      "grass2"

class Tgrass_ins_shader : public OShader
{
public:

    Tgrass_ins_shader();

    bool        create();

    void        setVP(const OMat4& vp);
    void        setAmbient(float value);
    void        setEyePos(const OVec3_f& pos);
    void        setTexture(uint32_t grass);
    void        setTime(float value);

private:

	uint32_t    m_vp;
	uint32_t    m_time;
	uint32_t    m_eyePos;
	uint32_t    m_ambient;
	uint32_t    m_grassMap;
};

class Tgrass_ins
{
public:

    Tgrass_ins();
    ~Tgrass_ins();

    void        create(std::string flux);
    void    	create(std::ifstream& flux);

    void        draw(OMat4& vp, OVec3_f& eyePos, float ambient);

    void        save(std::ofstream& flux);

private:

    void        _composition();

    uint32_t    _load_texture(std::string file);

    void        _make_vao();

public:
    //acces au shader pour le modifier
    Tgrass_ins_shader shGrass;

private:

    OTextureList    textureList;
    std::string     m_code, m_path, m_file;

    static const int m_nbr_vao = 3; // rvb
    std::string     m_str_grass[m_nbr_vao];
    uint32_t        m_tex_grass[m_nbr_vao];
    float           m_scale[m_nbr_vao];

    OVec3_f         m_vertex[12];
    OVec2_f         m_uv[12];

    struct s_grass {
        OVec3_f position;
        float   rotation;
        float   scale;
        float   windPhase;
    };
    std::vector<s_grass>  m_grass[m_nbr_vao];

    const int   m_nbr_vao_buffer = 4;
    uint32_t    m_vao[m_nbr_vao], m_vao_buffer[m_nbr_vao][4];

    std::vector<std::vector<OVec4_f> > m_pos; // données du fichier binaire : xyz + size + avec 3 couleurs

};


#endif
