예제 #1
0
int WINAPI WinMain( HINSTANCE inst, HINSTANCE, LPSTR cmdLine, int cmdShow )
{
	Window wnd;

	P(Context)				context		= 0;
	int						sw			= 640;
	int						sh			= 480;
	int						sbpp		= 0;
	bool					fullscreen	= (0 != sbpp);
	P(Scene)				root		= 0;

	try
	{
		// args
		String fxname = cmdLine;
		if ( fxname == "" )
			fxname = "bump.fx";

		// init window
		DWORD style = WS_VISIBLE;
		DWORD styleEx = 0;
		if ( fullscreen )
		{
			style |= WS_POPUP;
			styleEx |= WS_EX_TOPMOST;
		}
		else
		{
			style |= WS_OVERLAPPEDWINDOW;
		}
		wnd.create( "sgtestclass", "sg test", style, styleEx, 0, 0, sw, sh, inst, 0 );

		// init context
		context = new Context( "gd_dx8" );
		context->open( sw, sh, sbpp, 75,
			Context::SURFACE_TARGET + 
			Context::SURFACE_DEPTH + 
			Context::SURFACE_STENCIL,
			Context::RASTERIZER_HW, 
			Context::VERTEXP_HW,
			Context::TC_DISABLED );

		// scene
		root = new Scene;
		root->setName( "root" );

		// camera
		P(Camera) cam = new Camera;
		cam->setName( "cam" );
		cam->setPosition( Vector3(0,1.5f,-3) );
		Matrix3x3 rot = Matrix3x3( Vector3(1,0,0), Math::toRadians(30.f) );
		cam->setRotation( rot );
		cam->setHorizontalFov( Math::toRadians(100.f) );
		cam->setFront( 0.2f );
		cam->setBack( 100.f );
		cam->linkTo( root );

		// light
		P(DirectLight) lt = new DirectLight;
		lt->setName( "keylight" );
		lt->setIntensity( 0.5f );
		lt->linkTo( root );
		lt->lookAt( Vector3(-0.5f,-1,0) );

		// resources
		P(Texture) difmap = loadTex( "diffuse_map.tga" );
		P(Texture) normmap = loadTex( "normal_map.tga" );
		P(CubeTexture) envmap = loadCubeTex( "TestCubeTexture1.dds" );

		// read vb and ib data
		FileInputStream vbin( "vb.dat" );
		Array<uint8_t> vbbytes( vbin.available() );
		vbin.read( vbbytes.begin(), vbbytes.size() );
		int vertexSize = 4*3*4;
		int vertices = vbbytes.size() / vertexSize;
		FileInputStream ibin( "ib.dat" );
		Array<uint8_t> ibbytes( ibin.available() );
		ibin.read( ibbytes.begin(), ibbytes.size() );
		int indexSize = 2;
		int indices = ibbytes.size() / indexSize;

		// geometry (indirectly from vb and ib dat)
		VertexFormat vf; 
		vf.addNormal().addTextureCoordinate(3);
		P(Model) model = new Model( vertices, indices, vf );
		{
			VertexAndIndexLock<Model> lk( model, Model::LOCK_READWRITE );

			for ( int i = 0 ; i < vertices ; ++i )
			{
				model->setVertexPositions( i, (Vector3*)(vbbytes.begin()+i*vertexSize) );
				model->setVertexNormals( i, (Vector3*)(vbbytes.begin()+12+i*vertexSize) );
				model->setVertexTextureCoordinates( i, 0, 3, (float*)(vbbytes.begin()+24+i*vertexSize) );
			}

			void* idata;
			int istride;
			model->getIndexData( &idata, &istride );
			memcpy( idata, ibbytes.begin(), ibbytes.size() );
		}

		// env transform
		Matrix4x4 textm(0);
		textm(0,0) = 1.f;
		textm(1,1) = 1.f;
		textm(2,2) = 1.f;
		textm(0,3) = 0.f;
		textm(1,3) = 0.f;		
		textm(2,3) = 0.f;

		// material
		P(Material) mat = new Material;

		mat->setTexture( 0, difmap );
		
		mat->setTexture( 1, envmap );
		mat->setTextureColorCombine( 1, Material::TA_TEXTURE, Material::TOP_ADD, Material::TA_CURRENT );		
		mat->setTextureCoordinateTransform( 1, Material::TTFF_COUNT3, textm );
		mat->setTextureCoordinateSource( 1, Material::TCS_CAMERASPACENORMAL );

		mat->setVertexFormat( model->vertexFormat() );
		model->setShader( mat );

		// mesh
		P(Mesh) mesh = new Mesh;
		mesh->setName( "mesh" );
		mesh->linkTo( root );
		mesh->addPrimitive( model );
		cam->setRotationController( new sgu::LookAtControl(cam,mesh) );

		// floor
		vf = VertexFormat();
		vf.addNormal().addTextureCoordinate(2).addTextureCoordinate(2);
		P(Model) floormodel = createCube( 10, 0.01f, 10, vf );
		mat = new Material;
		mat->setDiffuseColor( Colorf(0,0,0) );
		mat->setEmissiveColor( Colorf(0.2f,0.2f,0.2f) );
		mat->setVertexFormat( floormodel->vertexFormat() );
		floormodel->setShader( mat );
		P(Mesh) floor = new Mesh;
		floor->setName( "floor" );
		floor->linkTo( root );
		floor->setPosition( Vector3(0,-2,0) );
		floor->addPrimitive( floormodel );

		// mesh position animation
		int keys = 8;
		{P(VectorInterpolator) anim = new VectorInterpolator(3);
		anim->setKeys( keys );
		for ( int i = 0 ; i < keys ; ++i )
		{
			float f = (float)i / (keys-1);
			float v[3] = { Math::sin(f*Math::PI*2.f)*2.f, 0, 0 };
			anim->setKeyValue( i, v, 3 );
			anim->setKeyTime( i, f * 4.f );
		}
		anim->sortKeys();
		mesh->setPositionController( anim );}

		// mesh rotation animation
		{P(QuaternionInterpolator) anim = new QuaternionInterpolator;
		anim->setKeys( keys );
		for ( int i = 0 ; i < keys ; ++i )
		{
			float f = (float)i / (keys-1);
			float ang = f * Math::PI*2.f;
			Quaternion quat( Vector3(0,1,0), ang );
			float v[] = {quat.x, quat.y, quat.z, quat.w};
			anim->setKeyValue( i, v, 4 );
			anim->setKeyTime( i, f * 3.f );
		}
		anim->sortKeys();
		mesh->setRotationController( anim );}

		// mesh scale animation
		/*{P(VectorInterpolator) anim = new VectorInterpolator(3);
		anim->setKeys( keys );
		for ( int i = 0 ; i < keys ; ++i )
		{
			float f = (float)i / (keys-1);
			float v[3] = { Math::abs(Math::sin(f*Math::PI*2.f))+.5f, 1.f, 1.f };
			anim->setKeyValue( i, v, 3 );
			anim->setKeyTime( i, f * 5.f );
		}
		anim->sortKeys();
		mesh->setScaleController( anim );}*/

		// shadow volume
		P(ShadowVolume) shadow = new ShadowVolume( model, lt->worldDirection(), 20.f );
		shadow->setShader( new ShadowShader );
		mesh->addPrimitive( shadow );

		// shadow filler
		VertexFormat fillvf;
		fillvf.addRHW().addDiffuse();
		P(Material) fillmat = new Material;
		fillmat->setDepthEnabled( false );
		fillmat->setDepthWrite( false );
		fillmat->setBlend( Material::BLEND_SRCALPHA, Material::BLEND_INVSRCALPHA );
		fillmat->setTextureColorCombine( 0, Material::TA_DIFFUSE, Material::TOP_SELECTARG1, Material::TextureArgument() );
		fillmat->setTextureAlphaCombine( 0, Material::TA_DIFFUSE, Material::TOP_SELECTARG1, Material::TextureArgument() );
		fillmat->setLighting( false );
		fillmat->setVertexColor( true );
		fillmat->setStencil( true );
		fillmat->setStencilRef( 1 );
		fillmat->setStencilFunc( Material::CMP_LESSEQUAL );
		fillmat->setStencilPass( Material::STENCILOP_KEEP );
		fillmat->setPass( ShadowShader::DEFAULT_SHADOW_FILL_PASS );
		fillmat->setVertexFormat( fillvf );

		// shadow filler geometry
		P(Model) fillgeom = new Model( 4, 6, fillvf );
		{VertexAndIndexLock<Model> lock( fillgeom, Model::LOCK_WRITE );
		Vector4 fillpos[4] = { Vector4(0,0,0,0), Vector4(sw,0,0,0), Vector4(sw,sh,0,0), Vector4(0,sh,0,0) };
		Color fillcolr[4] = { Color(0,0,0,80), Color(0,0,0,80), Color(0,0,0,80), Color(0,0,0,80) };
		int fillind[6] = { 0,1,2, 0,2,3 };
		fillgeom->setVertexPositionsRHW( 0, fillpos, 4 );
		fillgeom->setVertexDiffuseColors( 0, fillcolr, 4 );
		fillgeom->setIndices( 0, fillind, 6 );}

		fillgeom->setShader( fillmat );
		mesh->addPrimitive( fillgeom );

		// mainloop
		long prevTime = System::currentTimeMillis();
		float time = 0.f;
		while ( Window::flushWindowMessages() )
		{
			long curTime = System::currentTimeMillis();
			float dt = 1e-3f * (float)(curTime - prevTime);
			prevTime = curTime;

			if ( wnd.active() )
			{
				if ( GetKeyState('S') < 0 )
					dt *= 0.1f;
				if ( GetKeyState('R') < 0 )
					time = 0.f;
				if ( GetKeyState(VK_ESCAPE) < 0 )
					break;
				time += dt;

				for ( Node* node = root ; node ; node = node->nextInHierarchy() )
					node->setState( time );

				context->beginScene();
				cam->render();
				context->endScene();
				context->present();
				context->clear();
			}
		}

		context->destroy();
		wnd.destroy();
	}
	catch ( Throwable& e )
	{
		if ( context )
			context->destroy();

		MoveWindow( wnd.handle(), 0, 0, 0, 0, TRUE );
		char msg[1024] = "";
		e.getMessage().format().getBytes( msg, sizeof(msg), "ASCII-7" );
 		MessageBox( 0, msg, "Error", MB_OK );

		wnd.destroy();
	}
	return 0;
}