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

📄 viewtrans.cpp

📁 是《3D游戏编程》的代码 买了这本书
💻 CPP
字号:
//-----------------------------------------------------------------------------
// 名称: RenderSene.cpp
// 
// 功能: 进行3D场景的渲染——使用显示内存的顶点缓冲区。
//       
//-----------------------------------------------------------------------------

// 包含Direct3D头文件
#include <d3d8.h>
#include <d3dx8.h>

// Windows类的名称宏定义
#define  MY_WINCLASS_NAME      "Direct3D"

// 定义个表示顶点的结构
struct CUSTOMVERTEX
{
    FLOAT x, y, z; // x,y,z表示点的三维坐标值,
    DWORD color;        // 顶点颜色
};

// 自定义的顶点格式
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

// 定义全局变量
LPDIRECT3D8             g_pMyD3D          = NULL; // 定义Direct3D对象的指针
LPDIRECT3DDEVICE8       g_pMyd3dDevice    = NULL; // 定义Direct3D设备指针
LPDIRECT3DVERTEXBUFFER8 g_pMyVxBuffer     = NULL; // 定义顶点缓冲区对象指针
BOOL                    g_bWinActive;
  
D3DPRESENT_PARAMETERS   g_d3dpp;                       // 定义Present结构 


// 定义包含24个顶点的顶点数组
CUSTOMVERTEX g_Vertices[] =
{
        { -0.5f,-0.5f, 0.0f, 0xffff0000, },  
        { -0.5f, 0.5f, 0.0f, 0xffff0000, },
		{  0.5f,-0.5f, 0.0f, 0xffff0000, },
		{  0.5f, 0.5f, 0.0f, 0xffff0000, },  

};
//-----------------------------------------------------------------------------
// 名称: InitD3D()
// 功能: 初始化3D环境的函数,函数中创建了Direct3D对象和Direct3D设备。
//       函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT InitMy3D( HWND hWnd )
{
    // 创建Direct3D对象,是使用Direct3D的第一步操作
    if( NULL == ( g_pMyD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 获取当前Windows桌面的显示模式,保存到定义的d3ddm结构中
    D3DDISPLAYMODE d3ddm;
    if( FAILED( g_pMyD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
        return E_FAIL;

	// 定义Present结构   
    D3DPRESENT_PARAMETERS d3dpp; 

    // 把结构清零,创建设备时,结构中成员值为0表示使用缺省值 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );

	// 指定创建的Direct3D是支持窗口的设备
    d3dpp.Windowed = FALSE;

    // 设置设备展示表面的输出窗口
	d3dpp.hDeviceWindow = hWnd;

	d3dpp.BackBufferWidth  = 800;
    d3dpp.BackBufferHeight = 600;

	// 指定交换效果为D3DSWAPEFFECT_DISCARD,即把后台表面显示到前台表面以后,
	// 原来的后台表面包含的信息自动丢失
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

	// 后台缓冲区的的点格式为16位RGB色彩
    d3dpp.BackBufferFormat = D3DFMT_R5G6B5;

	memcpy(&g_d3dpp, &d3dpp, sizeof(D3DPRESENT_PARAMETERS));

	// 创建Direct3D设备:
	// 1. 使用主显卡创建设备,参数D3DADAPTER_DEFAULT
	// 2. 设备类型为硬件抽象设备,使用硬件加速功能,参数D3DDEVTYPE_HAL
    // 3. 使用前面创建的窗口用于目标表面的显示,参数hWnd
	// 4. 指定设备的对于顶点的处理能力为软件处理顶点,这是为了能够让所有
	//    的显卡支持,参数D3DCREATE_SOFTWARE_VERTEXPROCESSING
    if( FAILED( g_pMyD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pMyd3dDevice ) ) )
    {
        return E_FAIL;
    }

    g_pMyd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    g_pMyd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );


	// 创建顶点缓冲区
    if( FAILED( g_pMyd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_MANAGED, &g_pMyVxBuffer ) ) )
    {
        return E_FAIL;
    }

    // 定义一个保存顶点缓冲区内存地址的指针
    VOID* pVertices;

	// 获得顶点缓冲区的内存指针,并锁定顶点缓冲区
    if( FAILED( g_pMyVxBuffer->Lock( 0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
	{
        return E_FAIL;
	}

	// 复制顶点数据到顶点缓冲区中
    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );

	// 顶点缓冲区的解锁操作
    g_pMyVxBuffer->Unlock();
	
	// 进行观察坐标系转换
	D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 0.0f,-2.0f ),
                                  &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
                                  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    g_pMyd3dDevice->SetTransform( D3DTS_VIEW, &matView );

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

    return S_OK;
}

VOID Cleanup();

//-----------------------------------------------------------------------------
// 名称: RenderSene()
// 功能: 渲染3D场景
//-----------------------------------------------------------------------------
VOID RenderSene(HWND hWnd )
{
	HRESULT hr;

    // 测试设备的协作能力,是否可以正常渲染
    if(FAILED( hr = g_pMyd3dDevice->TestCooperativeLevel() ) )
    {
        // 假如设备丢失,不能进行渲染
        if( D3DERR_DEVICELOST == hr )
            return;

        // 检查设备是否需要重新设置
        if( D3DERR_DEVICENOTRESET == hr )
        {
            if( FAILED(hr = g_pMyd3dDevice->Reset(&g_d3dpp) ) )
                return;

			 g_pMyd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

			 g_pMyd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
			
			// 进行观察坐标系转换
			D3DXMATRIX matView;
			D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 0.0f,-2.0f ),
                                 &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
                                  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
			g_pMyd3dDevice->SetTransform( D3DTS_VIEW, &matView );

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

	//检查Direct3D设备是否已经创建,如果没有创建就直接返回
    if( NULL == g_pMyd3dDevice )
        return;

	// 进行世界坐标系转换
	D3DXMATRIX matWorld;
	D3DXMatrixRotationY( &matWorld, timeGetTime()/100.0f );
	g_pMyd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
			
    // 清除Direct3D设备的后台表面,背景颜色为蓝色RGB(0,0,255)
    g_pMyd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
    
    // 打开3D渲染开关
    g_pMyd3dDevice->BeginScene();
    
	// 设置待渲染顶点的来源
    g_pMyd3dDevice->SetStreamSource( 0, g_pMyVxBuffer, sizeof(CUSTOMVERTEX) );

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

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


//-----------------------------------------------------------------------------
// 名称: Cleanup()
// 功能: 释放创建过的Direct3D对象和设备
//-----------------------------------------------------------------------------
VOID Cleanup()
{
	if( g_pMyVxBuffer != NULL)
		g_pMyVxBuffer->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;

        case WM_PAINT:
            ValidateRect( hWnd, NULL );
            return 0;

		case WM_SIZE:
            if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
                g_bWinActive = FALSE;
            else
                g_bWinActive = TRUE;
            break;
    }

    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, 0, 0, 800, 600,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

	// 设置窗口风格
    SetWindowLong( hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );

    // 调用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 );
			}
			else
			{
				if(g_bWinActive)
				{
					RenderSene(hWnd);
				}
			}
        }
    }

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

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



⌨️ 快捷键说明

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