Nehe OpenGL Tutorial with OpenSceneGraph-35th lesson

Source: Internet
Author: User
Tags addchild traits
Brief Introduction

This lesson describes how to play a video in a three-dimensional scenario. We all know that the video is actually made up of a picture of a frame, so we parse the images in the video into a picture format and assign them to the surface of the geometry, allowing them to switch within a very short interval to achieve a dynamic effect. Implement

In this lesson, you use the API for Windows parsing video format AVI file, which comes from the code in the Nehe course, which readers can check out on MSDN to learn about:

First create the geometry that plays the AVI file (similar to the big screen of the movie)

osg::geode*	Createbackgroundgeode (osg::texture2d *text)
{
Osg::geode *geode = new Osg::geode;
Osg::geometry *geometry = new Osg::geometry;
Geometry->setupdatecallback (new dynamictextureupdatecallback);
...
	Geometry->setvertexarray (Vertexarray);
	Geometry->settexcoordarray (0, Texturearray, Osg::array::bind_per_vertex);
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::quads, 0, Vertexarray->size ()));
	Geometry->getorcreatestateset ()->settextureattributeandmodes (0, text);
	Geometry->getorcreatestateset ()->setmode (gl_lighting, false);
	Geode->adddrawable (geometry);

	return geode;
}
Dynamic texture callback Dynamictextureupdatecallback enables dynamic modification of textures:

Class Dynamictextureupdatecallback:public OSG::D rawable::updatecallback
{public
:
	Dynamictextureupdatecallback (): _lastupdate (0), _frame (0), _passedtimeinmillsecond (0)
	{
		_starttime = OSG:: Timer::instance ()->tick (); 
		_currenttime = _starttime;
	}

	void Update (Osg::nodevisitor* NV, OSG::D rawable* drawable)
	{
		Osg::geometry *geometry = dynamic_cast<osg:: Geometry*> (drawable);
		if (!geometry)
...}}
;
Then create the geometry in the scene:

osg::node*	Createbox ()
osg::node*	createsphere ()
osg::node*	Createcylinder ()
This part is similar to the 23rd lesson.

Add all the above geometry to a switch switch node to implement the toggle operation:

The effect of switching texture and switching nodes in the interaction with the keyboard:

		Case (Osgga::guieventadapter::keydown):
			{
				if (ea.getkey () = = Osgga::guieventadapter::key_space)
				{
					if (!g_switchnode) return
						false;

					static int i = 0;
					++i;
					if (i > 2)
						i = 0;
					G_switchnode->setsinglechildon (i);
				}
				if (ea.getkey () = = Osgga::guieventadapter::key_e)
				{
					static bool flag = TRUE;
					if (flag) {
						g_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_s, OSG:: Stateattribute::off);
						G_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_t, osg::stateattribute::off);
					else{
						G_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_s, Osg::StateAttribute::O N);
						G_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_t, osg::stateattribute::on);
					flag =!flag;
				}
Add all of the above to the scene root node. To 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/Texture2D> #include <osg/ShapeDrawable> #include <osg/ switch> #include <osg/AnimationPath> #include <osg/TexGen> #include <osg/TexGenNode> #include					
<vfw.h> Avistreaminfo psi;						
Pavistream Pavi;							
Pgetframe PGF;
Bitmapinfoheader Bmih;								
Long Lastframe;								
int width;								
int height;								
Char *pdata;									

int MPF;									
Hdrawdib HDD;
Hbitmap Hbitmap;		
HDC HDC = CreateCompatibleDC (0);								

unsigned char* data = 0;
Osg::texture2d *g_texture2d = NULL;
Osg::image *g_textureimage = NULL;

Osg::switch *g_switchnode = NULL;	
	void Flipit (void* buffer) {void* b = buffer;
__asm {		mov ecx, 256*256 mov ebx, b label:mov al,[ebx+0] mov ah,[ebx+2] mov [ebx+2],al mov [ebx+0],ah add ebx,3 Dec ecx jnz label}} void Openavi (LPCSTR szf

	ile) {TCHAR title[100];
	Avifileinit ();
	if (Avistreamopenfromfilea (&pavi, Szfile, Streamtypevideo, 0, Of_read, NULL)!=0) {return;
	Avistreaminfo (Pavi, &psi, sizeof (PSI));
	Width=psi.rcframe.right-psi.rcframe.left;

	Height=psi.rcframe.bottom-psi.rcframe.top;

	Lastframe=avistreamlength (Pavi);

	Mpf=avistreamsampletotime (pavi,lastframe)/lastframe;
	bmih.bisize = sizeof (Bitmapinfoheader);
	Bmih.biplanes = 1;
	Bmih.bibitcount = 24;
	Bmih.biwidth = 256;
	Bmih.biheight = 256;

	Bmih.bicompression = Bi_rgb;
	Hbitmap = CreateDIBSection (hdc, (bitmapinfo*) (&AMP;BMIH), Dib_rgb_colors, (void**) (&data), NULL, NULL);

	SelectObject (hdc, HBITMAP);
	Pgf=avistreamgetframeopen (Pavi, NULL);
	if (pgf==null) {return; } void GrabaViframe (int frame) {Lpbitmapinfoheader lpbi;
	LPBI = (lpbitmapinfoheader) avistreamgetframe (PGF, frame);

	Pdata= (char *) lpbi+lpbi->bisize+lpbi->biclrused * sizeof (RGBQUAD);
	Drawdibdraw (HDD, HDC, 0, 0, 256, 256, LPBI, pdata, 0, 0, width, height, 0);

	Flipit (data);
	G_textureimage->setimage (256, 256, 1, 3, Gl_rgb, Gl_unsigned_byte, data, osg::image::no_delete);
G_texture2d->setimage (G_textureimage);
	} void Closeavi (void) {DeleteObject (HBITMAP);
	Drawdibclose (HDD);
	Avistreamgetframeclose (PGF);
	Avistreamrelease (Pavi);
Avifileexit ();
	} void Initialize () {HDD = Drawdibopen ();
	g_texture2d = new Osg::texture2d;
	G_texture2d->setfilter (Osg::texture::mag_filter, osg::texture::nearest);
	G_texture2d->setfilter (Osg::texture::min_filter, osg::texture::nearest);
	G_textureimage = new Osg::image;
	G_textureimage->allocateimage (256, 256, 1, GL_RGB, gl_unsigned_byte);
Openavi ("Data/face3.avi"); Class Dynamictextureupdatecallback:public OSG::D rawable::updateCallback {public:dynamictextureupdatecallback (): _lastupdate (0), _frame (0), _passedtimeinmillsecond (0) {_startTime 
		= Osg::timer::instance ()->tick ();
	_currenttime = _starttime; } void Update (Osg::nodevisitor* NV, OSG::D rawable* drawable) {osg::geometry *geometry = Dynamic_cast<osg::geometr
		Y*> (drawable);
		if (!geometry) return; Osg::texture2d *texture2d = dynamic_cast<osg::texture2d *> (geometry->getorcreatestateset ()->
		Gettextureattribute (0, osg::stateattribute::texture));

		if (!texture2d) return; if (nv->getvisitortype () = = Osg::nodevisitor::update_visitor && nv->getframestamp () && nv->
			Getframestamp ()->getframenumber ()!= _lastupdate) {_lastupdate = Nv->getframestamp ()->getFrameNumber ();
			_currenttime = Osg::timer::instance ()->tick ();
			float T = osg::timer::instance ()->delta_m (_starttime, _currenttime);
			
			_passedtimeinmillsecond + = t; if (_passeDtimeinmillsecond >= MPF) {grabaviframe (_frame);

				_frame++;
				if (_frame >= lastframe) {_frame = 0;
			} _passedtimeinmillsecond = 0;
	}} osg::timer_t _starttime;
	osg::timer_t _currenttime;
	unsigned int _lastupdate;
	unsigned int _frame;
int _passedtimeinmillsecond;


}; Drawing Geometry/////////	osg::geode*
	Createbackgroundgeode (osg::texture2d *text) {Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry;
	Geometry->setupdatecallback (new Dynamictextureupdatecallback);
	Osg::vec3array *vertexarray = new Osg::vec3array;

	Osg::vec2array *texturearray = new Osg::vec2array;
	Vertexarray->push_back (OSG::VEC3 (11.0f, 8.3f, -20.0f));
	Vertexarray->push_back (OSG::VEC3 ( -11.0f, 8.3f, -20.0f)); Vertexarray->push_baCK (OSG::VEC3 ( -11.0f, -8.3f, -20.0f));

	Vertexarray->push_back (OSG::VEC3 (11.0f, -8.3f, -20.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));

	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Geometry->setvertexarray (Vertexarray);
	Geometry->settexcoordarray (0, Texturearray, Osg::array::bind_per_vertex);
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::quads, 0, Vertexarray->size ()));
	Geometry->getorcreatestateset ()->settextureattributeandmodes (0, text);
	Geometry->getorcreatestateset ()->setmode (gl_lighting, false);

	Geode->adddrawable (geometry);
return geode;
	} osg::node* Createbox (/*osg::texture2d *text*/) {osg::matrixtransform *mtx = new Osg::matrixtransform;
	Mtx->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::x_axis, 1.5));
	Osg::matrixtransform *mty = new Osg::matrixtransform; Mty->addupdAtecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::y_axis, 2.5));
	Osg::matrixtransform *mtz = new Osg::matrixtransform;

	Mtz->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::z_axis, 3.5));
	Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry;
	Osg::vec3array *vertexarray = new Osg::vec3array;
	Osg::vec2array *texturearray = new Osg::vec2array;
	
	Osg::vec3array *normalarray = new Osg::vec3array;
	for (int i = 0; i < 4; ++i) Normalarray->push_back (OSG::VEC3 (0.0f, 0.0f, 0.5f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, -1.0f, 1.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, -1.0f, 1.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, 1.0f, 1.0f));
	
Vertexarray->push_back (OSG::VEC3 ( -1.0f, 1.0f, 1.0f));	for (int i = 0; i < 4; ++i) Normalarray->push_back (OSG::VEC3 (0.0f, 0.0f,-0.5f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, -1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, 1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, 1.0f,-1.0f));

	Vertexarray->push_back (OSG::VEC3 (1.0f, -1.0f, -1.0f));
	for (int i = 0; i < 4; ++i) Normalarray->push_back (OSG::VEC3 (0.0f, 0.5f,0.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, 1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, 1.0f, 1.0f)); Vertexarray->push_back (OSG::VEC3 (1.0f, 1.0f, 1.0f));

	Vertexarray->push_back (OSG::VEC3 (1.0f, 1.0f, -1.0f));
	for (int i = 0; i < 4; ++i) Normalarray->push_back (OSG::VEC3 (0.0f, -0.5f,0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, -1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, -1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, -1.0f, 1.0f));

	Vertexarray->push_back (OSG::VEC3 ( -1.0f, -1.0f, 1.0f));
	for (int i = 0; i < 4; ++i) Normalarray->push_back (OSG::VEC3 (0.5f, 0.0f,0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, -1.0f, -1.0f)); Vertexarray->push_bacK (OSG::VEC3 (1.0f, 1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 (1.0f, 1.0f, 1.0f));

	Vertexarray->push_back (OSG::VEC3 (1.0f, -1.0f, 1.0f));
	for (int i = 0; i < 4; ++i) Normalarray->push_back (OSG::VEC3 ( -0.5f, 0.0f,0.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 0.0f));
	Texturearray->push_back (OSG::VEC2 (1.0f, 1.0f));
	Texturearray->push_back (OSG::VEC2 (0.0f, 1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, -1.0f, -1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, -1.0f, 1.0f));
	Vertexarray->push_back (OSG::VEC3 ( -1.0f, 1.0f, 1.0f));

	Vertexarray->push_back (OSG::VEC3 ( -1.0f, 1.0f, -1.0f));
	Geometry->setvertexarray (Vertexarray);
	Geometry->setnormalarray (Normalarray, Osg::array::bind_per_vertex);
	Geometry->settexcoordarray (0, Texturearray, Osg::array::bind_per_vertex);
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::quads, 0, Vertexarray->size ())); GeoMetRy->getorcreatestateset ()->setmode (gl_lighting, false);

	Geode->adddrawable (geometry);
	Mtx->addchild (mty);
	Mty->addchild (MtZ);

	Mtz->addchild (Geode);
return to MtX;
	} osg::node* Createsphere () {osg::matrixtransform *mtx = new Osg::matrixtransform;
	Mtx->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::x_axis, 1.5));
	Osg::matrixtransform *mty = new Osg::matrixtransform;
	Mty->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::y_axis, 2.5));
	Osg::matrixtransform *mtz = new Osg::matrixtransform;

	Mtz->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::z_axis, 3.5));
	Osg::geode *sphere = new Osg::geode;
	Osg::shapedrawable *spheredrawable = new Osg::shapedrawable (New Osg::sphere (OSG::VEC3 (0,0,0), 1.3));

	Sphere->adddrawable (spheredrawable);
	Mtx->addchild (mty);
	Mty->addchild (MtZ);

	Mtz->addchild (Sphere);
return to MtX; } osg::node* Createcylinder () {osg::matrixtransform *mtx = new Osg::matRixtransform;
	Mtx->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::x_axis, 1.5));
	Osg::matrixtransform *mty = new Osg::matrixtransform;
	Mty->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::y_axis, 2.5));
	Osg::matrixtransform *mtz = new Osg::matrixtransform;

	Mtz->addupdatecallback (New Osg::animationpathcallback (OSG::VEC3 (), Osg::z_axis, 3.5));
	Osg::geode *cylinder = new Osg::geode;
	Osg::shapedrawable *cylinderdrawable = new Osg::shapedrawable (New Osg::cylinder (OSG::VEC3 (0,0,0), 0.5, 2.0));

	Cylinder->adddrawable (cylinderdrawable);
	Mtx->addchild (mty);
	Mty->addchild (MtZ);


	Mtz->addchild (cylinder);
return to MtX; ///////////////////////////////////////////////////////////////////////////////////////////////////////Scene Interaction/// Class Manipulatorscenehandler:public Osgga::guieventhandler {Public:manipulatorscenehandler() {} virtual bool handle (const osgga::guieventadapter& EA, osgga::guiactionadapter& aa) {Osgviewer::view
		Er *viewer = dynamic_cast<osgviewer::viewer*> (&AMP;AA);
		if (!viewer) return false;
		if (!viewer->getscenedata ()) return false;

		if (ea.gethandled ()) return false; Switch (Ea.geteventtype ()) {case (Osgga::guieventadapter::keydown): {if (ea.getkey () = = Osgga::guieventadapter:

					: Key_space) {if (!g_switchnode) return false;
					static int i = 0;
					++i;
					if (i > 2) i = 0;
				G_switchnode->setsinglechildon (i);
					} if (Ea.getkey () = = osgga::guieventadapter::key_e) {static BOOL flag = TRUE; if (flag) {G_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_s, Osg::stateattribute::off
						);
					G_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_t, Osg::stateattribute::off); }else{G_switchnode->getorcreatestateset ()->Settexturemode (0, gl_texture_gen_s, osg::stateattribute::on);
					G_switchnode->getorcreatestateset ()->settexturemode (0, gl_texture_gen_t, osg::stateattribute::on);
				} flag =!flag;
		}} Default:break;
	return false;
}
}; //////////////////////////////////////////////////////////////////////////



///////////////////////////////////// Osgnehe Frame/////////////////////////////////////// Class Viewerwidget:public Qwidget, public osgviewer :: Viewer {public:viewerwidget (osg::node *scene = NULL) {qwidget* renderwidget = Getrenderwidget (creategraphicswind

		ow (0,0,100,100), 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->getcamera ();

		Camera->setgraphicscontext (GW);

		Const osg::graphicscontext::traits* Traits = Gw->gettraits ();
		Camera->setclearcolor (OSG::VEC4 (0.0, 0.0, 0.0, 1.0));
		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, 0, 0), osg::vec3d (0, 0,-1), osg::vec3d (0, 1, 0));
		This->setscenedata (Scene);

		This->addeventhandler (new Manipulatorscenehandler);
	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;



};

	osg::node* Buildscene () {initialize ();
	
	Osg::group *root = new Osg::group;
	Osg::switch *switchnode = new Osg::switch;
	G_switchnode = Switchnode;
	Switchnode->addchild (Createbox ());
	Switchnode->addchild (Createcylinder ());
	Switchnode->addchild (Createsphere ());

	Switchnode->setsinglechildon (0);
	Osg::texgen *texgen = new Osg::texgen;Texgen->setmode (OSG::TEXGEN::SPHERE_MAP);
	Switchnode->getorcreatestateset ()->settextureattributeandmodes (0, Texgen);

	Switchnode->getorcreatestateset ()->settextureattributeandmodes (0, g_texture2d);
	Osg::matrixtransform *zoommt = new Osg::matrixtransform;
	Zoommt->setmatrix (Osg::matrix::translate (0.0f, 0.0f, -10.0f));

	Zoommt->addchild (Switchnode);
	Root->addchild (Createbackgroundgeode (g_texture2d));
	Root->addchild (ZOOMMT);
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.