美文网首页
创建D3D窗口(二)

创建D3D窗口(二)

作者: 六六大魔头 | 来源:发表于2018-11-27 00:01 被阅读0次

    D3D创建(二)

    • 上篇文章我们实现了普通的Windows窗口,这次我们就要在之前代码的基础上将其改写成d3d窗口。
      首先要做的是包含头文件d3d9.h,然后设定库目录,包含目录,并链接LIB文件。删除以前写的包含windows.h头文件的代码,因为在d3d9.h中已经帮我们包含了windows.h头文件,我们在包含的话就会产生重复包含错误。

    要把普通窗口改造成d3d窗口,我们实现4个函数——初始化d3d、初始化物体、绘制、释放内存。
    首先我们定义出设备指针,设备对象指针。

    #include"d3d9.h"
    #pragma comment(lib,"d3d9.lib")
    LPDIRECT3D9 g_D3D = NULL;
    //D3D指针
    LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
    //D3D设备对象指针
    

    实现第一个函数,用于初始化D3D设备对象

    bool initialized3d(HWND hWnd,bool FullScreen)
    

    函数返回值为布尔型,用于接收处理结果
    参数HWND:要初始化的句柄
    参数bool:要初始化的是否是全屏窗口

    bool InitializeD3D(HWND hWnd,bool FullScreen)
    {
     D3DDISPLAYMODE displaymode;
    //D3D显示模式结构体,用于获取显卡的能力信息
    g_D3D= Direct3DCreate9(D3D_SDK_VERSION);
    //根据D3D版本创建D3D对象指针
    if(g_D3D!= NULL) return false;
    
      if (g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displaymode)) return false;
    //D3DADPTER_DEFUALT    指定获取的设备 这里指定默认显卡
    //displaymode                        所有获取信息填充进的结构体
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
    if (FullScreen)
    {
    d3dpp.Windowed = false;
    d3dpp.BackBufferWidth = WindowWidth;
    dedpp.BackBufferHeight = WindowHeight;
    }
    else
    {
            d3dpp.Windowed = TRUE;
    }
    //这里分全屏和窗口两个模式,在全屏模式下后台缓冲宽度和高度都不用指定
    //窗口模式下需要指定缓冲区大小 这里做个判断 如果窗口宽度高度都等于窗口宽度高度
    d3dpp.BackBufferFormat = displaymode.Format;
    //指定后台缓冲格式 之前获取的结构体内就有后台缓冲格式
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    //指定d3d后台交换模式 这里用最快的剪裁模式 类似的模式还有拷贝翻转等 根据自己需要选择
    if (FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&g_device);
    ))
    

    这里的D3DPARATERS结构体不需要我们填充所有值,如果是窗口,Windowed赋值FALSE,填入BackBufferWidth,BackBufferHeight,BackBufferFormat,SwapEffect。如果是全屏我们Windowed赋值TRUE,并填充BackBufferFormat,SwapEffect。参数功能如下
    BackBufferWidth,BackBufferHeight后台缓存大小,在全屏下无效,窗口模式下我直接赋值为窗口大小。
    BackBufferFormat 后台缓存格式,这里使用获取到的格式。
    SwapEffect 后备缓存区交换方式,我们使用最快的D3DSWAPEFFECT_DISCARD

    接下来改造一下我们的消息循环

    while (msg.message != WM_QUIT)
            {
                if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                else
                {
                    RenderScene();
                }
                      //此处修改效果为只要没有收到推出的消息便一直循环 获取到消息就立即处理消息,若没有消息就渲染D3D 选择在空闲时候渲染窗口
            }
    

    接下来我们实现渲染函数。

    Render()
    {
       g_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRBG(0,0,0),1.0f,0);
    //使用D3D设备对象内的Clear函数清空当前显示信息 
      g_D3DDevice->BeginScene();
    //开始渲染
    //这里写入渲染代码
      g_D3DDevice->EndScene();
    //结束渲染
      g_D3DDevice->Present(NULL,NULL,NULL,NULL);
    //显示渲染的帧
    }
    

    别忘记,用完所有指针后记得释放所有资源,大量的内存不释放将会导致内存泄漏。这里我创建Shutdown函数来释放已用资源

    void Shutdown()
    {
        if (g_D3DDevice != NULL) g_D3DDevice->Release();
        if (g_D3D != NULL) g_D3D->Release();
        //如果指针存在则释放指针资源
        g_D3DDevice = NULL;
        g_D3D = NULL;
            释放后指针赋空,杜绝空指针
    }
    

    完整代码

    #include "d3d9.h"
    
    #define ClassName               "UGPDX"
    #define WindowName          "Demo_Window"
    #define MenuName                NULL
    #define WINDOW_WIDTH    640
    #define WINDOW_HEIGHT    480
    
    #pragma comment(lib,"d3d9.lib")
    
    bool InitializeD3D(HWND hWnd, bool fullscreen);
    void RenderScene();
    void Shutdown();
    
    LPDIRECT3D9 g_D3D = NULL;
    LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
    
    LRESULT WINAPI WndPro(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
            break;
        }
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
    {
        WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,WndPro,NULL,NULL,hInstance,NULL,NULL,NULL
        ,MenuName,ClassName };
        RegisterClassEx(&wc);
        HWND hWnd = CreateWindowEx(NULL, ClassName, WindowName, WS_OVERLAPPEDWINDOW, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
        if (InitializeD3D(hWnd, false))
        {
            ShowWindow(hWnd, SW_SHOWDEFAULT);
            UpdateWindow(hWnd);
            MSG msg;
            ZeroMemory(&msg, sizeof(msg));
            while (msg.message != WM_QUIT)
            {
                if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                else
                {
                    RenderScene();
                }
            }
            Shutdown();
            UnregisterClass(ClassName, hInstance);
            return 0;
        }
        return 0;
    }
    
    bool InitializeD3D(HWND hWnd, bool fullscreen)
    {
        D3DDISPLAYMODE displaymode;
    
        g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
        if (!g_D3D) return false;
    
        if (g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displaymode)) return false;
    
        D3DPRESENT_PARAMETERS d3dpp;
        ZeroMemory(&d3dpp, sizeof(d3dpp));
    
        if (fullscreen)
        {
            d3dpp.Windowed = false;
            d3dpp.BackBufferWidth = WINDOW_WIDTH;
            d3dpp.BackBufferHeight = WINDOW_HEIGHT;
        }
        else
        {
            d3dpp.Windowed = TRUE;
        }
    
        d3dpp.BackBufferFormat = displaymode.Format;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    
    
        if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
            D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
        {
            return false;
        }
        return true;
    }
    
    void RenderScene()
    {
        g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
        g_D3DDevice->BeginScene();
        //开始渲染
    
    
    
        g_D3DDevice->EndScene();
        //结束场景渲染
        g_D3DDevice->Present(NULL, NULL, NULL, NULL);
        //显示渲染 
    }
    
    void Shutdown()
    {
        if (g_D3DDevice != NULL) g_D3DDevice->Release();
        if (g_D3D != NULL) g_D3D->Release();
    
        g_D3DDevice = NULL;
        g_D3D = NULL;
    }
    

    相关文章

      网友评论

          本文标题:创建D3D窗口(二)

          本文链接:https://www.haomeiwen.com/subject/owtwqqtx.html