• 热门专题

Directx11教程(6) 画一个简单的三角形(2)

作者:迈克老狼2012  发布日期:2012-03-21 20:48:15
Tag标签:Directx11  三角形  
  • 在上篇文章中,我们实现了在D3D11中,画一个简单的三角形。

    但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变,如下图所示:

     


     

    是因为我们改变了窗口大小,但后缓冲大小在程序初始化时候,已经被指定,不随着窗口改变而改变,这样在视口映射下,我们所渲染的三角形就改变了行装。

    下面我们将对程序进行一些小的改动,从而实现改变窗口大小,而渲染的图形形状不变。

    首先是SystemClass.cpp,主要是增加了WM_SIZE消息的处理,当窗口大小改变时候,我们重新调用GraphicsClass的初始化函数。它的代码如下:

     

    #include "SystemClass.h"
    
    
    SystemClass::SystemClass(void) 
        { 
        m_Input = 0; 
        m_Graphics = 0; 
        }
    
    SystemClass::SystemClass(const SystemClass &) 
        {
    
        }
    
    SystemClass::~SystemClass(void) 
        { 
        }
    
    //调用窗口初始化函数和其它一些类的初始化函数 
    bool SystemClass::Initialize() 
        { 
        bool result; 
        int screenWidth = 0, screenHeight = 0;
    
       // 初始化窗口 
        InitializeWindows(screenWidth, screenHeight);
    
        //创建input对象处理键盘输入 
        m_Input = new InputClass; 
        if(!m_Input) 
            { 
            return false; 
            }
    
       // 初始化输入对象. 
        m_Input->Initialize();
    
        // 创建图形对象,这个对象将渲染应用程序中的所有物体 
        m_Graphics = new GraphicsClass; 
        if(!m_Graphics) 
            { 
            return false; 
            } 
        // 初始化图形对象 
        result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd); 
        if(!result) 
            { 
            return false; 
            }
    
    
        return true; 
        }
    
    void SystemClass::Shutdown() 
        { 
        //其它类的一些销毁工作 
        if(m_Graphics) 
            { 
            m_Graphics->Shutdown(); 
            delete m_Graphics; 
            m_Graphics = 0; 
            }
    
        if(m_Input) 
            { 
            delete m_Input; 
            m_Input = 0; 
            } 
        // 执行一些销毁工作. 
        ShutdownWindows();
    
        }
    
    //处理消息 
    void  SystemClass::Run() 
        { 
        MSG msg; 
        bool done, result ;
    
    
        // 初始化消息结构. 
        ZeroMemory(&msg, sizeof(MSG));
    
        // 循环进行消息处理,如果接收到WM_QUIT. 
        done = false; 
        while(!done) 
            { 
            // 处理windows消息. 
            if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
                { 
                TranslateMessage(&msg); 
                DispatchMessage(&msg); 
                }
    
            // 接收到WM_QUIT消息,退出程序. 
            if(msg.message == WM_QUIT) 
                { 
                done = true; 
                } 
            else 
                {
    
                //我们的渲染或者其它处理,可以放在这儿 
                //.... 
                //..... 
                result = Frame(); 
                if(!result) 
                    { 
                    done = true; 
                    } 
                }
    
            }
    
        return; 
        }
    
    bool SystemClass::Frame() 
        { 
        bool result;
    
    
        //检测用户是否按下ESC键,如果按下,退出程序. 
        if(m_Input->IsKeyDown(VK_ESCAPE)) 
            { 
            return false; 
            }
    
        // 执行帧渲染函数. 
        result = m_Graphics->Frame(); 
        if(!result) 
            { 
            return false; 
            } 
        return true; 
        }
    
    //初始化窗口类,创建应用程序窗口 
    void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight) 
        { 
        WNDCLASSEX wc; 
        DEVMODE dmScreenSettings; 
        int posX, posY;
    
        //得到应用程序对象指针 
        ApplicationHandle = this;
    
        // 得到应用程序实例句柄 
        m_hinstance = GetModuleHandle(NULL);
    
        // 应用程序名字 
        m_applicationName = L"Engine";
    
       // 设置窗口类参数. 
        wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
        wc.lpfnWndProc   = WndProc; //指定回调函数 
        wc.cbClsExtra    = 0; 
        wc.cbWndExtra    = 0; 
        wc.hInstance     = m_hinstance; 
        wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO); 
        wc.hIconSm       = wc.hIcon; 
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
        wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //默认黑色窗口黑色背景 
        wc.lpszMenuName  = NULL; 
        wc.lpszClassName = m_applicationName; 
        wc.cbSize        = sizeof(WNDCLASSEX);
    
       // 注册窗口类 
        RegisterClassEx(&wc);
    
        // 得到windows桌面分辨率 
        screenWidth  = GetSystemMetrics(SM_CXSCREEN); 
        screenHeight = GetSystemMetrics(SM_CYSCREEN);
    
        // 根据是否全屏设置不同的分辨率. 
        if(FULL_SCREEN) 
            { 
            //全屏模式下,设置窗口大小为windows桌面分辨率. 
            memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); 
            dmScreenSettings.dmSize       = sizeof(dmScreenSettings); 
            dmScreenSettings.dmPelsWidth  = (unsigned long)screenWidth; 
            dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight; 
            dmScreenSettings.dmBitsPerPel = 32;            
            dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
    
            // 临时设置显示设备为全屏模式,注意:应用程序退出时候,将恢复系统默认设置。 
            ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
    
            // 设置窗口的默认位置为(0,0). 
            posX = posY = 0; 
            } 
        else 
            { 
            // 窗口模式:800*600. 
            screenWidth  = 800; 
            screenHeight = 600;
    
            // 窗口位置,posX, posY窗口左上角坐标 
            posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth)  / 2; 
            posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2; 
            }
    
        // 全屏和窗口使用不同的参数. 
        if( FULL_SCREEN) 
            { 
            m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, 
                WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, 
                posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); 
            } 
        else 
            { 
            m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, 
                WS_OVERLAPPEDWINDOW, 
                posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); 
            }
    
        // 显示窗口并设置其为焦点. 
        ShowWindow(m_hwnd, SW_SHOW); 
        SetForegroundWindow(m_hwnd); 
        SetFocus(m_hwnd);
    
        // 隐藏鼠标. 
        //ShowCursor(false);
    
    
        }
    
    void SystemClass::ShutdownWindows() 
        { 
        //显示光标. 
        //ShowCursor(true);
    
        // 恢复默认显示设置. 
        if(FULL_SCREEN) 
            { 
            ChangeDisplaySettings(NULL, 0); 
            }
    
       // 销毁窗口 
        DestroyWindow(m_hwnd); 
        m_hwnd = NULL;
    
       // 销毁应用程序实例. 
        UnregisterClass(m_applicationName, m_hinstance); 
        m_hinstance = NULL; 
        ApplicationHandle = NULL;
    
        return;
    
        }
    
    LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) 
        {
    
        switch(umsg) 
            { 
            // 检测按键消息. 
        case WM_KEYDOWN: 
            { 
            m_Input->KeyDown((unsigned int)wparam); 
            return 0; 
            }
    
        case WM_KEYUP: 
            { 
            m_Input->KeyUp((unsigned int)wparam); 
            return 0; 
            } 
            //任何其它消息发送到windows缺省处理. 
        case WM_SIZE: 
            { 
            int screenWidth = 0, screenHeight = 0; 
            screenWidth  = LOWORD(lparam); 
            screenHeight = HIWORD(lparam); 
            // 窗口大小改变时,重新初始化图形对象 
            if(m_Graphics) 
                { 
                bool result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd); 
                if(!result) 
                    { 
                    return false; 
                    } 
                }
    
            return 0; 
            } 
        default: 
            { 
            return DefWindowProc(hwnd, umsg, wparam, lparam); 
            } 
            } 
        }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) 
        { 
        switch(umessage) 
            {
    
            // 窗口销毁消息. 
        case WM_DESTROY: 
            { 
            PostQuitMessage(0); 
            return 0; 
            }
    
            // 窗口关闭消息. 
        case WM_CLOSE: 
            { 
            PostQuitMessage(0);        
            return 0; 
            }
    
            //MessageHandle过程处理其它所有消息. 
        default: 
            { 
            return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam); 
            } 
            } 
        }
    
    

    GraphicsClass.cpp的初始化函数也进行了小小的改动,就是在函数的开始,先调用Shutdown()函数。

     

    bool GraphicsClass:: Initialize(int screenWidth, int screenHeight, HWND hwnd) 
        { 
        bool result;
    
        //如果对象已经存在,先释放掉它们 
        Shutdown();
    
        // 创建一个D3DClass对象. 
        m_D3D = new D3DClass; 
        if(!m_D3D) 
            { 
            return false; 
            }
    
        // 调用D3DClass初始化函数 
        result = m_D3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK); 
            return false; 
            }
    
        //创建摄像机对象 
        m_Camera = new CameraClass; 
        if(!m_Camera) 
            { 
            return false; 
            }
    
        // 设置摄像机位置. 
        m_Camera->SetPosition(0.0f, 0.0f, -10.0f);
    
        // 创建模型对象. 
        m_Model = new ModelClass; 
        if(!m_Model) 
            { 
            return false; 
            }
    
        // 初始化模型对象. 
        result = m_Model->Initialize(m_D3D->GetDevice()); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK); 
            return false; 
            }
    
        // 创建shader对象 
        m_ColorShader = new ColorShaderClass; 
        if(!m_ColorShader) 
            { 
            return false; 
            }
    
        // 初始化shader对象 
        result = m_ColorShader->Initialize(m_D3D->GetDevice(), hwnd); 
        if(!result) 
            { 
            MessageBox(hwnd, L"Could not initialize the color shader object.", L"Error", MB_OK); 
            return false; 
            }
    
        return true; 
        }
    
    
    第三个小改动是在D3CClass的初始化函数中,定义numerator和denominator这两个刷新率相关变量时候,要赋初值。如果不赋初值的话,当改变窗口大小时候,可能超找不到合适的刷新率,引起程序异常。
    代码如下:

    //Initialize函数包含完成D3D设置的所有代码。 
    bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, 
        float screenDepth, float screenNear) 
        { 
        HRESULT result; 
        IDXGIFactory* factory; 
        IDXGIAdapter* adapter; 
        IDXGIOutput* adapterOutput; 
        unsigned int numModes, i, numerator=0, denominator=1, stringLength; 
        DXGI_MODE_DESC* displayModeList; 
        DXGI_ADAPTER_DESC adapterDesc; 
        int error; 
        DXGI_SWAP_CHAIN_DESC swapChainDesc; 
        D3D_FEATURE_LEVEL featureLevel; 
        ID3D11Texture2D* backBufferPtr; 
        D3D11_TEXTURE2D_DESC depthBufferDesc; 
        D3D11_DEPTH_STENCIL_DESC depthStencilDesc; 
        D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; 
        D3D11_RASTERIZER_DESC rasterDesc; 
        D3D11_VIEWPORT viewport; 
        float fieldOfView, screenAspect;
    
    
       // 保存垂直同步设置 
        m_vsync_enabled = vsync;
    
        // 创建一个DirectX graphics interface factory. 
        result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 用接口工厂创建一个主显卡的适配 
        result = factory->EnumAdapters(0, &adapter); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       // 得到主适配器的输出. 
        result = adapter->EnumOutputs(0, &adapterOutput); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       //得到适合 DXGI_FORMAT_R8G8B8A8_UNORM 的显示模式. 
        result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        displayModeList = new DXGI_MODE_DESC[numModes]; 
        if(!displayModeList) 
            { 
            return false; 
            }
    
        // 保存显示模式到displayModeList中 
        result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        //遍历所有显示模式,得到刷新率两个参数值numerator 和 denominato 
        for(i=0; i<numModes; i++) 
            { 
            if(displayModeList[i].Width == (unsigned int)screenWidth) 
                { 
                if(displayModeList[i].Height == (unsigned int)screenHeight) 
                    { 
                    numerator = displayModeList[i].RefreshRate.Numerator; 
                    denominator = displayModeList[i].RefreshRate.Denominator; 
                    } 
                } 
            } 
       // 得到显卡描述 
        result = adapter->GetDesc(&adapterDesc); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       // 保存显存大小. 
        m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);
    
        //保存显卡描述串 
        //wcstombs_s, wide char转化为char 
        error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); 
        if(error != 0) 
            { 
            return false; 
            } 
       // 释放显示模式列表 
        delete [] displayModeList; 
        displayModeList = 0;
    
        //释放适配器输出. 
        adapterOutput->Release(); 
        adapterOutput = 0;
    
        //释放适配器 
        adapter->Release(); 
        adapter = 0;
    
        // 释放接口工厂. 
        factory->Release(); 
        factory = 0;
    
       // 初始化交换链描述 
        ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
    
        // 用1个后缓冲 
        swapChainDesc.BufferCount = 1;
    
        //帧缓冲的大小和应用程序窗口大小相等. 
        swapChainDesc.BufferDesc.Width = screenWidth; 
        swapChainDesc.BufferDesc.Height = screenHeight;
    
        // 后缓冲的surface的格式为DXGI_FORMAT_R8G8B8A8_UNORM. 
        // surface的每个像素用4个无符号的8bit[映射到0-1]来表示。NORM表示归一化。 
        swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    
        // 如果使用垂直同步,设置后缓冲的刷新率。. 
        //刷新率就是一秒钟把后缓冲内容在屏幕上画出的次数。 
        //如果开启垂直同步,则锁定刷新率,则fps是固定的 
        if(m_vsync_enabled) 
            { 
            swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; 
            swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; 
            } 
        else 
            { 
            swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; 
            swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 
            }
    
        // 设置后缓冲的用途 
        // 我们的渲染目标缓冲为后缓冲。 
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    
       // 后缓冲输出的窗口句柄. 
        swapChainDesc.OutputWindow = hwnd;
    
        // 不使用多重采样 
        swapChainDesc.SampleDesc.Count = 1; 
        swapChainDesc.SampleDesc.Quality = 0;
    
       // 设置全屏或者窗口模式. 
        if(fullscreen) 
            { 
            swapChainDesc.Windowed = false; 
            } 
        else 
            { 
            swapChainDesc.Windowed = true; 
            }
    
        // 设定扫描线ordering以及缩放为unspecified. 
        swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
        swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    
        // 后缓冲内容呈现到屏幕后,放弃其内容 
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    
        //不设置标志 
        swapChainDesc.Flags = 0;
    
        // 设置feature level为D3D11 
        // 如果显卡不支持D3D11,我们能够通过设置这个参数,使用D3D10,或者9. 
        featureLevel = D3D_FEATURE_LEVEL_11_0;
    
        // 创建交换链,设备以及设备上下文. 
        result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, 
            D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       // 得到交换链中的后缓冲指针. 
        result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       // 用后缓冲创建渲染目标视图. 
        result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        //释放后缓冲.(引用计数减1) 
        backBufferPtr->Release(); 
        backBufferPtr = 0;
    
        // 初始化深度缓冲描述. 
        ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
    
        //设置深度缓冲描述 
        depthBufferDesc.Width = screenWidth; 
        depthBufferDesc.Height = screenHeight; 
        depthBufferDesc.MipLevels = 1;//对于深度缓冲为1 
        depthBufferDesc.ArraySize = 1;//对于深度缓冲为1,对于纹理,这2个参数有更多用途 
        depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
        depthBufferDesc.SampleDesc.Count = 1; 
        depthBufferDesc.SampleDesc.Quality = 0; 
        depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; 
        depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; 
        depthBufferDesc.CPUAccessFlags = 0; 
        depthBufferDesc.MiscFlags = 0;
    
       // 创建深度缓冲. 
        result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); 
        if(FAILED(result)) 
            { 
            return false;
    
            }
    
       // 初始化深度模版状态描述. 
        ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
    
       // 设置深度模版状态描述. 
        depthStencilDesc.DepthEnable = true; 
        depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; //D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲 
        depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
    
        depthStencilDesc.StencilEnable = true; 
        depthStencilDesc.StencilReadMask = 0xFF; 
        depthStencilDesc.StencilWriteMask = 0xFF;
    
       // 对于front face 像素使用的模版操作操作. 
        depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; 
        depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    
        // 对于back face像素使用的模版操作模式. 
        depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; 
        depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 
        depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    
        // 创建深度模版状态,使其生效 
        result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); 
        if(FAILED(result)) 
            { 
            return false;
    
            }
    
        // 设置深度模版状态. 
        m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);
    
        // 初始化深度模版视图. 
        ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
    
        // 设置深度模版视图描述. 
        depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
        depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 
        depthStencilViewDesc.Texture2D.MipSlice = 0;
    
        // 创建深度模版视图. 
        result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
        // 绑定渲染目标视图和深度缓冲到渲染管线. 
        m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
    
    
       // 设置光栅化描述,指定多边形如何被渲染. 
        rasterDesc.AntialiasedLineEnable = false; 
        rasterDesc.CullMode = D3D11_CULL_BACK; 
        rasterDesc.DepthBias = 0; 
        rasterDesc.DepthBiasClamp = 0.0f; 
        rasterDesc.DepthClipEnable = true; 
        rasterDesc.FillMode = D3D11_FILL_SOLID; 
        rasterDesc.FrontCounterClockwise = false; 
        rasterDesc.MultisampleEnable = false; 
        rasterDesc.ScissorEnable = false; 
        rasterDesc.SlopeScaledDepthBias = 0.0f;
    
        // 创建光栅化状态 
        result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); 
        if(FAILED(result)) 
            { 
            return false; 
            }
    
       //设置光栅化状态,使其生效 
        m_deviceContext->RSSetState(m_rasterState);
    
    
        // 设置视口,显示全部后缓冲内容 
        viewport.Width = (float)screenWidth; 
        viewport.Height = (float)screenHeight; 
        viewport.MinDepth = 0.0f; 
        viewport.MaxDepth = 1.0f; 
        viewport.TopLeftX = 0.0f; 
        viewport.TopLeftY = 0.0f;
    
       // 创建视口 
        m_deviceContext->RSSetViewports(1, &viewport);
    
       // 设置透视投影矩阵 
        fieldOfView = (float)D3DX_PI / 4.0f; 
        screenAspect = (float)screenWidth / (float)screenHeight;
    
        // 创建透视投影矩阵. 
        D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);
    
        //初始化world矩阵为单位矩阵. 
        //该矩阵实现局部坐标到世界坐标的转换 
        D3DXMatrixIdentity(&m_worldMatrix);
    
    
        // 创建正交投影矩阵,主要用来实施2D渲染. 
        D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth);
    
        return true;
    
    
        }
    
    

    程序运行后,现在我们再更变窗口大小,则三角形的形状不会改变。

     

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规