灯光

LPDIRECT3D9             g_pD3D       = NULL;     //用于建造D3D设备
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;     //设备描述
LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;     //缓冲区支持顶点渲染

//定义顶点的结构
struct CUSTOMVERTEX
{
	D3DXVECTOR3 position;           //顶点的坐标
	D3DXVECTOR3 normal;             //顶点的法线
};

//定义可变的顶点格式
// 要让灯光起作用,必须为顶点设置法线
// D3DFVF_XYZ		: 表示顶点坐标
// D3DFVF_NORMAL	: 表示一个顶点的法线
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

//初始化Direct3D
HRESULT D3D::InitD3D( HWND hWnd )
{
	//创造D3D对象,
	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;                                            //获得目前的硬件的显示模式信息
	//建立一个用来建造D3D设备的结构  D3DPRESENT_PARAMETERS
	D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );        //伸请结构变量空间
    d3dpp.Windowed = TRUE;                      //是否为窗口模式
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;   //换页模式
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;    //后缓冲区格式
	d3dpp.EnableAutoDepthStencil = TRUE;        //打开深度缓冲
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  //深度缓冲格式
	//产生符合显示模式的变量  g_pd3d
	// 创建D3D设备
	// 第一个参数:使用默认的显卡适配器
	// 第二个参数:请求使用硬件抽象层(HAL)
	// 第三个参数:窗口句柄
	// 第四个参数:使用软件处理顶点
	// 第五个参数:创建的参数
	// 第六个参数:创建的D3D设备指针
	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, 
		                              D3DDEVTYPE_HAL, 
									  hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, 
									  &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }
	// 关闭culling,让我们能看到3角型的正反面
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
	// 关闭灯光,因为我们的顶点有自己的颜色
	g_pd3dDevice->SetRenderState( D3DRS_ZENABLE,TRUE);
	return S_OK;
}
//填充顶点缓冲区
HRESULT D3D::InitVB()
{
	//创建顶点缓冲区
	//第一个参数表示缓冲区大小。
	//第二个参数暂时不管,填0。
	//第三个参数是我们自定义的FVF
	//第四个参数表示通过什么方式创建,用缺省值就好了
	//第五个参数返回缓冲区指针。
	if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
                                                  0, 
												  D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, 
												  &g_pVB, 
												  NULL ) ) )
    {
        return E_FAIL;
    }

	CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i=0; i<50; i++ )
    {
        FLOAT theta = (2*D3DX_PI*i)/(50-1);
        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].normal   = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
        pVertices[2*i+1].normal   = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
    }
    g_pVB->Unlock();
    return S_OK;
}
//释放以前已初始化的对象
void D3D::Cleanup()
{
	if( g_pVB != NULL )        
        g_pVB->Release();

    if( g_pd3dDevice != NULL) 
        g_pd3dDevice->Release();

    if( g_pD3D != NULL)
        g_pD3D->Release();
}
//绘制场景
void D3D::Render()
{
	if( NULL == g_pd3dDevice )
        return;

	//以蓝色的颜色值来清除后缓冲区
	g_pd3dDevice->Clear( 0, 
		                 NULL, 
						 D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,    //清除后缓冲区和zbuffer(深度缓冲)
		                 D3DCOLOR_XRGB(0,0,156),              //背景色
						 1.0f, 
						 0 );
	//开始绘制场景
	if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )     //插入描绘D3D对象的程序代码
    {
        
		//开灯
		SetupLights();	
		//在顶点缓冲区绘制三角形
		SetupMatrices();
		g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );  // 指定渲染源
		g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );                         // 指定自定义的FVF
		// 渲染
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,       //绘制的像素类型
			                         0,                         //索引到在顶点流中的一个元素
									 2*50-2 );                  //绘制图元的个数
    
        //结束绘制
        g_pd3dDevice->EndScene();
    }
	g_pd3dDevice->Present( NULL, NULL, NULL, NULL );    //将后缓冲区的数据显示出来
}

void D3D::SetupMatrices()
{
	D3DXMATRIXA16 matWorld;                                 //设置世界的矩阵数据

    D3DXMatrixRotationX( &matWorld, timeGetTime()/500.0f );     //旋转函数,只改变X轴来让对象旋转
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );       //设置该矩阵为D3D的当前世界矩阵

	D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );                         //定义摄影机坐标
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );                      //定义目标点坐标
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );                         //摄影机朝上的方向坐标
    D3DXMATRIXA16 matView;                                          //设置目标点的矩阵数据

    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );   //设置摄影机矩阵的函数
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );          // 设置该矩阵为D3D的当前观察矩阵

	//设置摄象机的射影矩阵
	D3DXMATRIXA16 matProj;                                       //设置射影矩阵的数据
	// 建立一个基于左手坐标系的射影矩阵
    D3DXMatrixPerspectiveFovLH( &matProj,          //返回射影的矩阵
		                        D3DX_PI/4,         //可视的角度
								1.0f,              //纵横比(屏幕高宽比)
								1.0f,              //最近的距离
								100.0f );          //最远的距离
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );    //设置该矩阵为D3D的当前射影矩阵
}

void D3D::SetupLights()
{

	//设置一个材质,颜色为黄色的漫射环境光
	D3DMATERIAL9 mtrl;
    ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
    mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
    mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pd3dDevice->SetMaterial(&mtrl);

	//设置一个白色的方向光
	D3DXVECTOR3 vecDir;                        //3D向量的结构
    D3DLIGHT9 light;                           //光的结构变量
    ZeroMemory( &light, sizeof(D3DLIGHT9) );   //伸请结构变量空间
    light.Type       = D3DLIGHT_DIRECTIONAL;   //光的类型

	//光的颜色
    light.Diffuse.r  = 255.0f;                   //红色的量
    light.Diffuse.g  = 255.0f;                   //绿色的量
    light.Diffuse.b  = 255.0f;                   //蓝色的量
    
	vecDir = D3DXVECTOR3(cosf(timeGetTime()/350.0f),
                         1.0f,
                         sinf(timeGetTime()/350.0f) );
	D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
    
	light.Range       = 1000.0f;               //光的范围
    g_pd3dDevice->SetLight( 0, &light );       // 设置0号灯为我们设置的灯
    g_pd3dDevice->LightEnable( 0, TRUE );      // 打开0号灯光
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING,TRUE);

	//打开一些环境光              光的颜色           颜色
	g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
}

你可能感兴趣的:(struct,null,Parameters,float)