Tenth Chapter Spotlight Core Code

Source: Internet
Author: User
Tags mul pow reserved

Spotlight.cpp

=============================================================================//Spotlight.cpp by Frank Luna (C)
2005 All rights Reserved.
Demonstrates an animated spotlight. Controls:use Mouse to orbit and zoom;
Use the ' W ' and ' S ' keys to//alter the height of the camera.
Use ' G ' and ' H ' to decrease and increase the spotlight cone,//respectively. ============================================================================= #include "d3dApp.h" #include " DirectInput.h "#include <crtdbg.h> #include" GfxStats.h "#include <list> #include" Vertex.h "class Spotlight Demo:public D3dapp {public:spotlightdemo (hinstance hinstance, std::string wincaption, D3DDEVTYPE devType, DWORD reque
	STEDVP);

	~spotlightdemo ();
	BOOL Checkdevicecaps ();
	void Onlostdevice ();
	void Onresetdevice ();
	void Updatescene (float dt);

	void Drawscene ();
	Helper methods void Buildgeobuffers ();
	void Buildfx ();
	void Buildviewmtx (); void BUILDPROJMTX ();
	void DrawGrid ();
	void Drawcylinders ();

void Drawspheres ();

	Private:gfxstats* Mgfxstats;
	DWORD mnumgridvertices;

	DWORD Mnumgridtriangles;
	id3dxmesh* Mcylinder;

	id3dxmesh* Msphere;
	idirect3dvertexbuffer9* MVB;

	idirect3dindexbuffer9* MIB;
	id3dxeffect* MFX;
	D3dxhandle Mhtech;
	D3dxhandle MHWVP;
	D3dxhandle Mhworldinvtrans;
	D3dxhandle Mhambientlight;
	D3dxhandle Mhdiffuselight;
	D3dxhandle Mhspeclight;
	D3dxhandle MHLIGHTPOSW;
	D3dxhandle MHLIGHTDIRW;
	D3dxhandle mhAttenuation012;
	D3dxhandle Mhspotpower;
	D3dxhandle Mhambientmtrl;
	D3dxhandle Mhdiffusemtrl;
	D3dxhandle Mhspecmtrl;
	D3dxhandle Mhspecpower;
	D3dxhandle Mheyepos;

	D3dxhandle Mhworld;
	D3dxcolor Mambientlight;
	D3dxcolor Mdiffuselight;
	D3dxcolor Mspeclight;
	D3dxvector3 mAttenuation012;

	float Mspotpower;
	Mtrl Mgridmtrl;
	Mtrl Mcylindermtrl;

	Mtrl Mspheremtrl;
	float Mcamerarotationy;
	float Mcameraradius;

	float Mcameraheight; D3dxmatrix MvieW
D3dxmatrix mProj;


}; int WINAPI WinMain (hinstance hinstance, hinstance previnstance, PSTR cmdline, int showcmd) {//Enable run-time Me
	Mory Check for debug builds. #if defined (DEBUG) |
	Defined (_DEBUG) _crtsetdbgflag (_CRTDBG_ALLOC_MEM_DF | _crtdbg_leak_check_df);
	#endif Spotlightdemo app (hinstance, "Spotlight Demo", D3ddevtype_hal, d3dcreate_hardware_vertexprocessing);

	Gd3dapp = &app; DirectInput di (discl_nonexclusive| Discl_foreground, discl_nonexclusive|
	Discl_foreground);

    Gdinput = &di;
return Gd3dapp->run (); } spotlightdemo::spotlightdemo (HInstance hinstance, std::string wincaption, D3ddevtype devType, DWORD RequestedVP): D3D APP (HInstance, Wincaption, Devtype, REQUESTEDVP) {if (!checkdevicecaps ()) {MessageBox (0, "checkdevicecaps () Failed",
		0, 0);
	PostQuitMessage (0);

	} mgfxstats = new Gfxstats ();
	Mcameraradius = 50.0f;
	Mcamerarotationy = 1.2 * D3DX_PI;

	Mcameraheight = 20.0f;
	Mambientlight = 0.4f*white;  Mdiffuselight = white;
	Mspeclight = white;
	mAttenuation012 = D3dxvector3 (1.0f, 0.0f, 0.0f);

	Mspotpower = 16.0f;
	Mgridmtrl = Mtrl (blue, blue, white, 16.0f);
	Mcylindermtrl = Mtrl (red, red, white, 8.0f);

	Mspheremtrl = Mtrl (green, green, White, 8.0f);
	HR (D3dxcreatecylinder (Gd3ddevice, 1.0f, 1.0f, 6.0f, &mcylinder, 0));

	HR (D3dxcreatesphere (Gd3ddevice, 1.0f, &msphere, 0));
	Buildgeobuffers ();

	BUILDFX ();
	If you are on the drawcylinders and Drawspheres functions, you see//that we draw the cylinders and spheres.
	int numcylverts = mcylinder->getnumvertices () * 14;
	int numsphereverts = msphere->getnumvertices () * 14;
	int numcyltris = mcylinder->getnumfaces () * 14;

	int numspheretris = msphere->getnumfaces () * 14;
	Mgfxstats->addvertices (mnumgridvertices);
	Mgfxstats->addvertices (Numcylverts);
	Mgfxstats->addvertices (Numsphereverts);
	Mgfxstats->addtriangles (Mnumgridtriangles); Mgfxstats->addtrianglES (Numcyltris);

	Mgfxstats->addtriangles (Numspheretris);

	Onresetdevice ();
Initallvertexdeclarations ();
	} spotlightdemo::~spotlightdemo () {delete mgfxstats;
	Releasecom (MVB);
	Releasecom (MIB);
	Releasecom (MFX);
	Releasecom (Mcylinder);

	Releasecom (Msphere);
Destroyallvertexdeclarations ();
	} bool Spotlightdemo::checkdevicecaps () {D3DCAPS9 caps;

	HR (Gd3ddevice->getdevicecaps (&caps));
	Check for vertex shader version 2.0 support. if (Caps.

	Vertexshaderversion < D3dvs_version (2, 0)) return false;
	Check for pixel shader version 2.0 support. if (Caps.

	Pixelshaderversion < D3dps_version (2, 0)) return false;
return true;
	} void Spotlightdemo::onlostdevice () {mgfxstats->onlostdevice ();
HR (Mfx->onlostdevice ());
	} void Spotlightdemo::onresetdevice () {mgfxstats->onresetdevice ();


	HR (Mfx->onresetdevice ());  The aspect ratio depends on the backbuffer dimensions, which can//possibly change after a reset. So rebuild the projection Matrix.
BUILDPROJMTX ();

	} void Spotlightdemo::updatescene (float dt) {mgfxstats->update (dt);
	Get snapshot of input devices.

	Gdinput->poll ();
	Check input.
	if (Gdinput->keydown (dik_w)) Mcameraheight + = 25.0f * DT;

	if (Gdinput->keydown (dik_s)) Mcameraheight-= 25.0f * DT; 
	Divide to make mouse less sensitive.
	Mcamerarotationy + = Gdinput->mousedx ()/100.0f;

	Mcameraradius + = Gdinput->mousedy ()/25.0f; If we rotate over degrees, just roll back to 0 if (FABSF (mcamerarotationy) >= 2.0f * d3dx_pi) Mcamerarotati

	OnY = 0.0f;
	Don ' t let radius get too small.

	if (Mcameraradius < 5.0f) Mcameraradius = 5.0f;
	Control Spotlight Cone.
	if (Gdinput->keydown (dik_g)) Mspotpower + = 25.0f * DT;

	if (Gdinput->keydown (dik_h)) Mspotpower-= 25.0f * DT;
	Clamp spot Power.
	if (Mspotpower < 1.0f) Mspotpower = 1.0f;

	if (Mspotpower > 64.0f) mspotpower = 64.0f; The camera Position/orieNtation relative to World space can//change every frame based on input, so we need to rebuild the//view matrix ever
	Y frame with the latest changes.
BUILDVIEWMTX ();
	} void Spotlightdemo::d rawscene () {//Clear the Backbuffer and depth buffer. HR (gd3ddevice->clear (0, 0, d3dclear_target |

	D3dclear_zbuffer, 0xFFFFFFFF, 1.0f, 0));

	HR (Gd3ddevice->beginscene ());
	Setup the rendering FX HR (Mfx->setvalue (mhambientlight, &mambientlight, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (mhdiffuselight, &mdiffuselight, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (mhspeclight, &mspeclight, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (mhAttenuation012, &mattenuation012, sizeof (D3DXVECTOR3)));

	HR (Mfx->setfloat (Mhspotpower, mspotpower));
	Begin passes.
	UINT numpasses = 0;
	HR (Mfx->begin (&numpasses, 0));

		for (UINT i = 0; i < numpasses; ++i) {HR (Mfx->beginpass (i));
		DrawGrid ();
		Drawcylinders ();

		Drawspheres ();
	HR (Mfx->endpass ()); } HR (Mfx->end ());

	Mgfxstats->display ();

	HR (Gd3ddevice->endscene ());
	Present the Backbuffer.
HR (gd3ddevice->present (0, 0, 0, 0));
	} void Spotlightdemo::buildgeobuffers () {std::vector<d3dxvector3> verts;

	Std::vector<dword> indices;

	Gentrigrid (1.0f, 1.0f, D3dxvector3 (0.0f, 0.0f, 0.0f), Verts, indices);
	Save vertex count and triangle count for drawindexedprimitive arguments.
	Mnumgridvertices = 100*100;

	Mnumgridtriangles = 99*99*2;
	Obtain a pointer to a new vertex buffer. HR (Gd3ddevice->createvertexbuffer (mnumgridvertices * sizeof (VERTEXPN), d3dusage_writeonly, 0, D3DPOOL_MANAGED, &

	AMP;MVB, 0));
	Now lock it to obtain a pointer to its internal data, and write the//grid ' s vertex data.
	Vertexpn* v = 0;

	HR (mvb->lock (0, 0, (void**) &v, 0));
		for (DWORD i = 0; i < mnumgridvertices; ++i) {v[i].pos = verts[i];
	V[i].normal = D3dxvector3 (0.0f, 1.0f, 0.0f);


	} HR (Mvb->unlock ()); Obtain a pointerTo a new index buffer. HR (Gd3ddevice->createindexbuffer (mnumgridtriangles*3*sizeof (WORD), d3dusage_writeonly, D3DFMT_INDEX16, D3DPOOL

	_managed, &mib, 0));

	Now lock IT-obtain a pointer to its internal data, and write the//grid's index data.
	word* k = 0;

	HR (mib->lock (0, 0, (void**) &k, 0));

	for (DWORD i = 0; i < mnumgridtriangles*3; ++i) k[i] = (WORD) indices[i];
HR (Mib->unlock ());
	} void Spotlightdemo::buildfx () {//Create the FX from a. fx file.
	id3dxbuffer* errors = 0;
	HR (D3dxcreateeffectfromfile (Gd3ddevice, "spotlight.fx", 0, 0, d3dxshader_debug, 0, &mfx, &errors));

	if (errors) MessageBox (0, (char*) errors->getbufferpointer (), 0, 0);
	Obtain handles.
	Mhtech = Mfx->gettechniquebyname ("Spotlighttech");
	MHWVP = mfx->getparameterbyname (0, "GWVP");
	Mhworldinvtrans = mfx->getparameterbyname (0, "Gworldinvtrans");
	Mheyepos = mfx->getparameterbyname (0, "GEYEPOSW");          Mhworld= Mfx->getparameterbyname (0, "Gworld");
	Mhambientlight = mfx->getparameterbyname (0, "gambientlight");
	Mhdiffuselight = mfx->getparameterbyname (0, "gdiffuselight");
	Mhspeclight = mfx->getparameterbyname (0, "gspeclight");
	MHLIGHTPOSW = mfx->getparameterbyname (0, "GLIGHTPOSW");
	MHLIGHTDIRW = mfx->getparameterbyname (0, "GLIGHTDIRW");
	mhAttenuation012 = mfx->getparameterbyname (0, "gAttenuation012");
	Mhambientmtrl = mfx->getparameterbyname (0, "Gambientmtrl");
	Mhdiffusemtrl = mfx->getparameterbyname (0, "Gdiffusemtrl");
	Mhspecmtrl = mfx->getparameterbyname (0, "Gspecmtrl");
	Mhspecpower = mfx->getparameterbyname (0, "Gspecpower");
Mhspotpower = mfx->getparameterbyname (0, "Gspotpower");
	} void Spotlightdemo::buildviewmtx () {Float x = Mcameraradius * COSF (Mcamerarotationy);
	float z = Mcameraradius * Sinf (Mcamerarotationy);
	D3dxvector3 POS (x, Mcameraheight, z);
	D3dxvector3 Target (0.0f, 0.0f, 0.0f); D3dxvecTOR3 up (0.0f, 1.0f, 0.0f);

	D3DXMATRIXLOOKATLH (&mview, &pos, &target, &up);

	HR (Mfx->setvalue (Mheyepos, &pos, sizeof (D3DXVECTOR3)));
	Spotlight position is the same as the camera position.

	HR (Mfx->setvalue (MHLIGHTPOSW, &pos, sizeof (D3DXVECTOR3)));
	Spotlight direction is the same as the camera forward direction.
	D3dxvector3 lightdir = Target-pos;
	D3dxvec3normalize (&lightdir, &lightdir);
HR (Mfx->setvalue (MHLIGHTDIRW, &lightdir, sizeof (D3DXVECTOR3)));
	} void Spotlightdemo::buildprojmtx () {Float w = (float) md3dpp.backbufferwidth;
	Float h = (float) md3dpp.backbufferheight;
D3DXMATRIXPERSPECTIVEFOVLH (&mproj, D3dx_pi * 0.25f, w/h, 1.0f, 5000.0f);
	} void Spotlightdemo::d rawgrid () {HR (Gd3ddevice->setstreamsource (0, MVB, 0, sizeof (VERTEXPN)));
	HR (Gd3ddevice->setindices (MIB));

	HR (Gd3ddevice->setvertexdeclaration (vertexpn::D ecl));
	D3dxmatrix W, WIT;
	D3DXMatrixIdentity (&AMP;W); D3dxmatrixinverse (&wit, 0, &
	W);
	D3dxmatrixtranspose (&wit, &wit);
	HR (Mfx->setmatrix (Mhworld, &w));
	HR (Mfx->setmatrix (MHWVP, & (W*mview*mproj)));

	HR (Mfx->setmatrix (Mhworldinvtrans, &wit));
	HR (Mfx->setvalue (Mhambientmtrl, &mgridmtrl.ambient, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (Mhdiffusemtrl, &mgridmtrl.diffuse, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (Mhspecmtrl, &mgridmtrl.spec, sizeof (D3DXCOLOR)));

	HR (Mfx->setfloat (Mhspecpower, mgridmtrl.specpower));
	HR (Mfx->commitchanges ());
HR (gd3ddevice->drawindexedprimitive (d3dpt_trianglelist, 0, 0, mnumgridvertices, 0, mnumgridtriangles));

	} void Spotlightdemo::d rawcylinders () {D3dxmatrix T, R, W, WIT;

	D3dxmatrixrotationx (&r, d3dx_pi*0.5f);
	HR (Mfx->setvalue (Mhambientmtrl, &mcylindermtrl.ambient, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (Mhdiffusemtrl, &mcylindermtrl.diffuse, sizeof (D3DXCOLOR)));
	HR (Mfx->setvalue (Mhspecmtrl, &mcylindermtrl.spec, sizeof (D3DXCOLOR))); HR (mfx->SetFloat (Mhspecpower, mcylindermtrl.specpower));
		for (int z = -30; z <=; z+=) {d3dxmatrixtranslation (&t, -10.0f, 3.0f, (float) z);
		W = r*t;
		D3dxmatrixinverse (&wit, 0, &w);

		D3dxmatrixtranspose (&wit, &wit);
		HR (Mfx->setmatrix (MHWVP, & (W*mview*mproj)));
		HR (Mfx->setmatrix (Mhworld, &w));
		HR (Mfx->setmatrix (Mhworldinvtrans, &wit));
		HR (Mfx->commitchanges ());

		HR (Mcylinder->drawsubset (0));
		D3DXMatrixTranslation (&t, 10.0f, 3.0f, (float) z);
		W = r*t;
		D3dxmatrixinverse (&wit, 0, &w);

		D3dxmatrixtranspose (&wit, &wit);
		HR (Mfx->setmatrix (MHWVP, & (W*mview*mproj)));
		HR (Mfx->setmatrix (Mhworld, &w));
		HR (Mfx->setmatrix (Mhworldinvtrans, &wit));
		HR (Mfx->commitchanges ());
	HR (Mcylinder->drawsubset (0));

	}} void Spotlightdemo::d rawspheres () {D3dxmatrix W, WIT;
	HR (Mfx->setvalue (Mhambientmtrl, &mspheremtrl.ambient, sizeof (D3DXCOLOR))); HR (Mfx->setvalue (mhdiffuSemtrl, &mspheremtrl.diffuse, sizeof (D3DXCOLOR));
	HR (Mfx->setvalue (Mhspecmtrl, &mspheremtrl.spec, sizeof (D3DXCOLOR)));
	HR (Mfx->setfloat (Mhspecpower, mspheremtrl.specpower));
		for (int z = -30; z <=; z+=) {d3dxmatrixtranslation (&w, -10.0f, 7.5f, (float) z);
		D3dxmatrixinverse (&wit, 0, &w);

		D3dxmatrixtranspose (&wit, &wit);
		HR (Mfx->setmatrix (MHWVP, & (W*mview*mproj)));
		HR (Mfx->setmatrix (Mhworld, &w));
		HR (Mfx->setmatrix (Mhworldinvtrans, &wit));
		HR (Mfx->commitchanges ());

		HR (Msphere->drawsubset (0));
		D3DXMatrixTranslation (&w, 10.0f, 7.5f, (float) z);
		D3dxmatrixinverse (&wit, 0, &w);

		D3dxmatrixtranspose (&wit, &wit);
		HR (Mfx->setmatrix (MHWVP, & (W*mview*mproj)));
		HR (Mfx->setmatrix (Mhworld, &w));
		HR (Mfx->setmatrix (Mhworldinvtrans, &wit));
		HR (Mfx->commitchanges ());
	HR (Msphere->drawsubset (0)); }
}

Spotlight.fx

=============================================================================//Spotlight.fx by Frank Luna (C)
2004 All rights Reserved.
Does ambient, diffuse, and specular lighting with a spotlight source.
============================================================================= uniform extern float4x4 GWorld;
uniform extern float4x4 Gworldinvtrans;
uniform extern float4x4 GWVP;

uniform extern float3 GEYEPOSW;
uniform extern float4 Gambientmtrl;
uniform extern float4 Gdiffusemtrl;
uniform extern float4 Gspecmtrl;
	
uniform extern float gspecpower;
uniform extern float4 gambientlight;
uniform extern float4 gdiffuselight;
uniform extern float4 gspeclight;  
uniform extern float3 GLIGHTPOSW;
uniform extern float3 GLIGHTDIRW; 
uniform extern float3 gAttenuation012;

uniform extern float gspotpower;
    struct Outputvs {float4 posh:position0;
FLOAT4 color:color0;

}; Outputvs Spotlightvs (float3 posl:position0, Float3 normall:normal0) {//Zero out OUR output.
	
	Outputvs Outvs = (Outputvs) 0;
	Transform normal to World space.
	FLOAT3 NORMALW = Mul (Float4 (Normall, 0.0f), Gworldinvtrans). xyz;
	
	NORMALW = normalize (NORMALW);
	Transform vertex position to the world space.
	
	FLOAT3 PosW = Mul (Float4 (POSL, 1.0f), Gworld). xyz;
	Unit vector from vertex to light source.
	
	FLOAT3 LIGHTVECW = normalize (GLIGHTPOSW-POSW);
	Ambient light Computation.
	
	FLOAT3 ambient = (gambientmtrl*gambientlight). RGB;
	Diffuse light computation.
	float s = max (dot (NORMALW, LIGHTVECW), 0.0f);
	
	FLOAT3 diffuse = s* (gdiffusemtrl*gdiffuselight). RGB;
	Specular light computation.
	FLOAT3 Toeyew = normalize (GEYEPOSW-POSW);
	FLOAT3 reflectw = Reflect (-LIGHTVECW, NORMALW);
	float t = POW (max (dot (reflectw, Toeyew), 0.0f), gspecpower);
	
	FLOAT3 spec = t* (gspecmtrl*gspeclight). RGB;
	Attentuation.
	float d = distance (GLIGHTPOSW, PosW);
	
	Float A = gattenuation012.x + gattenuation012.y*d + gattenuation012.z*d*d;
	Spotlight factor. Float SPOt = POW (max (dot (-LIGHTVECW, GLIGHTDIRW), 0.0f), gspotpower);
	Everything together.
	
	FLOAT3 color = spot* (ambient + (diffuse + spec)/A);
	Pass on color and diffuse material alpha.
	
	Outvs.color = FLOAT4 (color, GDIFFUSEMTRL.A);
	Transform to homogeneous clip space.
	
	Outvs.posh = Mul (Float4 (POSL, 1.0f), GWVP);
    Done--return the output.
return Outvs;

} float4 Spotlightps (float4 c:color0): COLOR {return C;}
        Technique Spotlighttech {Pass P0 {//Specify the vertex and pixel shader associated with this pass.
        VertexShader = Compile vs_2_0 Spotlightvs ();
    PixelShader = Compile ps_2_0 Spotlightps (); }
}



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.