Osgearth Drawing Dynamic water effects

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.