一、VS2015update2环境下DirectX11编程说明(2016.5.5更新)

本文索引:

  • 一 关于龙书
  • 二 在vs2015u2环境下编写DirectX11程序
  • 三 关于MSDN帮助文档
  • 四 官方示例项目
  • 五 自己尝试编写一个小项目
    • 1 创建一个win32项目
    • 2 配置依赖库
    • 3 添加源文件
    • 4 完成
  • 六 总结

一、 关于龙书

相信很多看想要学习DirectX编程的小伙伴都有听说过龙书,也就是官方推出的《Introduction to 3D Game Programming with Directx 9》这本书,从DirectX9开始,龙书作为最权威、详尽的DirectX编程学习资料早已广受好评,到现在Directx编程接口已经出到DirectX12了,龙书也即将推出《Introduction to 3D Game Programming with Directx 12》,但本小菜发现在之前阅读《Introduction to 3D Game Programming with Directx 11》的时候按照书上的说明已经无法找到Directx的编程SDK包。在查找资料和摸索后发现现在的Directx配置早已没有那么麻烦,于是总结一下,把经验分享出来给大家参考。

二、 在vs2015u2环境下编写DirectX11程序

从win8发售开发,DirectX编程SDK包就已经集成在windows SDK包中,所以想要使用DirectX接口进行2D和3D编程的小伙伴发现没有地方可以下载像DirectX9那样的SDK包了,那么是不是一定要下载windows SDK包呢?微软在这方面也为推广自己的IDE编程工具VISUAL提供了便利。对的,只要使用的是visual studio2012以上的编程环境,都已经预先集成了windows SDK包,区别只是不同版本的IDE和操作系统能获取到的示例工程不太一样,一般更高的版本中能够获得更全面的示例工程。

以下为官方声明:

Starting with Windows 8, the DirectX SDK is included as part of the Windows SDK.

Use a free, Visual Studio Community 2015 with Update 2 client that already includes the latest Windows 10 developer tools to get started creating innovative and compelling Universal Windows apps and Classic Windows applications. These tools include universal app templates, a code editor, a powerful debugger, Windows Mobile emulators, rich language support, and more, all ready to use in production. Includes the latest Windows Standalone SDK and mobile emulator releases.

这里官方提到的操作系统是win10,但使用win8进行编程的童鞋也可以继续使用visual studio2015,和win10下编程是一样的(但最新的direct12是在win10中才有的)。

所以使用vs2015做开发的童鞋已经不用再配置任何东西了。

三、 关于MSDN帮助文档

在VS2015中点击菜单栏“Help”->“Add and Remove Help Content”

打开“Microsoft Help View 2.0 - Visual Studio 2012文档”

单击“Recommended Documentation”=>“Windows Desktop Application Development”后面的”Add”链接,VS就会从服务器上将对应的帮助文档下载到本地。

更新完成后,可以从以下路径找到DirectX的说明文档:

“Desktop app technologies - Windows app development”=>”Graphics and Gaming - Windows app development”=>”DirectX Graphics and Gaming - Windows app development”

四、 官方示例项目

在VS2015菜单栏中依次点击”Tools”=>”Extensions and Updates”

在左侧点击”Online”=>”Samples Gallery”,左边将会展示出对应的线上示例项目列表,也可以直接在右上方的搜索框中搜索所想要的具体项目名。

找到所需要的示例项目后就可以直接点击项目后面的”Download”按钮下载项目到本地。

例如:

这个例子包含了一些最基本的接口使用,可以作为入门教程参考。

五、 自己尝试编写一个小项目

(1) 创建一个win32项目

      在VS2015中依次点击菜单栏"File"=>"New"=>"Project"

      设置好项目名称和路径后点击确定,继续填写后续设置,完成创建。

(2) 配置依赖库

      右键项目名,单击弹出菜单中的"Properties"

      在左侧点击"Configuration Properties"=>"Linker"=>"Input",点击右边"Addtional Dependencis"下的Edit

      添加以下依赖库名称:
           d3d11.lib
           d3dcompiler.lib
           dxguid.lib
           winmm.lib
           comctl32.lib

(3) 添加源文件

      创建头文件"Release.h"和源文件"Tutorial01.cpp",源码如下:

Release.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Tutorial01.rc
//

#define IDS_APP_TITLE           103

#define IDR_MAINFRAME           128
#define IDD_TUTORIAL1_DIALOG    102
#define IDD_ABOUTBOX            103
#define IDM_ABOUT               104
#define IDM_EXIT                105
#define IDI_TUTORIAL1           107
#define IDI_SMALL               108
#define IDC_TUTORIAL1           109
#define IDC_MYICON              2
#define IDC_STATIC              -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC                 130
#define _APS_NEXT_RESOURCE_VALUE    129
#define _APS_NEXT_COMMAND_VALUE     32771
#define _APS_NEXT_CONTROL_VALUE     1000
#define _APS_NEXT_SYMED_VALUE       110
#endif
#endif

Tutorial01.cpp

//--------------------------------------------------------------------------------------
// File: Tutorial01.cpp
//
// This application demonstrates creating a Direct3D 11 device
//
// http://msdn.microsoft.com/en-us/library/windows/apps/ff729718.aspx
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include <windows.h>
#include <d3d11_1.h>
#include <directxcolors.h>
#include "resource.h"

using namespace DirectX;

//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE               g_hInst = nullptr;
HWND                    g_hWnd = nullptr;
D3D_DRIVER_TYPE         g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL       g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device*           g_pd3dDevice = nullptr;
ID3D11Device1*          g_pd3dDevice1 = nullptr;
ID3D11DeviceContext*    g_pImmediateContext = nullptr;
ID3D11DeviceContext1*   g_pImmediateContext1 = nullptr;
IDXGISwapChain*         g_pSwapChain = nullptr;
IDXGISwapChain1*        g_pSwapChain1 = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;

//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK    WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();

//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow )
{
    UNREFERENCED_PARAMETER( hPrevInstance );
    UNREFERENCED_PARAMETER( lpCmdLine );

    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;

    if( FAILED( InitDevice() ) )
    {
        CleanupDevice();
        return 0;
    }

    // Main message loop
    MSG msg = {0};
    while( WM_QUIT != msg.message )
    {
        if( PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            Render();
        }
    }

    CleanupDevice();

    return ( int )msg.wParam;
}

//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
    // Register class
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hCursor = LoadCursor( nullptr, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = nullptr;
    wcex.lpszClassName = L"TutorialWindowClass";
    wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;

    // Create window
    g_hInst = hInstance;
    RECT rc = { 0, 0, 800, 600 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 1: Direct3D 11 Basics",
                           WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                           CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance,
                           nullptr );
    if( !g_hWnd )
        return E_FAIL;

    ShowWindow( g_hWnd, nCmdShow );

    return S_OK;
}

//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch( message )
    {
    case WM_PAINT:
        hdc = BeginPaint( hWnd, &ps );
        EndPaint( hWnd, &ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

        // Note that this tutorial does not handle resizing (WM_SIZE) requests,
        // so we created the window without the resize border.

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
    }

    return 0;
}

//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
    HRESULT hr = S_OK;

    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;

    UINT createDeviceFlags = 0;
#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE,
        D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE,
    };
    UINT numDriverTypes = ARRAYSIZE( driverTypes );

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };
    UINT numFeatureLevels = ARRAYSIZE( featureLevels );

    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
    {
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
                                D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );

        if ( hr == E_INVALIDARG )
        {
            // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
            hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
                                    D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
        }

        if( SUCCEEDED( hr ) )
            break;
    }
    if( FAILED( hr ) )
        return hr;

    // Obtain DXGI factory from device (since we used nullptr for pAdapter above)
    IDXGIFactory1* dxgiFactory = nullptr;
    {
        IDXGIDevice* dxgiDevice = nullptr;
        hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) );
        if (SUCCEEDED(hr))
        {
            IDXGIAdapter* adapter = nullptr;
            hr = dxgiDevice->GetAdapter(&adapter);
            if (SUCCEEDED(hr))
            {
                hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) );
                adapter->Release();
            }
            dxgiDevice->Release();
        }
    }
    if (FAILED(hr))
        return hr;

    // Create swap chain
    IDXGIFactory2* dxgiFactory2 = nullptr;
    hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) );
    if ( dxgiFactory2 )
    {
        // DirectX 11.1 or later
        hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) );
        if (SUCCEEDED(hr))
        {
            (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) );
        }

        DXGI_SWAP_CHAIN_DESC1 sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.Width = width;
        sd.Height = height;
        sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.BufferCount = 1;

        hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 );
        if (SUCCEEDED(hr))
        {
            hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) );
        }

        dxgiFactory2->Release();
    }
    else
    {
        // DirectX 11.0 systems
        DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;

        hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain );
    }

    // Note this tutorial doesn‘t handle full-screen swapchains so we block the ALT+ENTER shortcut
    dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER );

    dxgiFactory->Release();

    if (FAILED(hr))
        return hr;

    // Create a render target view
    ID3D11Texture2D* pBackBuffer = nullptr;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) );
    if( FAILED( hr ) )
        return hr;

    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView );
    pBackBuffer->Release();
    if( FAILED( hr ) )
        return hr;

    g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr );

    // Setup the viewport
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT)width;
    vp.Height = (FLOAT)height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    g_pImmediateContext->RSSetViewports( 1, &vp );

    return S_OK;
}

//--------------------------------------------------------------------------------------
// Render the frame
//--------------------------------------------------------------------------------------
void Render()
{
    // Just clear the backbuffer
    g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, Colors::MidnightBlue );
    g_pSwapChain->Present( 0, 0 );
}

//--------------------------------------------------------------------------------------
// Clean up the objects we‘ve created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
    if( g_pImmediateContext ) g_pImmediateContext->ClearState();

    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain1 ) g_pSwapChain1->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pImmediateContext1 ) g_pImmediateContext1->Release();
    if( g_pImmediateContext ) g_pImmediateContext->Release();
    if( g_pd3dDevice1 ) g_pd3dDevice1->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

(4) 完成

      按F5键即可编译并运行项目,最终效果如下:

六、 总结

  • 目前在VS2015 IDE中编写DirectX11程序已经不用安装SDK包,只要简单的将所以来LIB库配置到项目中即可。
  • (更新于2016.05.05)龙书11中的示例项目尝试过目前是不能运行的,因为在win8系统发布以后微软不仅将directx的SDK包集合到win SDK中,将directx11直接集成到操作系统中,同时,也对DIRECT编程所依赖的一些库文件做了大量修改,而龙书11中的示例项目大部分是基于之前独立的DX11SDK_Jun10.exe和win7这个环境的,因此想要运行这些示例项目需要根据情况将所依赖接口更新到目前版本。
时间: 2024-10-10 13:17:37

一、VS2015update2环境下DirectX11编程说明(2016.5.5更新)的相关文章

OpenStack 环境下 SHELL 编程练习(持续更新中)

须知: 1.本次 Shell 主要是针对于 OpneStack 环境下的编程练习 2.欢迎大家留言讨论 3.持续更新 练习1:将文件内容打印输出到屏幕上,并在每一行前面加上字符串"nova delete ",示例如下: 文件内容为: aaaa bbbb cccc 屏幕上输出为: nova delete aaaa nova delete bbbb nova delete cccc #!/bin/bash #文件功能:文件内容打印输出到屏幕上,并在每一行前面加上字符串"nova

在vSphere环境下简单测试Windows 2016 S2D (2)

在了解了S2D基本概念及架构以后,我们接下来做一些具体的配置及测试.本实验环境搭在vCenter6.0u2上,配置四台虚机作为S2D的节点,每台虚机的具体配置如下: OS:Windows 2016 datacenter 4 vCPU& 8GB RAM 4 vNics 1个40GB磁盘装OS:另外再添加2 x 50GB(模拟PCIe SSD):2 x 100GB(模拟SSD):4 x 300GB(HDD) 本测试的设想是将模拟的NVMe PCIe SSD磁盘作为读写缓存使用,而把SSD和HDD作为

在vSphere环境下简单测试Windows 2016 S2D (3)

W2016包含了很多Powershell工具,帮助用户诊断.查看和收集存储相关的日志.在接下来的实验里,我们一起看看和排错相关的命令. 用Get-StorageSubSystem命令查看测试环境里的S2D子系统的名称,比如下面这个是笔者测试用的S2D,因为名字较长,所以后续步骤命令中均以通配符"*"取代除"cluster"之外的部分: 2. Enable-StorageDiagnosticLog 命令能够配置收集不同级别的日志信息(包含Critical.Error.

Linux环境下网络编程杂谈&lt;&lt;转&gt;&gt;

今天我们说说“Pre-网络编程”.内容比较杂,但都是在做网络应用程序开发过程中经常要遇到的问题. 一.大端.小端和网络字节序 小端字节序:little-endian,将低字节存放在内存的起始地址: 大端字节序:big-endian,将高字节存放在内存的其实地址. 例如,数字index=0x11223344,在大小端字节序方式下其存储形式为: 上图一目了然的可以看出大小端字节序的区别. 还有另外一个概念就是网络字节序.网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型.操作

【Linux&amp;C++】Linux环境下C++编程

在阅读的过程中有任何问题,欢迎一起交流 邮箱:[email protected]   QQ:1494713801 在linux下,开发工具被切割成一个个独立的小工具.各自处理不同的问题.例如: 编辑器(emacs, vim)用来进行编辑程序的 调试器(gdb) 用来调试程序 编译器(GCC) 用来编译和链接程序的 性能分析工具(gcov, gprof) 用来优化程序的 文档生成器(doxygen) 用来生成文档的 同时,还有一些系统工具和系统知识,我们是很有必要了解的: makefile  程序

在vSphere环境下简单测试Windows 2016 S2D (1)

伴随这两年SDDC(软件定义的数据中心)越来越热,作为其中重要的建设区块的软件定义存储(SDS)也越来越多地被各行业,各类规模的数据中心所使用.作为SDS厂商之一的微软,面对这块蛋糕当然不甘人后,从Windows Server 2012开始,微软隆重推出了他的SDS解决方案--Storage Space.该版本还是需要建立在共享磁盘柜(JBOD)的基础上,和其他主流SDS厂商一样,其目的是通过将JBOD里各类磁盘加入到一个或多个存储池,再从存储池里划分存储空间(Storage Space)给单台

WinXP SP环境下Photoshop CS6中画布图层不更新的问题记录

现在是正常的三个图层 图层1里面有红色画笔画的线条,但隐藏图层1,画布上面的线条还在 现在是我把三个图层都点显示了,画布上却只显示了一个背景层. 解决问题的关键办法其实非常简单,只是这个操作在其它版本里面不一定是这个位置,大家仔细找找就好了

CentOS环境下vim配置(有图)

在刚开始在Linux环境下进行编程时,没有对vim进行配置,在编程时只能进行最初的编辑,而与Windows环境下编程相比有很多不方便. 那么,在对vim进行配置之后,这种不方便在很大程度上可以减轻. 在查询相关文档之后,选择了一个相对来说最好的方案: 配置情况如图: 接下来开始最重要的:配置vim 1.在根目录下下载zip文件(打开目标目录,在目录下下载) wget  http://files.cnblogs.com/ma6174/vimrc.zip 解压文件到 /root 目录 unzip v

多线程环境下队列操作之锁的教训

之前一直在研究多线程环境下的编程方法,却很少实战体验,以至于我一提到多线程编程,我总是信心不足,又总是说不出到底哪里不明白.今天工程现场反馈了一个“老问题”,我一直担心的是DAServer的运行机制有什么我不明白的地方,DAS Toolkit中总有一部分是我没有仔细研究的,在我心中有阴影,所以工程出了问题我第一反应就是“会不会问题出在阴影里?”.结果,至今为止,我总结起来问题90%都是在自己编码部分. 我的DAServer中有一个需求,就是上送某个定点数据的速度不能太快,否则后台接收不过来.于是