⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 light.cpp

📁 是《3D游戏编程》的代码 买了这本书
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    memcpy( pVertices, pVerticesEllipse, dwNumVertices*sizeof(CUSTOMVERTEX) );
	
	// 顶点缓冲区的解锁操作
    g_pMyVxBufferEllipse->Unlock();
	delete pVerticesEllipse;
*/
	InitGeometry();

	g_Player.LookAt[0] = D3DXVECTOR3( 0.0f, 1.0f,-4.0f );
	g_Player.LookAt[1] = D3DXVECTOR3( 0.0f, 1.0f,-3.0f );
	g_Player.LookAt[2] = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    g_lightPosition = D3DXVECTOR3( 0.0f, 1.0f,-4.0f );

	return S_OK;
}

//-----------------------------------------------------------------------------
// 名称: SetupPointLights()
// 功能: 建立一个点灯光
//-----------------------------------------------------------------------------
VOID SetupPointLights(D3DXVECTOR3 Position, ULONG ulIndex, D3DCOLORVALUE Color)
{
    D3DXVECTOR3 vecDir;
    D3DLIGHT8 light;
    ZeroMemory( &light, sizeof(D3DLIGHT8) );
    light.Type       = D3DLIGHT_POINT ;
    light.Diffuse.r  = Color.r;
    light.Diffuse.g  = Color.g;
    light.Diffuse.b  = Color.b;

	light.Position	 = Position;				 
    light.Range       = 20.0f;
	light.Attenuation0 = 1.0f;
    g_pMyd3dDevice->SetLight( ulIndex, &light );
    g_pMyd3dDevice->LightEnable( 0, TRUE );
    g_pMyd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
	return;

}

//-----------------------------------------------------------------------------
// 名称: MatricesTrans()
// 功能: 处理转换操作
//-----------------------------------------------------------------------------
VOID MatricesTrans()
{
	// 进行观察坐标系转换
	D3DXMATRIX matView;

    D3DXMatrixLookAtLH( &matView, &(g_Player.LookAt[0]),
                                  &(g_Player.LookAt[1]),
                                  &(g_Player.LookAt[2]) );

    g_pMyd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // 进行透视转换
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2.5, 1.0f, 1.0f, 100.0f );
    g_pMyd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

}

//-----------------------------------------------------------------------------
// 名称: ProcInput()
// 功能: 处理外部控制设备的输入
//-----------------------------------------------------------------------------
VOID ProcInput()
{
	if(KEYDOWN(VK_DOWN))
	{
	    g_Player.LookAt[0].x = g_Player.LookAt[0].x-sinf(g_Angle)/20;
        g_Player.LookAt[0].z = g_Player.LookAt[0].z-cosf(g_Angle)/20;

		g_Player.LookAt[1].x = g_Player.LookAt[1].x-sinf(g_Angle)/20;
        g_Player.LookAt[1].z = g_Player.LookAt[1].z-cosf(g_Angle)/20;

		g_lightPosition.x = g_lightPosition.x - sinf(g_Angle)/20;
		g_lightPosition.z = g_lightPosition.z-cosf(g_Angle)/20;
	}

	if(KEYDOWN(VK_UP))
	{
	    g_Player.LookAt[0].x = g_Player.LookAt[0].x+sinf(g_Angle)/20;
        g_Player.LookAt[0].z = g_Player.LookAt[0].z+cosf(g_Angle)/20;

		g_Player.LookAt[1].x = g_Player.LookAt[1].x+sinf(g_Angle)/20;
        g_Player.LookAt[1].z = g_Player.LookAt[1].z+cosf(g_Angle)/20;

	    g_lightPosition.x = g_lightPosition.x+sinf(g_Angle)/20;
        g_lightPosition.z = g_lightPosition.z+cosf(g_Angle)/20;

	}

	if(KEYDOWN(VK_RIGHT))
	{
		g_Angle+=0.01f;
        g_Player.LookAt[1].x = g_Player.LookAt[0].x+sinf(g_Angle);
        g_Player.LookAt[1].z = g_Player.LookAt[0].z+cosf(g_Angle);
	}

	if(KEYDOWN(VK_LEFT))
	{
		g_Angle-=0.01f;
        g_Player.LookAt[1].x = g_Player.LookAt[0].x+sinf(g_Angle);
        g_Player.LookAt[1].z = g_Player.LookAt[0].z+cosf(g_Angle);
	}

	return;
}

//-----------------------------------------------------------------------------
// 名称: RenderSene()
// 功能: 渲染3D场景
//-----------------------------------------------------------------------------
VOID RenderSene()
{
	D3DXMATRIX matWorld;
	
	//检查Direct3D设备是否已经创建,如果没有创建就直接返回
    if( NULL == g_pMyd3dDevice )
        return;
	D3DCOLORVALUE       color;
	color.r = 1.0f;
	color.b = 1.0f;
	color.g = 1.0f;

    // 清除Direct3D设备的后台表面,背景颜色为蓝色RGB(0,0,255)
    g_pMyd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
						D3DCOLOR_XRGB(0,100,255), 1.0f, 0 );
    
    // 打开3D渲染开关
    g_pMyd3dDevice->BeginScene();

	D3DXMatrixIdentity(&matWorld);
	g_pMyd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

	D3DMATERIAL8 mtrl;
    ZeroMemory( &mtrl, sizeof(D3DMATERIAL8) );
    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_pMyd3dDevice->SetMaterial( &mtrl );

    // 设置一个点灯光
	SetupPointLights( g_lightPosition,0, color);

	//**************************************************************
	// 渲染地面
	//**************************************************************

	// 设置待渲染顶点的来源
    g_pMyd3dDevice->SetStreamSource( 0, g_pMyVxBufferLine, sizeof(CUSTOMVERTEX) );

    // 进行3D渲染,在这里设置渲染的顶点格式,并调用DrawPrimitive完成顶点渲染处理
    g_pMyd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );

	g_pMyd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, NUM_GRID*NUM_GRID );

	//**************************************************************
	// 渲染墙面
	//**************************************************************
	// 设置待渲染顶点的来源
    g_pMyd3dDevice->SetStreamSource( 0, g_pMyVxBufferRec, sizeof(CUSTOMVERTEX01) );

    // 进行3D渲染,在这里设置渲染的顶点格式,并调用DrawPrimitive完成顶点渲染处理
    g_pMyd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX01 );

	float i, j;
	for (i = -GRID_WIDTH/2 + 1; i < GRID_WIDTH/2; i+=4)
	{
		for(j = -GRID_WIDTH/2 + 1; j < GRID_WIDTH/2; j+=4)
		{
			if((j > -2) && (j < 2))
				continue;

			// 为不同的墙面设置不同的材质
			float r = 1 - 1.0f/i;
			float g = 1 - 1.0f/j;
			float a = 1 - 1.0f/(i+j);

			mtrl.Diffuse.r = mtrl.Ambient.r = r;
			mtrl.Diffuse.g = mtrl.Ambient.g = g;
			mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
			mtrl.Diffuse.a = mtrl.Ambient.a = a;

			mtrl.Specular.r = mtrl.Specular.g =mtrl.Specular.b = 1.0f;
			mtrl.Specular.a = 1.0f;
			mtrl.Power = 50.0f;

			g_pMyd3dDevice->SetMaterial( &mtrl );

			D3DXMatrixTranslation( &matWorld, j, 0, i );
			g_pMyd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

			g_pMyd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
		}
	}
//	g_pMyd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );



	// 初始化圆柱体位置,以及指定顶点来源
   	D3DXMatrixTranslation( &matWorld, 0, 1, 0 );
	g_pMyd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
	g_pMyd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX01) );
    g_pMyd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX01 );

	// 设置圆柱体的自发光材质
	mtrl.Emissive.r = 0.0f;
	mtrl.Emissive.g = 1.0f;
	mtrl.Emissive.b = 1.0f;
	mtrl.Emissive.a = 1.0f;
    g_pMyd3dDevice->SetMaterial( &mtrl );

    g_pMyd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*100-2 );
	// 关闭3D渲染开关
    g_pMyd3dDevice->EndScene();
    // 展现后台表面到窗口的客户区域中,即把渲染后的图像显示到窗口中
    g_pMyd3dDevice->Present( NULL, NULL, NULL, NULL );
	
	return;
}


//-----------------------------------------------------------------------------
// 名称: Cleanup()
// 功能: 释放创建过的Direct3D对象和设备
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if(g_pVB != NULL)
		g_pVB->Release();

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

	// 释放时的顺序为先释放后创建的对象,设备后创建,先释放
	if( g_pMyd3dDevice != NULL) 
        g_pMyd3dDevice->Release();

	// Direct3D对象最先创建,但需要最后释放
    if( g_pMyD3D != NULL)
        g_pMyD3D->Release();

	return;
}


//-----------------------------------------------------------------------------
// 名称: MsgProc()
// 功能: Windows的消息处理函数
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;

    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

//-----------------------------------------------------------------------------
// 名称: WinMain()
// 功能: Windows主函数,程序启动时,从这里开始执行
//-----------------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    // 定义一个Windows类,指定消息的处理函数为MsgProc
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      MY_WINCLASS_NAME, NULL };
	// 注册这个窗口类
    RegisterClassEx( &wc );

    // 创建应用程序窗口
    HWND hWnd = CreateWindow( MY_WINCLASS_NAME, "3D游戏编程——使用材质", 
                              WS_OVERLAPPEDWINDOW, 100, 100, 400, 300,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    // 调用InitMy3D函数进行3D对象和设备的创建,传入参数为窗口的句柄hWnd
    if( SUCCEEDED( InitMy3D( hWnd ) ) )
    { 
        // 显示窗口
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        // 程序主循环,进行窗口消息的分发,消息的处理在MsgProc函数中完成
        MSG msg; 
        while( msg.message != WM_QUIT)
        {
			if(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ))
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
			
			ProcInput();
			MatricesTrans();
			RenderSene();
			
        }
    }

    // 调用Cleanup函数清除3D对象和设备
    Cleanup();

	// 注销窗口类
    UnregisterClass( MY_WINCLASS_NAME, wc.hInstance );
    return 0;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -