The idea of drawing water effect on Osgearth is:
1. Draw the polygon using the Osg::geometry method;
2. Paste a water texture on the painted polygon;
3. Use the shader effect on the texture to make it appear dynamically.
This method is suitable for small-scale, less stringent water effects, use Osgocean if a large range or underwater effect is required.
The code is as follows: Water.h
Class Water: Publichandleadapter{ Public:Water(graphicsview* view); ~water ();protected:Virtual void slotpickedxyz(Osg::vec3d POS);Virtual voidSLOTMOVEINGXYZ (osg::vec3d POS);Virtual voidSlotrighthandle ();Private:void Drawwater(Osg::vec3d pos = Osg::vec3d ()); osg::texture2d* creattext2d (Constqstring& strfile);voidInitshader ();Private: Osg::ref_ptr<osg::vec3darray> m_vecpoints; osg::geode* M_pwater;Char* M_WATERFRAG;Char* M_watervert;};
The implementation code is as follows: Water.cpp
Water:: Water (graphicsview* view): Handleadapter (view) {m_pwater = NULL; M_vecpoints =New OSG:: Vec3darray; M_vecpoints->clear (); Initshader ();}Water:: ~water () {}void Water:: Slotpickedxyz (OSG:: Vec3d Pos) {m_vecpoints->push_back (POS);if(M_vecpoints->size () <=2) {return; } drawwater ();}void Water:: Slotmoveingxyz (OSG:: Vec3d Pos) {if(M_vecpoints->size () <2) {return; } drawwater (POS);}void Water:: Slotrighthandle () {endhandle (); M_pwater = nullptr;}void Water::d Rawwater (OSG:: Vec3d Pos/*= osg::vec3d () */){OSG::ref_ptr<OSG::vec3darray> vecpoints =New OSG:: Vec3darray; Vecpoints = m_vecpoints;if(pos = =OSG:: Vec3d () && m_vecpoints->size () <=2) {return; }if(POS! =OSG:: Vec3d ()) {vecpoints->push_back (POS); }OSG::ref_ptr<OSG::geometry> Pwater =New OSG:: Geometry; Pwater->setvertexarray (vecpoints); Pwater->addprimitiveset (New OSG::D rawarrays (OSG::Primitiveset:: Triangle_fan,0, Vecpoints->size ()));//TextureOSG::ref_ptr<OSG::texture2d> ptext2d =New OSG:: texture2d; Ptext2d->settexturesize (1024x768,1024x768); Ptext2d->setinternalformat (Gl_rgba); Pwater->getorcreatestateset ()Settextureattributeandmodes (0, PTEXT2D); Pwater->getorcreatestateset ()Settextureattributeandmodes (1, CREATTEXT2D ("E:/greatmap/project/version/data/bmp/shui_5.jpg")); Pwater->getorcreatestateset ()Settextureattributeandmodes (2, CREATTEXT2D ("E:/greatmap/project/version/data/bmp/water_dudv.jpg")); Pwater->getorcreatestateset ()Settextureattributeandmodes (3, CREATTEXT2D ("E:/greatmap/project/version/data/bmp/water_nm.jpg"));//ShaderOSG::ref_ptr<OSG::shader> Pveter =New OSG:: Shader (OSG::Shader:: VERTEX, M_watervert);OSG::ref_ptr<OSG::shader> Pfrag =New OSG:: Shader (OSG::Shader:: FRAGMENT, M_waterfrag);OSG::ref_ptr<OSG::P rogram> Pprogram =New OSG::P Rogram; Pprogram->addshader (Pveter); Pprogram->addshader (Pfrag); Pwater->getorcreatestateset ()Adduniform (New OSG:: Uniform ("Reflection",0)); Pwater->getorcreatestateset ()Adduniform (New OSG:: Uniform ("Defaulttex",1)); Pwater->getorcreatestateset ()Adduniform (New OSG:: Uniform ("Refraction",2)); Pwater->getorcreatestateset ()Adduniform (New OSG:: Uniform ("Normaltex",3)); Pwater->getorcreatestateset ()Setattributeandmodes (Pprogram);if(M_pwater = = NULL) {M_pwater =New OSG:: Geode; M_playergroup->addchild (M_pwater); } m_pwater->adddrawable (Pwater); M_pwater->setstateset (Pwater->getorcreatestateset ());}OSG:: texture2d*Water:: Creattext2d (Constqstring& strfile) {if(Strfile.isempty ()) {returnNULL; }OSG::ref_ptr<OSG::texture2d> ptext2d =New OSG:: texture2d; Ptext2d->setimage (Osgdb:: Readimagefile (Strfile.tostdstring ())); Ptext2d->setwrap (OSG::texture2d:: wrap_s,OSG::texture2d:: REPEAT); Ptext2d->setwrap (OSG::texture2d:: wrap_t,OSG::texture2d:: REPEAT); Ptext2d->setfilter (OSG::texture2d:: Min_filter,OSG::Texture:: Linear_mipmap_linear); Ptext2d->setfilter (OSG::texture2d:: Mag_filter,OSG::Texture:: LINEAR);returnPtext2d.release ();}
The contents of shader are as follows:
void Water::initshader () {M_watervert = {"Uniform float osg_frametime;\n" "varying vec4 projcoords;\n" "varying vec3 lightdir, eyedir;\n" "varying vec2 flowcoords, ripplecoords;\n" "void main () \ n" "{\ n" "VEC3 T = vec3 (0.0, 1.0, 0.0); \ n" "VEC3 N = vec3 (0.0, 0.0, 1.0); \ n" "VEC3 B = VEC3 (1.0, 0.0, 0.0); \ n" "T = Normalize (Gl_normalmatrix * T); \ n" "B = Normalize (Gl_normalmatrix * b); \ n" n = Normalize (Gl_normalmatrix * n); \ n " "Mat3 tbnmat;\n" "tbnmat[0][0] = t[0]; Tbnmat[1][0] = t[1]; Tbnmat[2][0] = t[2];\n " "tbnmat[0][1] = b[0]; TBNMAT[1][1] = b[1]; TBNMAT[2][1] = b[2];\n " "tbnmat[0][2] = n[0]; TBNMAT[1][2] = n[1]; TBNMAT[2][2] = n[2];\n " "VEC3 Vertexineye = VEC3 (Gl_modelviewmatrix * gl_vertex); \ n" "Lightdir = gl_lightsource[0].position.xyz-vertexineye;\n" "Lightdir = Normalize (Tbnmat * lightdir); \ n" "Eyedir = Normalize (Tbnmat * (-vertexineye)); \ n" "Vec2 t1 = vec2 (osg_frametime*0., Osg_frametime *0.); \ n" "VEC2 t2 = vec2 (osg_frametime*0., Osg_frametime*0.); \ n" "flowcoords = Gl_multitexcoord0.xy + t1/10.0;\n"//*5.0+ T1"ripplecoords = Gl_multitexcoord0.xy + t1;\n"//"gl_texcoord[0] = gl_multitexcoord0;\n" "gl_position = Ftransform (); \ n" "projcoords = gl_position;\n" "}\n"}; M_waterfrag = {"Uniform sampler2d defaulttex;\n" "Uniform sampler2d reflection;\n" "Uniform sampler2d refraction;\n" "Uniform sampler2d normaltex;\n" "varying vec4 projcoords;\n" "varying vec3 lightdir, eyedir;\n" "varying vec2 flowcoords, ripplecoords;\n" "void main () \ n" "{\ n" "VEC2 rippleeffect = 0.02 * TEXTURE2D (refraction, ripplecoords * 0.01). xy;\n" "Vec4 N = texture2d (Normaltex, flowcoords + rippleeffect); \ n" "n = n * 2.0-VEC4 (1.0); \ n" "N.A = 1.0; n = normalize (n); \ n " "VEC3 Refvec = normalize (Reflect (-lightdir, VEC3 (N) * 0.6)); \ n" "Float refangle = Clamp (dot (eyedir, Refvec), 0.0, 1.0); \ n" "VEC4 specular = Vec4 (Pow (refangle, 40.0)); \ n" "VEC2 dist = texture2d (refraction, Flowcoords + rippleeffect). xy;\n" "dist = (Dist * 2.0-VEC2 (1.0)) * 0.1;\n" "vec2 UV = projcoords.xy/projcoords.w;\n" "UV = Clamp ((UV + 1.0) * 0.5 + dist, 0.0, 1.0); \ n" "VEC4 base = Texture2d (Defaulttex, UV); \ n" "Vec4 Refl = texture2d (reflection, UV); \ n" "Gl_fragcolor = Mix (base, REFL + specular, 0.6); \ n" "}\n"};}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Osgearth Drawing Dynamic water effects