Nehe OpenGL Tutorial with OpenSceneGraph-36th lesson

Source: Internet
Author: User
Tags addchild cos sin traits
Brief Introduction

This lesson nehe us how to read the pixel value in the frame cache and load it into the geometry as a texture in the scene. Which is what we often call rendering to texture (Render to texture) function, also known as texture baking. This function has two main functions: the first is to realize the post processing after the scene off screen rendering, and the second is to realize the fusion display effect of many different scenes. Implement

First create the Helix model that we need to display in our scenario, the code reads as follows:

osg::geode*	Createhelix ()

Next we need to write the scene loaded in the model to the texture, and in osg you can do this by creating a camera that renders to the texture:

osg::camera* Createrendertotexturecamera (int w, int h) {Osg::camera *rtt = new Osg::camera;	
	Rtt->setclearcolor (OSG::VEC4 (0.0f, 0.0f, 0.5f, 0.5)); Rtt->setclearmask (Gl_color_buffer_bit |
	Gl_depth_buffer_bit);
	Rtt->setreferenceframe (OSG::TRANSFORM::ABSOLUTE_RF);
	Rtt->setviewport (0, 0, W, h);
	Rtt->setrenderorder (Osg::camera::P re_render);
	Rtt->setrendertargetimplementation (Osg::camera::frame_buffer_object); Rtt->setprojectionmatrixasperspective (45.0f, static_cast<double> (640)/static_cast<double> (480),
	0.1f, 100.0f);

	Rtt->setviewmatrixaslookat (osg::vec3d (0, 5, m), osg::vec3d (0, 0, 0), osg::vec3d (0, 1, 0));
	Osg::matrixtransform *zoommt = new Osg::matrixtransform;
	Zoommt->setmatrix (Osg::matrix::translate (0,0,-50));
	Osg::matrixtransform *xrotmt = new Osg::matrixtransform;
	Xrotmt->addupdatecallback (New Rotaxiscallback (Osg::x_axis, 0.02));
	Osg::matrixtransform *yrotmt = new Osg::matrixtransform; Yrotmt->addupdatecallback (New RotaxiScallback (Osg::y_axis, 0.01));
	Zoommt->addchild (XROTMT);
	Xrotmt->addchild (YROTMT);

	Yrotmt->addchild (Createhelix ());
	
	Rtt->addchild (ZOOMMT);
return RTT; }
By setting the camera rendering, Pre_render can make sure that the scene in the camera is rendered before rendering the other scene, and save it to the texture by doing the following:

	G_texture = CreateTexture (128,128);
	Osg::camera *rttcamera = Createrendertotexturecamera (128, 128);
	Rttcamera->attach (Osg::camera::color_buffer, g_texture);
So the textures we need are created.

Next, load the geometry using the texture:

osg::node*	Createblur (int times, float Inc)
At the same time in the geometry of the update constantly modify the location of texture coordinates to achieve a small offset, the whole scene looks like a motion blur effect:

Class Blurgeometryupdatecallback:public OSG::D rawable::updatecallback

Finally, add all these parts to the scene root node and compile and run the program:


Attached: This lesson source code (source code may exist errors and deficiencies, for reference only)

#include ". /osgnehe.h "#include <QtCore/QTimer> #include <QtGui/QApplication> #include <QtGui/QVBoxLayout> Include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osgQt/GraphicsWindowQt> #include <osg/MatrixTransform> #include <osg/AnimationPath> #include <osg/Material> #include <osg/
lightsource> #include <osg/BlendFunc> #include <osg/Texture2D> #include <osg/State> float angle;
float vertexes[4][3];
float normal[3];

Osg::texture2d *g_texture; //////////////////////////////////////////////////////////////////////////
///////////////////////////////////// 

/////////////////////////////////////
////////////////////////////////////////////////////////////////////////// void Reducetounit (float vector[3])//reduces a Normal vector (3 coordinates) {/To A unit Norma
	L Vector with A Length of one.												float length; Holds unit Length//calculates the LengtH of the Vector length = (float) sqrt ((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2));											if (length = = 0.0f)//Prevents Divide by 0 Error by providing length = 1.0f;

	An acceptable Value of Vectors to close to 0.										VECTOR[0]/= length;										Dividing each Element by vector[1]/= length;										The length Results in A vector[2]/= Length;
Unit Normal Vector.											} void Calcnormal (float v[3][3], float out[3])//Calculates Normal for A Quad Using 3 Points {float v1[3],v2[3];										Vector 1 (x,y,z) & Vector 2 (x,y,z) static const int x = 0;										Define X Coord static const int y = 1;										Define Y Coord static const int z = 2; Define Z Coord//Finds the Vector Between 2 Points by subtracting//the X,Y,Z coordinates									R.//Calculate The Vector from point 1 to point 0 v1[x] = v[0][x]-v[1][x]; Vector 1.x=vertex[0].x-vertex[1].x V1[y] = V[0][y]-v[1][y];									Vector 1.y=vertex[0].y-vertex[1].y V1[z] = v[0][z]-v[1][z];									Vector 1.z=vertex[0].y-vertex[1].z//Calculate vector from point 2 to point 1 v2[x] = v[1][x]-v[2][x];									Vector 2.x=vertex[0].x-vertex[1].x V2[y] = v[1][y]-v[2][y];									Vector 2.y=vertex[0].y-vertex[1].y V2[z] = v[1][z]-v[2][z]; Vector 2.z=vertex[0].z-vertex[1].z//Compute the Cross Product to give Us A Surface Normal out[x] = v1[y]*v2[z]-V1							[Z]*v2[y];							Cross Product for y-z out[y] = v1[z]*v2[x]-v1[x]*v2[z];							Cross Product for x-z out[z] = v1[x]*v2[y]-v1[y]*v2[x];											Cross Product for X-y Reducetounit (out); Normalize the Vectors} class Rotaxiscallback:public Osg::nodecallback {public:rotaxiscallback (const OSG::VEC3 & axis, double rotspeed = 0.0, double currentangle = 0.0): _rotaxis (axis), _rotspeed (Rotspeed), _currentangle (Curre Ntangle) {} virtual void operator () (osg::node* node, osg::nodevisitor* nv) {Osg::matrixtransform *rotmt = dynamic_cast<osg::matrixtransform*> (node);
		if (!rotmt) return;
		_currentangle + = _rotspeed;
		
		Rotmt->setmatrix (Osg::matrix::rotate (_currentangle, _rotaxis));
	Traverse (node, NV);
	} void Setrotatespeed (double speed) {_rotspeed = speed;
	Double Getrotatespeed () const {return _rotspeed;
	Double Getcurrentangle () const {return _currentangle;
	} PRIVATE:OSG::VEC3 _rotaxis;
	Double _currentangle;
Double _rotspeed;

};									osg::geode* Createhelix () {glfloat x;									Helix x coordinate glfloat y;										Helix y coordinate glfloat z;									Helix Z coordinate glfloat phi;								Angle Glfloat Theta;									Angle glfloat V,u;							Angles glfloat r = 1.5f;								Radius of Twist int twists = 5;
	5 twists Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry; Osg::vec3array *vertexarray = new Osg::vec3array;

Osg::vec3array *normalarray = new Osg::vec3array;							for (int phi=0; Phi <= 360; phi+=20.0) 360 Degrees in Steps to {for (int theta=0; theta<=360*twists; theta+=20.0)//360 Degrees * Number of Twist								s in Steps of v= (phi/180.0f*3.142f);							Calculate Angle of the (0) u= (theta/180.0f*3.142f);					Calculate Angle of the (0) x=float (cos (u) * (2.0f+cos (v))) *r;					Calculate x Position (1st point) y=float (sin (u) * (2.0f+cos (v))) *r;		Calculate y Position (1st point) Z=float ((U-2.0f*3.142f) + sin (v)) * R);									Calculate z Position (1st point) vertexes[0][0]=x;									Set x Value of the Vertex vertexes[0][1]=y;									Set y Value of the Vertex vertexes[0][2]=z;								Set Z Value of the Vertex v= (phi/180.0f*3.142f);			Calculate Angle of Second Point (0) u= ((theta+20)/180.0f*3.142f);			Calculate Angle of Second point x=float (cos (u) * (2.0f+cos (v)) *r;					Calculate x Position (2nd point) y=float (sin (u) * (2.0f+cos (v))) *r;		Calculate y Position (2nd point) Z=float ((U-2.0f*3.142f) + sin (v)) * R);									Calculate z Position (2nd point) vertexes[1][0]=x;									Set x Value of Second Vertex vertexes[1][1]=y;									Set y Value of Second Vertex vertexes[1][2]=z;							Set z Value of Second Vertex v= ((phi+20)/180.0f*3.142f);						Calculate Angle of Third Point u= ((theta+20)/180.0f*3.142f);					Calculate Angle of Third Point x=float (cos (u) * (2.0f+cos (v)) *r;					Calculate x Position (3rd point) y=float (sin (u) * (2.0f+cos (v))) *r;		Calculate y Position (3rd point) Z=float ((U-2.0f*3.142f) + sin (v)) * R);									Calculate z Position (3rd point) vertexes[2][0]=x;									Set x Value of third Vertex vertexes[2][1]=y; Set y Value of third Vertex vertexes[2][2]=z;							Set Z Value of Third Vertex v= ((phi+20)/180.0f*3.142f);							Calculate Angle of Fourth point u= ((theta)/180.0f*3.142f);					Calculate Angle of Fourth point (0) x=float (cos (u) * (2.0f+cos (v))) *r;					Calculate x Position (4th point) y=float (sin (u) * (2.0f+cos (v))) *r;		Calculate y Position (4th point) Z=float ((U-2.0f*3.142f) + sin (v)) * R);									Calculate z Position (4th point) vertexes[3][0]=x;									Set x Value of fourth Vertex vertexes[3][1]=y;									Set y Value of fourth Vertex vertexes[3][2]=z;						Set z Value of Fourth Vertex calcnormal (Vertexes,normal);
			Calculate the Quad Normal normalarray->push_back (OSG::VEC3 (normal[0],normal[1],normal[2));
			Normalarray->push_back (OSG::VEC3 (normal[0],normal[1],normal[2));
			Normalarray->push_back (OSG::VEC3 (normal[0],normal[1],normal[2));

			Normalarray->push_back (OSG::VEC3 (normal[0],normal[1],normal[2)); RenderThe Quad vertexarray->push_back (OSG::VEC3 (vertexes[0][0],vertexes[0][1],vertexes[0][2));
			Vertexarray->push_back (OSG::VEC3 (vertexes[1][0],vertexes[1][1],vertexes[1][2));
			Vertexarray->push_back (OSG::VEC3 (vertexes[2][0],vertexes[2][1],vertexes[2][2));
		Vertexarray->push_back (OSG::VEC3 (vertexes[3][0],vertexes[3][1],vertexes[3][2)); }}//////////////////////////////////////////////////////////////////////////Geometry->setvertexarray (
	Vertexarray);
	Geometry->setnormalarray (Normalarray, Osg::array::bind_per_vertex);

	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::quads, 0, Vertexarray->size ()));
	Osg::material *helixmat = new Osg::material;
	Helixmat->setambient (Osg::material::front_and_back, OSG::VEC4 (0.4f,0.2f,0.8f,1.0f));
	Helixmat->setdiffuse (Osg::material::front_and_back, OSG::VEC4 (0.4f,0.2f,0.8f,1.0f));
	Helixmat->setspecular (Osg::material::front_and_back, OSG::VEC4 (1.0f,1.0f,1.0f,1.0f)); Helixmat->setshininesS (Osg::material::front, 128.0f);
	Geometry->getorcreatestateset ()->setattributeandmodes (Helixmat);

	Geometry->getorcreatestateset ()->setmode (gl_light0, Osg::stateattribute::on);

	Geode->adddrawable (geometry);
return geode; Class Viewerwidget:public Qwidget, public osgviewer::viewer {public:viewerwidget (osg::node *scene = NULL) {QW

		idget* renderwidget = Getrenderwidget (Creategraphicswindow (0,0,640,480), scene);
		qvboxlayout* layout = new Qvboxlayout;
		Layout->addwidget (Renderwidget);
		Layout->setcontentsmargins (0, 0, 0, 1);

		SetLayout (layout);
		Connect (&_timer, SIGNAL (timeout ()), this, SLOT (update ()));
	_timer.start (10); } qwidget* Getrenderwidget (osgqt::graphicswindowqt* GW, osg::node* scene) {osg::camera* Camera = This->getcamer
		A ();

		Camera->setgraphicscontext (GW);

		Const osg::graphicscontext::traits* Traits = Gw->gettraits ();
		Camera->setclearcolor (OSG::VEC4 (0.0, 0.0, 0.0, 0.5)); Camera->setvieWport (New Osg::viewport (0, 0, traits->width, traits->height)); Camera->setprojectionmatrixasperspective (45.0f, static_cast<double> (traits->width)/static_cast<
		Double> (Traits->height), 0.1f, 100.0f);

		Camera->setviewmatrixaslookat (osg::vec3d (0, 5, m), osg::vec3d (0, 0, 0), osg::vec3d (0, 1, 0));
		This->setscenedata (Scene);
	return Gw->getglwidget (); osgqt::graphicswindowqt* Creategraphicswindow (int x, int y, int w, int h, const std::string& name= "", bool Window
		Decoration=false) {osg::D isplaysettings* ds = osg::D isplaysettings::instance (). get ();
		osg::ref_ptr<osg::graphicscontext::traits> Traits = new Osg::graphicscontext::traits;
		Traits->windowname = name;
		Traits->windowdecoration = windowdecoration;
		traits->x = x;
		Traits->y = y;
		Traits->width = W;
		Traits->height = h;
		Traits->doublebuffer = true;
		Traits->alpha = Ds->getminimumnumalphabits (); Traits->stencil = Ds->getminiMumnumstencilbits ();
		Traits->samplebuffers = Ds->getmultisamples ();

		Traits->samples = Ds->getnummultisamples ();
	return new OSGQT::GRAPHICSWINDOWQT (Traits.get ()); 
	virtual void PaintEvent (qpaintevent* event) {frame ();
} Protected:qtimer _timer;



}; Class Blurgeometryupdatecallback:public OSG::D rawable::updatecallback {public:blurgeometryupdatecallback (int Rendertimes, Float Inc.: _times (Rendertimes), _inc (inc) {} void Update (osg::nodevisitor*, OSG::D rawable* d) {osg::g
		Eometry *geometry = dynamic_cast<osg::geometry*> (d);
		
		if (!geometry) return;
		Osg::vec2array *texarray = dynamic_cast<osg::vec2array*> (Geometry->gettexcoordarray (0));
		
		if (!texarray) return;
		Osg::vec4array *colorarray = dynamic_cast<osg::vec4array*> (Geometry->getcolorarray ());

		if (!colorarray) return;	
		float spost = 0.0f;
		float alphainc = 0.9f/_times;
		float alpha = 0.2f;

		Alphainc = Alpha/_times; Texarray->clear ();
		
		Colorarray->clear ();
			for (int num = 0;num < _times;num++) {Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));

			Texarray->push_back (OSG::VEC2 (0+spost,1-spost));
			Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));

			Texarray->push_back (OSG::VEC2 (0+spost,0+spost));
			Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));

			Texarray->push_back (OSG::VEC2 (1-spost,0+spost));
			Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));

			Texarray->push_back (OSG::VEC2 (1-spost,1-spost));					
			Spost + = _inc;	
		Alpha = Alpha-alphainc;
		} texarray->dirty ();
	Colorarray->dirty ();
	int _times;
float _inc;


};
	osg::node* Createblur (int times, float Inc) {float spost = 0.0f;
	float alphainc = 0.9f/times;
	float alpha = 0.2f;

	Alphainc = Alpha/times;
	Osg::blendfunc *blendfunc = new Osg::blendfunc (Osg::blendfunc::src_alpha, Osg::blendfunc::one);
	Osg::geode *geode = new Osg::geode; Osg::geometrY *geometry = new Osg::geometry;
	Geometry->setupdatecallback (New Blurgeometryupdatecallback (Times, Inc.);
	Osg::vec2array *vertexarray = new Osg::vec2array;
	Osg::vec2array *texarray = new Osg::vec2array;

	Osg::vec4array *colorarray = new Osg::vec4array;
		for (int num = 0;num < times;num++) {Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));
		Vertexarray->push_back (OSG::VEC2 (0,0));

		Texarray->push_back (OSG::VEC2 (0+spost,1-spost));
		Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));
		Vertexarray->push_back (OSG::VEC2 (0,480));

		Texarray->push_back (OSG::VEC2 (0+spost,0+spost));
		Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));
		Vertexarray->push_back (OSG::VEC2 (640,480));

		Texarray->push_back (OSG::VEC2 (1-spost,0+spost));
		Colorarray->push_back (OSG::VEC4 (1.0f, 1.0f, 1.0f, Alpha));
		Vertexarray->push_back (OSG::VEC2 (640,0));
	Texarray->push_back (OSG::VEC2 (1-spost,1-spost)); } geometry->setvertexarray (vErtexarray);
	Geometry->settexcoordarray (0, Texarray, Osg::array::bind_per_vertex);
	Geometry->setcolorarray (Colorarray, Osg::array::bind_per_vertex);
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::quads, 0, Vertexarray->size ()));
	Geometry->getorcreatestateset ()->setattributeandmodes (Blendfunc);
	Geometry->getorcreatestateset ()->settextureattributeandmodes (0, g_texture);
	Geometry->getorcreatestateset ()->setmode (Gl_depth_test, Osg::stateattribute::off);
	Geometry->getorcreatestateset ()->setmode (gl_light0, Osg::stateattribute::on);

	Geode->adddrawable (geometry);
return geode;
	} osg::camera* Createblurhud () {osg::camera* Camera = new Osg::camera;
	Camera->setprojectionmatrix (osg::matrix::ortho2d (0,640,0,480));
	Camera->setreferenceframe (OSG::TRANSFORM::ABSOLUTE_RF);
	Camera->setviewmatrix (Osg::matrix::identity ());
	Camera->setrenderorder (Osg::camera::P ost_render);

	Camera->setalloweventfocus (FALSE); camera->addchild (Createblur, 0.02f));
return camera;
	} osg::texture2d* createtexture (int w, int h) {osg::texture2d *texture = new Osg::texture2d;
	Texture->setinternalformat (Gl_rgba);
	Texture->setfilter (Osg::texture::min_filter, osg::texture::linear);
	Texture->setfilter (Osg::texture::mag_filter, osg::texture::linear);
	Texture->settexturesize (W,H);
return texture;
	} osg::camera* Createrendertotexturecamera (int w, int h) {Osg::camera *rtt = new Osg::camera;	
	Rtt->setclearcolor (OSG::VEC4 (0.0f, 0.0f, 0.5f, 0.5)); Rtt->setclearmask (Gl_color_buffer_bit |
	Gl_depth_buffer_bit);
	Rtt->setreferenceframe (OSG::TRANSFORM::ABSOLUTE_RF);
	Rtt->setviewport (0, 0, W, h);
	Rtt->setrenderorder (Osg::camera::P re_render);
	Rtt->setrendertargetimplementation (Osg::camera::frame_buffer_object); Rtt->setprojectionmatrixasperspective (45.0f, static_cast<double> (640)/static_cast<double> (480),
	0.1f, 100.0f); Rtt->setviewmatrixaslookat (osg::vec3d (0, 5, osg::vec3d (0, 0, 0), osg::vec3d (0, 1, 0));
	Osg::matrixtransform *zoommt = new Osg::matrixtransform;
	Zoommt->setmatrix (Osg::matrix::translate (0,0,-50));
	Osg::matrixtransform *xrotmt = new Osg::matrixtransform;
	Xrotmt->addupdatecallback (New Rotaxiscallback (Osg::x_axis, 0.02));
	Osg::matrixtransform *yrotmt = new Osg::matrixtransform;

	Yrotmt->addupdatecallback (New Rotaxiscallback (Osg::y_axis, 0.01));
	Zoommt->addchild (XROTMT);
	Xrotmt->addchild (YROTMT);

	Yrotmt->addchild (Createhelix ());
	
	Rtt->addchild (ZOOMMT);
return RTT;
	} osg::node* Buildscene () {glfloat light0pos[4]= {0.0f, 5.0f, 10.0f, 1.0f};
	Glfloat light0ambient[4]= {0.2f, 0.2f, 0.2f, 1.0f};
	Glfloat light0diffuse[4]= {0.3f, 0.3f, 0.3f, 1.0f};	

	Glfloat light0specular[4]={0.8f, 0.8f, 0.8f, 1.0f};
	
	Osg::group *root = new Osg::group;
	Osg::light *light = new Osg::light;
	Light->setlightnum (0); Light->setambient (OSG::VEC4 (Light0ambient[0],light0ambient[1],light0ambient[2],liGHT0AMBIENT[3]));
	Light->setdiffuse (OSG::VEC4 (light0diffuse[0],light0diffuse[1],light0diffuse[2],light0diffuse[3));
	Light->setposition (OSG::VEC4 (light0pos[0], light0pos[1],light0pos[2],light0pos[3));
	Light->setspecular (OSG::VEC4 (light0specular[0],light0specular[1],light0specular[2],light0specular[3));
	Osg::lightsource *lightsource = new Osg::lightsource;
	Lightsource->setlight (light);

	Root->addchild (LightSource);
	Osg::matrixtransform *zoommt = new Osg::matrixtransform;
	Zoommt->setmatrix (Osg::matrix::translate (0,0,-50));
	Osg::matrixtransform *xrotmt = new Osg::matrixtransform;
	Xrotmt->addupdatecallback (New Rotaxiscallback (Osg::x_axis, 0.02));
	Osg::matrixtransform *yrotmt = new Osg::matrixtransform;
	
	Yrotmt->addupdatecallback (New Rotaxiscallback (Osg::y_axis, 0.01));
	Zoommt->addchild (XROTMT);
	Xrotmt->addchild (YROTMT);


	Yrotmt->addchild (Createhelix ());
	G_texture = CreateTexture (128,128); Osg::camera *rttcamera = CreaterendertotexturecaMera (128, 128);
	Rttcamera->attach (Osg::camera::color_buffer, g_texture);
	Root->addchild (Rttcamera);
	Root->addchild (ZOOMMT);
	
	Root->addchild (Createblurhud ());
return root;
	int main (int argc, char** argv) {qapplication app (argc, argv);
	viewerwidget* viewwidget = new Viewerwidget (Buildscene ());
	Viewwidget->setgeometry (100, 100, 640, 480);
	Viewwidget->show ();
return App.exec ();
 }


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.