Directx11学习笔记【三】 第一个D3D11程序

在先前的解决方案中新建一个新的Win32项目FirstD3D11Demo。在写代码之前,我们必须先添加dx11所需要的库。为了链接dx库,右键项目选择属性->vc++目录,在包含目录中添加你所安装的SDK根目录\Include,在库目录中添加 根目录\lib\x86(或x64),在链接器->输入的附加依赖项中添加d3d11.lib、d3dx11.lib、dxerr.lib。

第一次使用d3d,首先应该从初始化开始。

初始化d3d11的步骤主要有以下几个:

1、定义我们要检查的设备类型和特征级别

2、创建d3d设备,渲染环境和交换链

3、创建渲染对象

4、设置视口观察区(ViewPort)

下面将对一些概念和用到的d3d对象和函数作具体说明。

数据格式

D3D应用程序中,无论是纹理图片,还是创建的缓冲区,都有着特定的数据格式。D3D11支持有限的数据格式,以枚举变量形式存在,如下几种:

DXGI_FORMAT_R32G32B32_FLOAT: 3个32位单精度符点数组成,比如用于代表三维空间坐标,以及24位颜色;

DXGI_FORMAT_R16G16B16A16_UNORM: 4个16位数组成,每个成员位于[0,1.0f]之间,UNORM意指:unsigned normalized,即无符号,且归一化的;

DXGI_FORMAT_R32G32_UINT:2个32位数组成,每个成员为无符号整型(unsigned int);

DXGI_FORMAT_R8G8B8A8_UNORM:4个8位数组成,每个成员为[0,1.f]之间;

DXGI_FORMAT_R8G8B8A8_SNORM:4个8位数组成,每个成员为[-1.0f, 1.0f]之间,SNORM意指:signed normalized;

DXGI_FORMAT_R8G8B8A8_SINT:4个8位数组成,每个成员为有符号整型;

特征级别(Feature Level)

特征级别定义了一系列支持不同d3d功能的相应等级,如果一个用户的硬件不支持某一特征等级,程序可以选择较低的等级来运行。

下面是d3d定义的几个不同级别代表不同的d3d版本

typedef enum D3D_FEATURE_LEVEL {
  D3D_FEATURE_LEVEL_9_1   = 0x9100,
  D3D_FEATURE_LEVEL_9_2   = 0x9200,
  D3D_FEATURE_LEVEL_9_3   = 0x9300,
  D3D_FEATURE_LEVEL_10_0  = 0xa000,
  D3D_FEATURE_LEVEL_10_1  = 0xa100,
  D3D_FEATURE_LEVEL_11_0  = 0xb000,
  D3D_FEATURE_LEVEL_11_1  = 0xb100,
  D3D_FEATURE_LEVEL_12_0  = 0xc000,
  D3D_FEATURE_LEVEL_12_1  = 0xc100
} D3D_FEATURE_LEVEL;

在初始化过程中,我们可以提供一组不同的特征等级,程序会从第一个开始逐个检测,碰到第一个合适的来创建设备。因此我们在数组中从高到低放置特征等级提供给初始化程序。

交换链(SwapChain)

为了实现平滑的动画,至少需要两个缓冲区,一个前缓冲区用于显示,一个后缓冲区用于下一帧的绘制,每次绘制完一帧后通过交换前、后缓冲区对应的指针来显示新一帧,并在之前的前缓冲区(当前的后缓冲区)上开始继续绘制下一帧。交换链可以有3个或者更多缓冲区,但一般情况下两个够用了。通常在游戏中,我们有两种颜色缓存,一个主缓存,一个辅助缓存,这就是所谓的前向和后向缓存。主缓存是显示在屏幕上的,辅助缓存则是用于下一帧的绘制。在d3d11中交换链对应的接口为IDXGISwapChain。

深度/模板缓冲区:Depth/Stencil Buffer

深度缓冲区是与交换链缓冲区大小完全一样的一块显存区域,即每个像素在深度缓冲区中对应相应的位置。在渲染管线的最终的混合阶段(Output Merger Stage),每个片(Fragment)都有一个深度值z,与深度缓冲区对应位置上的深度相比较,如果该片段z更小,则绘制该片段,并覆盖当前的尝试值,否则抛弃该片段。该缓冲区主要用于实现投影在屏幕上同一位置、远近不同的物体之间相同的遮挡效果。此外,灵活配置尝试缓冲区,可以实现很多种高级特效。

 多重采样抗锯齿:Multisampling Atialiasing

       针对光栅化显示器抗锯齿的方法有多种,在d3d中采用的多重采样方法。即在每个像素点内部,设置多个采样点,绘制多边形边缘时,针对每个采样点判断是否被多边形覆盖,最终的颜色值从采样点中取均值,以对多边形的边缘进行“模糊化",从而减轻锯齿效果。如下图所示,这是一个4重采样的例子,该像素最终的颜色值是多边形本身颜色值的3/4:

支持d3d11的硬件全部支持4重采样,因此我们在后面的程序中将普遍使用4个采样点。在d3d11中通过结构DXGI_SAMPLE_DESC来设置多重采样,其定义如下:

typedef struct DXGI_SAMPLE_DESC {
  UINT Count;
  UINT Quality;
} DXGI_SAMPLE_DESC;

D3D11_CREATE_DEVICE_FLAG 枚举类型

typedef enum D3D11_CREATE_DEVICE_FLAG {
  D3D11_CREATE_DEVICE_SINGLETHREADED                                 = 0x1,
  D3D11_CREATE_DEVICE_DEBUG                                          = 0x2,
  D3D11_CREATE_DEVICE_SWITCH_TO_REF                                  = 0x4,
  D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS       = 0x8,
  D3D11_CREATE_DEVICE_BGRA_SUPPORT                                   = 0x20,
  D3D11_CREATE_DEVICE_DEBUGGABLE                                     = 0x40,
  D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY  = 0x80,
  D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT                            = 0x100,
  D3D11_CREATE_DEVICE_VIDEO_SUPPORT                                  = 0x800
} D3D11_CREATE_DEVICE_FLAG;

D3D11_CREATE_DEVICE_SINGLETHREADED
如果使用该常量,你的应用程序将只可以在一个线程中的调用 Dierct3D 11接口。在默认情况下ID3D11Device
对象是一个安全线程。使用这个标志,你可以增强性能。然而,如果你使用这个标志并且你的应用程序使用
多线程调用Dierct3D 11接口,可能导致不可预期的结果。

D3D11_CREATE_DEVICE_DEBUG
创建一个设备支持调用层。

D3D11_CREATE_DEVICE_SWITCH_TO_REF
注意 这个标志不支持Direct3D 11.

D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
阻止被多线程创建。当使用WARP标志时,WARP和所有光栅不能够被线程调用。这个标志不建议使用。

D3D11_CREATE_DEVICE_BGRA_SUPPORT
Dierct2D需要和Direct3D资源交互。

交换链具体定义

typedef struct DXGI_SWAP_CHAIN_DESC {
  DXGI_MODE_DESC   BufferDesc;
  DXGI_SAMPLE_DESC SampleDesc;
  DXGI_USAGE       BufferUsage;
  UINT             BufferCount;
  HWND             OutputWindow;
  BOOL             Windowed;
  DXGI_SWAP_EFFECT SwapEffect;
  UINT             Flags;
} DXGI_SWAP_CHAIN_DESC;

BufferDesc指定后缓冲区有关特性;

SampleDesc指定多重采样,前面说过;

BufferUsage,对于交换链,为DXGI_USAGE_RENDER_TARGET_OUTPUT;

BufferCount:我们只创建一个后缓冲区(双缓冲),因此为1;

OutputWindow:指定窗口句柄,Win32程序初始化完创建的主窗口;

Windowed:是否全屏;

DXGI_SWAP_EFFECT:通常为DXGI_SWAP_EFFECT_DISCARD;

Flags:可选

其中DXGI_MODE_DESC定义如下
typedef struct DXGI_MODE_DESC {
  UINT                     Width;
  UINT                     Height;
  DXGI_RATIONAL            RefreshRate;
  DXGI_FORMAT              Format;
  DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;
  DXGI_MODE_SCALING        Scaling;
} DXGI_MODE_DESC, *LPDXGI_MODE_DESC;

Width、Height为缓冲区大小,一般设为主窗口大小;

Format为缓冲区类型,一般作为渲染对象缓冲区类型为DXGI_FORMAT_R8G8B8A8_UNORM;

其他参数一般为固定的。

创建交换链的具体过程见后面附的代码

D3D11CreateDeviceAndSwapChain函数原型:

HRESULT D3D11CreateDeviceAndSwapChain(
  _In_opt_        IDXGIAdapter         *pAdapter,
                  D3D_DRIVER_TYPE      DriverType,
                  HMODULE              Software,
                  UINT                 Flags,
  _In_opt_  const D3D_FEATURE_LEVEL    *pFeatureLevels,
                  UINT                 FeatureLevels,
                  UINT                 SDKVersion,
  _In_opt_  const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
  _Out_opt_       IDXGISwapChain       **ppSwapChain,
  _Out_opt_       ID3D11Device         **ppDevice,
  _Out_opt_       D3D_FEATURE_LEVEL    *pFeatureLevel,
  _Out_opt_       ID3D11DeviceContext  **ppImmediateContext
);

pAdapter来选择相应的图形适配器,设为NULL以选择默认的适配器;

DriverType设置驱动类型,一般毫无疑问选择硬件加速,即D3D_DRIVER_TYPE_HARDWARE,此时下一个参数就是NULL;

Flags为可选参数,一般为NULL,可以设为D3D11_CREATE_DEVICE_DEBUG、D3D11_CREATE_DEVICE_SINGLETHREADED,或两者一起,前者让要用于调试时收集信息,后者在确定程序只在单线程下运行时设置为它,可以提高性能;

pFeatureLevels为我们提供给程序的特征等级的一个数组,下一个参数为数组中元素个数;

SDKVersion恒定为D3D11_SDK_VERSION;

ppDevice为设备指针的地址,注意设备是指针类型,这里传递的是指针的地址(二维指针,d3d程序中所有的接口都声明为指针类型!);

pFeatureLevel为最后程序选中的特征等级,我们定义相应的变量,传递它的地址进来;

ppImmediateContext为设备上下文指针的地址,要求同设备指针。

CreateRenderTargetView函数原型

HRESULT CreateRenderTargetView(
  [in]                  ID3D11Resource                *pResource,
  [in, optional]  const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,
  [out, optional]       ID3D11RenderTargetView        **ppRTView
);

pResource为视图对应资源

pDesc为视图描述

ppRTView要创建的视图,是一个指针的地址

D3D11_VIEWPORT定义

typedef struct D3D11_VIEWPORT {
  FLOAT TopLeftX;        //视口左上角x坐标,一般视口占满屏幕的,所以为0
  FLOAT TopLeftY;        //y坐标
  FLOAT Width;            //视口宽度,一般与后缓冲区一致,以保持图像不变形
  FLOAT Height;            //高度,同上
  FLOAT MinDepth;        //最小深度值:0.0f
  FLOAT MaxDepth;        //最大深度值:1.0f
} D3D11_VIEWPORT;

下面给出整个工程的代码:

  1 #include <windows.h>
  2 #include <d3d11.h>
  3 #include <DxErr.h>
  4 #include <D3DX11.h>
  5
  6 HINSTANCE g_hInstance = NULL;
  7 HWND g_hWnd = NULL;
  8 LPCWSTR g_name = L"FirstD3D11Demo";
  9 D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;                //驱动类型
 10 D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;            //特征等级
 11 ID3D11Device *g_pd3dDevice = NULL;                                    //设备
 12 ID3D11DeviceContext *g_pImmediateContext = NULL;                    //设备上下文
 13 IDXGISwapChain *g_pSwapChain = NULL;                                //交换链
 14 ID3D11RenderTargetView *g_pRenderTargetView = NULL;                    //要创建的视图
 15
 16
 17 HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
 18 HRESULT InitDevice();
 19 void CleanupDevice();
 20 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 21 void Render();
 22
 23 int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
 24 {
 25     if (FAILED(InitWindow(hInstance, nShowCmd)))
 26         return 0;
 27     if (FAILED(InitDevice()))
 28     {
 29         CleanupDevice();
 30         return 0;
 31     }
 32     MSG msg;
 33     ZeroMemory(&msg, sizeof(MSG));
 34     while (msg.message != WM_QUIT)
 35     {
 36         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
 37         {
 38             TranslateMessage(&msg);
 39             DispatchMessage(&msg);
 40         }
 41         else//渲染
 42         {
 43             Render();
 44         }
 45     }
 46     CleanupDevice();
 47     return static_cast<int>(msg.wParam);
 48 }
 49
 50 HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
 51 {
 52     WNDCLASSEX wcex;
 53     wcex.cbClsExtra = 0;
 54     wcex.cbSize = sizeof(WNDCLASSEX);
 55     wcex.cbWndExtra = 0;
 56     wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
 57     wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
 58     wcex.hIcon = LoadIcon(NULL, IDI_WINLOGO);
 59     wcex.hIconSm = wcex.hIcon;
 60     wcex.hInstance = hInstance;
 61     wcex.lpfnWndProc = WndProc;
 62     wcex.lpszClassName = g_name;
 63     wcex.lpszMenuName = NULL;
 64     wcex.style = CS_HREDRAW | CS_VREDRAW;
 65     if (!RegisterClassEx(&wcex))
 66         return E_FAIL;
 67
 68     g_hInstance = hInstance;
 69     RECT rc{0,0,640,480};
 70     AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
 71     g_hWnd = CreateWindowEx(WS_EX_APPWINDOW, g_name, g_name, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
 72         rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, g_hInstance, NULL);
 73     if (!g_hWnd)
 74         return E_FAIL;
 75
 76     ShowWindow(g_hWnd, nCmdShow);
 77
 78     return S_OK;
 79 }
 80
 81 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wPararm, LPARAM lParam)
 82 {
 83     switch (message)
 84     {
 85     case WM_DESTROY:
 86         PostQuitMessage(0);
 87         break;
 88     default:
 89         return DefWindowProc(hWnd, message, wPararm, lParam);
 90     }
 91     return 0;
 92 }
 93
 94 //创建设备及交换链
 95 HRESULT InitDevice()
 96 {
 97     HRESULT hResult = S_OK;//返回结果
 98
 99     RECT rc;
100     GetClientRect(g_hWnd, &rc);//获取窗口客户区大小
101     UINT width = rc.right - rc.left;
102     UINT height = rc.bottom - rc.top;
103
104     UINT createDeviceFlags = 0;
105 #ifdef _DEBUG
106     createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
107 #endif
108
109     //驱动类型数组
110     D3D_DRIVER_TYPE driverTypes[] =
111     {
112         D3D_DRIVER_TYPE_HARDWARE,
113         D3D_DRIVER_TYPE_WARP,
114         D3D_DRIVER_TYPE_REFERENCE
115     };
116     UINT numDriverTypes = ARRAYSIZE(driverTypes);
117
118     //特征级别数组
119     D3D_FEATURE_LEVEL featureLevels[] =
120     {
121         D3D_FEATURE_LEVEL_11_0,
122         D3D_FEATURE_LEVEL_10_1,
123         D3D_FEATURE_LEVEL_10_0
124     };
125     UINT numFeatureLevels = ARRAYSIZE(featureLevels);
126
127     //交换链
128     DXGI_SWAP_CHAIN_DESC sd;
129     ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC));//填充
130     sd.BufferCount = 1;                              //我们只创建一个后缓冲(双缓冲)因此为1
131     sd.BufferDesc.Width = width;
132     sd.BufferDesc.Height = height;
133     sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
134     sd.BufferDesc.RefreshRate.Numerator = 60;
135     sd.BufferDesc.RefreshRate.Denominator = 1;
136     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
137     sd.OutputWindow = g_hWnd;
138     sd.SampleDesc.Count = 1;                      //1重采样
139     sd.SampleDesc.Quality = 0;                      //采样等级
140     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;      //常用参数
141     sd.Windowed = TRUE;                              //全屏
142
143     for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex)
144     {
145         g_driverType = driverTypes[driverTypeIndex];
146         hResult = D3D11CreateDeviceAndSwapChain(
147             NULL,                                //默认图形适配器
148             g_driverType,                        //驱动类型
149             NULL,                                //实现软件渲染设备的动态库句柄,如果使用的驱动设备类型是软件设备则不能为NULL
150             createDeviceFlags,                    //创建标志,0用于游戏发布,一般D3D11_CREATE_DEVICE_DEBUG允许我们创建可供调试的设备,在开发中比较有用
151             featureLevels,                        //特征等级
152             numFeatureLevels,                    //特征等级数量
153             D3D11_SDK_VERSION,                    //sdk版本号
154             &sd,
155             &g_pSwapChain,
156             &g_pd3dDevice,
157             &g_featureLevel,
158             &g_pImmediateContext
159             );
160         if (SUCCEEDED(hResult))
161             break;
162     }
163     if (FAILED(hResult))
164         return hResult;
165
166     //创建渲染目标视图
167     ID3D11Texture2D *pBackBuffer = NULL;
168     //获取后缓冲区地址
169     hResult = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
170     if (FAILED(hResult))
171         return hResult;
172
173     //创建目标视图
174     hResult = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
175     //释放后缓冲
176     pBackBuffer->Release();
177     if (FAILED(hResult))
178         return hResult;
179
180     //绑定到渲染管线
181     g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);
182
183     //设置viewport
184     D3D11_VIEWPORT vp;
185     vp.Height = (FLOAT)height;
186     vp.Width = (FLOAT)width;
187     vp.MinDepth = 0.0f;
188     vp.MaxDepth = 1.0f;
189     vp.TopLeftX = 0;
190     vp.TopLeftY = 0;
191     g_pImmediateContext->RSSetViewports(1, &vp);
192
193     return S_OK;
194 }
195
196 void Render()
197 {
198     float ClearColor[4] = { 0.5f, 0.1f, 0.2f, 1.0f }; //red,green,blue,alpha
199     g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
200     g_pSwapChain->Present(0, 0);
201 }
202
203 void CleanupDevice()
204 {
205     if (g_pImmediateContext)
206         g_pImmediateContext->ClearState();
207     if (g_pSwapChain)
208         g_pSwapChain->Release();
209     if (g_pRenderTargetView)
210         g_pRenderTargetView->Release();
211     if (g_pImmediateContext)
212         g_pImmediateContext->Release();
213     if (g_pd3dDevice)
214         g_pd3dDevice->Release();
215 }

 

 

时间: 2025-01-08 18:56:13

Directx11学习笔记【三】 第一个D3D11程序的相关文章

学习笔记之03-第一个C程序代码分析

一.代码分析 打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: 1 #include <stdio.h> 2 3 int main(int argc, const char * argv[]) { 4 // insert code here... 5 printf("Hello, World!\n"); 6 return 0; 7 } 1.#include <stdio.h> #include 是

C语言学习笔记之第一个C程序及编译运行(一)

一.第一个C程序 1>C程序由函数构成 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”.所以,你可以说C语言程序是由函数构成的. 2>C程序的入口 C程序的入口是一个名字叫做main的函数,简称main函数.(为了区分函数,每一个函数都有一个名称)也就是说,不管整个程序中有多少个函数,都是先执行main函数.不管main函数写在文件中间,还是文件末尾,也都是先执行main函数. 注意: 如果一个C程序中没有main函数,那么

OD学习笔记10:一个VB程序的加密和解密思路

前边,我们的例子中既有VC++开发的程序,也有Delphi开发的程序,今天我们给大家分析一个VB程序的加密和解密思路. Virtual BASIC是由早期DOS时代的BASIC语言发展而来的可视化编程语言. VB是由事件驱动的编程语言:就是在可视化编程环境下我们可以绘制一些窗体,按钮,编辑框等控件,然后为这些控件所可能引发的事件如按钮被单击或者被双击编写对应的处理代码. 所有的VB程序几乎都是依赖于一个外部的动态链接库.这个动态链接库的名字是:MSVBVM60.dll(可能有多个版本,但名字都差

Servlet&amp;JSP学习笔记:第一个Servlet程序

第一个Servlet程序代码如下,接着根据这个小程序逐步讲解. import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletReq

DirectX11 学习笔记3 - 创建一个立方体 和 坐标轴

这个程序再进一步的将上一个程序 面向对象化. 把模型类独立出来.更加像一个框架. 在此中遇到了一个很逗比的问题,弄了一晚上,看了好几遍其他列子才找到.就是有些函数一定要放在Render里面实时更新,而不是只放到初始化InitModel里面 因为当要渲染多个物体的时候,缓冲区的内容是要随设备变化的. 话不多说直接上代码 主程序main #include "D3DBase.h" #include "Axis.h" #include "Cube.h"

DirectX11 学习笔记3 - 创建一个立方体 和 轴

该方案将在进一步的程序 面向对象. 独立的模型类.更像是一个框架. 其中以超过遇到了一个非常有趣的问题,.获得一晚.我读了好几遍,以找到其他的列子.必须放在某些功能Render里面实时更新,而不是仅仅进入初始化InitModel里边 染多个物体的时候,缓冲区的内容是要随设备变化的. 话不多说直接上代码 主程序main #include "D3DBase.h" #include "Axis.h" #include "Cube.h" class D3

学习笔记_第一个strut程序_之中文乱码,过滤器解决方案及过程总结

1.  第一次碰到加过滤器的过程,就是在学习struct1的时候,中文乱码 几个需要注意的关键字 2.什么叫package 所谓package就是打包的意思,就是说以下程序都是处于这个包内,所以一开始你看见src下拉菜单下面都是一些自己建的就是为了分开结构的作用 3.  建好了,就可以在包的下面建子文件,可以是class类文件,也可以是各种jsp,servlet文件. 4.  任何servlet文件或者显示界面文件都要在web.xml文件中进行配置,才能加载进去,而且是自动加载 5.  写代码的

学习笔记之第一个C程序

1.打开Xcode,新建Xcode项目 2.选择最简单的命令行项目 3.输入项目信息 4.选择一个用来存放C程序代码的文件夹 5.运行项目 运行结果如图(控制台输出)

DuiLib学习笔记2——写一个简单的程序

我们要独立出来自己创建一个项目,在我们自己的项目上加皮肤这才是初衷.我的新建项目名为:duilibTest 在duilib根目录下面有个 Duilib入门文档.doc 我们就按这个教程开始入门 首先新建一个win32项目 去DuiLib根目录,把目录下DuiLib文件夹拷贝到新建项目的根目录.再把这个项目添加进我们解决方案中. 从教程里面把以下代码粘贴到我们项目的stdafx.h中 // Duilib使用设置部分 #pragma once #define WIN32_LEAN_AND_MEAN

Directx11学习笔记【二十二】 用高度图实现地形

本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Directx11学习笔记[十三] 实现一个简单地形),只不过原来使用一个固定的函数获得地形高度,这样跟真实的地形差距比较大.接下来让我们学习使用高度图来进行三维地形模拟. 1.高度图 高度图其实就是一组连续的数组,这个数组中的元素与地形网格中的顶点一一对应,且每一个元素都指定了地形网格的某个顶点的高度值.高度