
#ifndef TGRASS_GEO_H_INCLUDED
#define TGRASS_GEO_H_INCLUDED

/*
OBJET       nappe d'herbe par geometry shader

DATE        07/2025

AUTEUR      philippe Thebaud

COMMENTAIRE le grass2 par instancied est préférable en terme de performances
*/

#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"

#include "common.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_geo_make(std::string filepng, std::string filecol, OVec3_f decalage, float taille = 1.0f, float densite = 0.05f);
bool Tgrass_geo_make(std::string flux);


// code flux load save
#define FLUX_GRASS1      "grass1"

class Tgrass_geo_shader : public OShader
{
public:

    Tgrass_geo_shader();

    bool        create();

    void        setVP(const OMat4& vp);
    void        setAmbient(float value);
    void        setEyePos(const OVec3_f& pos);
    void        setLod(float val1, float val2, float val3);
    void        setTexture(uint32_t texGrass);
    void        setTime(float value);
    void        setWind(float dir, float speed);

private:

	uint32_t    m_vp;
	uint32_t    m_eyePos;
	uint32_t    m_grassMap;
	uint32_t    m_ambient;
	uint32_t    m_windDir, m_windSpeed, m_time;
	uint32_t    m_lod1, m_lod2, m_lod3;
};



class Tgrass_geo
{
public:
	Tgrass_geo();
    ~Tgrass_geo();

    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_geo_shader shGrass;

private:

    std::string m_code, m_path, m_file;

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

    std::vector<std::vector<OVec4_f> > m_pos; // xyz + size + avec 3 couleurs

};

#endif
