DirectX Box

通过该Demo,可以清楚了解DirectX流程。将完整程序贴出,自己加以注释,方面查看理解。

  1 /*
  2 2015.4
  3 d3dUtil.h
  4
  5 d3d 常用工具代码
  6 */
  7
  8 #ifndef D3DUTIL_H
  9 #define D3DUTIL_H
 10
 11 // Let VC++ know we are compiling for WinXP and up.  This let‘s us use
 12 // API functions specific to WinXP (e.g., WM_INPUT API).
 13 #ifndef _WIN32_WINNT
 14 #define _WIN32_WINNT   0x0600 // Vista
 15 #endif
 16
 17 // Enable extra D3D debugging in debug builds if using the debug DirectX runtime.
 18 // This makes D3D objects work well in the debugger watch window, but slows down
 19 // performance slightly.
 20 #if defined(DEBUG) || defined(_DEBUG)
 21     #ifndef D3D_DEBUG_INFO
 22     #define D3D_DEBUG_INFO
 23     #endif
 24 #endif
 25
 26 #if defined(DEBUG) || defined(_DEBUG)
 27 #define _CRTDBG_MAP_ALLOC
 28 #include <crtdbg.h>
 29 #endif
 30
 31
 32 #include <d3dx10.h>
 33 #include <dxerr.h>
 34 #include <cassert>
 35
 36 // Simple d3d error checker.
 37 #if defined(DEBUG) | defined(_DEBUG)
 38 #ifndef HR
 39 #define HR(x)                                                     40     {                                                             41         HRESULT hr = (x);                                         42         if (FAILED(hr))                                             43         {                                                         44             DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true);     45         }                                                         46     }                                                             47 /*当DXTrace函数的最后一个参数设为false时,该函数不会显示消息框,
 48 而是把调试信息输出到Visual C++的输出窗口*/
 49 #endif
 50
 51 #else
 52 #ifndef HR
 53 #define HR(x) (x)
 54 #endif
 55 #endif
 56
 57 // releasing COM objects
 58 #define ReleaseCOM(x) { if(x){ x->Release();x = 0; } }
 59
 60 // 内联函数
 61 // Converts ARGB 32-bit color format to ABGR 32-bit color format.
 62 D3DX10INLINE UINT ARGB2ABGR(UINT argb)
 63 {
 64     BYTE A = (argb >> 24) & 0xff;
 65     BYTE R = (argb >> 16) & 0xff;
 66     BYTE G = (argb >> 8) & 0xff;
 67     BYTE B = (argb >> 0) & 0xff;
 68
 69     return (A << 24) | (B << 16) | (G << 8) | (R << 0);
 70 }
 71
 72 // Returns random float in [0, 1).
 73 D3DX10INLINE float RandF()
 74 {
 75     return (float)(rand()) / (float)RAND_MAX;
 76 }
 77 // Returns random float in [a, b).
 78 D3DX10INLINE float RandF(float a, float b)
 79 {
 80     return a + RandF()*(b - a);
 81 }
 82
 83 // 获得单位球体向量
 84 D3DX10INLINE D3DXVECTOR3 RandUnitVec3()
 85 {
 86     D3DXVECTOR3 v(RandF(), RandF(), RandF());
 87     D3DXVec3Normalize(&v, &v);
 88     return v;
 89 }
 90
 91 template<typename T>
 92 D3DX10INLINE T Min(const T& a, const T& b)
 93 {
 94     return a < b ? a : b;
 95 }
 96
 97 template<typename T>
 98 D3DX10INLINE T Max(const T& a, const T& b)
 99 {
100     return a > b ? a : b;
101 }
102
103 //线性插值,在不生成像素的情况下增加图像像素大小的一种方法
104 template<typename T>
105 D3DX10INLINE T Lerp(const T& a, const T& b, float t)
106 {
107     return a + (b - a)*t;
108 }
109
110 template<typename T>
111 D3DX10INLINE T Clamp(const T& x, const T& low, const T& high)
112 {
113     return x < low ? low : (x > high ? high : x);
114 }
115
116 const float PI = 3.14159265358979323f;
117 const float MATH_EPS = 0.0001f;
118
119 const D3DXCOLOR WHITE(1.0f, 1.0f, 1.0f, 1.0f);
120 const D3DXCOLOR BLACK(0.0f, 0.0f, 0.0f, 1.0f);
121 const D3DXCOLOR RED(1.0f, 0.0f, 0.0f, 1.0f);
122 const D3DXCOLOR GREEN(0.0f, 1.0f, 0.0f, 1.0f);
123 const D3DXCOLOR BLUE(0.0f, 0.0f, 1.0f, 1.0f);
124 const D3DXCOLOR YELLOW(1.0f, 1.0f, 0.0f, 1.0f);
125 const D3DXCOLOR CYAN(0.0f, 1.0f, 1.0f, 1.0f);
126 const D3DXCOLOR MAGENTA(1.0f, 0.0f, 1.0f, 1.0f);
127
128 const D3DXCOLOR BEACH_SAND(1.0f, 0.96f, 0.62f, 1.0f);
129 const D3DXCOLOR LIGHT_YELLOW_GREEN(0.48f, 0.77f, 0.46f, 1.0f);
130 const D3DXCOLOR DARK_YELLOW_GREEN(0.1f, 0.48f, 0.19f, 1.0f);
131 const D3DXCOLOR DARKBROWN(0.45f, 0.39f, 0.34f, 1.0f);
132
133 #endif
 1 /*
 2 2015.4
 3 GameTimer.h
 4
 5 */
 6
 7 #ifndef GAMETIMER_H
 8 #define GAMETIMER_H
 9
10 class GameTimer
11 {
12 public:
13     GameTimer();
14
15     float getGameTime()const;  // in seconds
16
17     // 获得增量
18     float getDeltaTime()const; // in seconds
19
20     void reset(); // Call before message loop.
21     void start(); // Call when unpaused.
22     void stop();  // Call when paused.
23     void tick();  // Call every frame.
24
25 private:
26     double mSecondsPerCount;
27     double mDeltaTime;
28
29     __int64 mBaseTime;
30     __int64 mPausedTime;
31     __int64 mStopTime;
32     __int64 mPrevTime;
33     __int64 mCurrTime;
34
35     bool mStopped;
36 };
37
38 #endif 
  1 /*
  2 2015.4
  3 GameTimer.cpp
  4
  5 */
  6 #include "GameTimer.h"
  7 #include <windows.h>
  8
  9 GameTimer::GameTimer()
 10 : mSecondsPerCount(0.0), mDeltaTime(-1.0), mBaseTime(0),
 11 mPausedTime(0), mPrevTime(0), mCurrTime(0), mStopped(false)
 12 {
 13     __int64 countsPerSec;
 14
 15     // 获取性能计时器的频率(每秒的计数次数)
 16     QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
 17     mSecondsPerCount = 1.0 / (double)countsPerSec;
 18 }
 19
 20 // Returns the total time elapsed since reset() was called, NOT counting any
 21 // time when the clock is stopped.
 22 float GameTimer::getGameTime()const
 23 {
 24     // If we are stopped, do not count the time that has passed since we stopped.
 25     //
 26     // ----*---------------*------------------------------*------> time
 27     //  mBaseTime       mStopTime                      mCurrTime
 28
 29     if (mStopped)
 30     {
 31         return (float)((mStopTime - mBaseTime)*mSecondsPerCount);
 32     }
 33
 34     // The distance mCurrTime - mBaseTime includes paused time,
 35     // which we do not want to count.  To correct this, we can subtract
 36     // the paused time from mCurrTime:
 37     //
 38     //  (mCurrTime - mPausedTime) - mBaseTime
 39     //
 40     //                     |<-------d------->|
 41     // ----*---------------*-----------------*------------*------> time
 42     //  mBaseTime       mStopTime        startTime     mCurrTime
 43
 44     else
 45     {
 46         return (float)(((mCurrTime - mPausedTime) - mBaseTime)*mSecondsPerCount);
 47     }
 48 }
 49
 50 float GameTimer::getDeltaTime()const
 51 {
 52     return (float)mDeltaTime;
 53 }
 54
 55 void GameTimer::reset()
 56 {
 57     __int64 currTime;
 58     QueryPerformanceCounter((LARGE_INTEGER*)&currTime);
 59
 60     mBaseTime = currTime;
 61     mPrevTime = currTime;
 62     mStopTime = 0;
 63     mStopped = false;
 64 }
 65
 66 void GameTimer::start()
 67 {
 68     __int64 startTime;
 69     QueryPerformanceCounter((LARGE_INTEGER*)&startTime);
 70
 71
 72     // Accumulate the time elapsed between stop and start pairs.
 73     //
 74     //                     |<-------d------->|
 75     // ----*---------------*-----------------*------------> time
 76     //  mBaseTime       mStopTime        startTime
 77
 78     if (mStopped)
 79     {
 80         mPausedTime += (startTime - mStopTime);
 81
 82         mPrevTime = startTime;
 83         mStopTime = 0;
 84         mStopped = false;
 85     }
 86 }
 87
 88 void GameTimer::stop()
 89 {
 90     if (!mStopped)
 91     {
 92         __int64 currTime;
 93         QueryPerformanceCounter((LARGE_INTEGER*)&currTime);
 94
 95         mStopTime = currTime;
 96         mStopped = true;
 97     }
 98 }
 99
100 void GameTimer::tick()
101 {
102     if (mStopped)
103     {
104         mDeltaTime = 0.0;
105         return;
106     }
107
108     __int64 currTime;
109     QueryPerformanceCounter((LARGE_INTEGER*)&currTime);
110     mCurrTime = currTime;
111
112     // Time difference between this frame and the previous.
113     mDeltaTime = (mCurrTime - mPrevTime)*mSecondsPerCount;
114
115     // Prepare for next frame.
116     mPrevTime = mCurrTime;
117
118     // Force nonnegative.  The DXSDK‘s CDXUTTimer mentions that if the
119     // processor goes into a power save mode or we get shuffled to another
120     // processor, then mDeltaTime can be negative.
121     if (mDeltaTime < 0.0)
122     {
123         mDeltaTime = 0.0;
124     }
125 }
 1 /*
 2 2015.4
 3 d3dApp.h
 4
 5 Simple Direct3D demo application class.
 6
 7 Make sure you link: d3d10.lib d3dx10d.lib dxerr.lib dxguid.lib.
 8 Link d3dx10.lib for release mode builds instead of d3dx10d.lib.
 9 */
10
11 #ifndef D3DAPP_H
12 #define D3DAPP_H
13
14
15 #include "d3dUtil.h"
16 #include "GameTimer.h"
17 #include <string>
18
19 #pragma comment(lib, "d3d10.lib")
20 #pragma comment(lib, "d3dx10d.lib")
21 #pragma comment(lib, "dxguid.lib")
22 #pragma comment(lib, "dxerr.lib")
23
24 class D3DApp
25 {
26 public:
27     D3DApp(HINSTANCE hInstance);
28     virtual ~D3DApp();
29
30     HINSTANCE getAppInst();
31     HWND      getMainWnd();
32
33     int run();
34
35     // Framework methods.  Derived client class overrides these methods to
36     // implement specific application requirements.
37
38     virtual void initApp();
39     virtual void onResize();// reset projection/etc
40     virtual void updateScene(float dt);
41     virtual void drawScene();
42     virtual LRESULT msgProc(UINT msg, WPARAM wParam, LPARAM lParam);
43
44 protected:
45     void initMainWindow();
46     void initDirect3D();
47
48 protected:
49
50     HINSTANCE mhAppInst;
51     HWND      mhMainWnd;
52     bool      mAppPaused;
53     bool      mMinimized;
54     bool      mMaximized;
55     bool      mResizing;
56
57     GameTimer mTimer;
58
59     std::wstring mFrameStats;
60
61     ID3D10Device*    md3dDevice;
62     IDXGISwapChain*  mSwapChain;
63     ID3D10Texture2D* mDepthStencilBuffer;
64     ID3D10RenderTargetView* mRenderTargetView;
65     ID3D10DepthStencilView* mDepthStencilView;
66     ID3DX10Font* mFont;
67
68     // Derived class should set these in derived constructor to customize starting values.
69     std::wstring mMainWndCaption;
70     D3D10_DRIVER_TYPE md3dDriverType;
71     D3DXCOLOR mClearColor;
72     int mClientWidth;
73     int mClientHeight;
74 };
75
76 #endif // D3DAPP_H
  1 /*
  2 2015.4
  3 d3dApp.cpp
  4
  5 */
  6 #include "d3dApp.h"
  7 #include <sstream>
  8
  9 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 10 {
 11     static D3DApp* app = 0;
 12
 13     switch (msg)
 14     {
 15     case WM_CREATE:
 16     {
 17         // Get the ‘this‘ pointer we passed to CreateWindow via the lpParam parameter.
 18         // CREATESTRUCT结构定义了应用程序中窗口过程的初始化参数
 19         CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
 20         app = (D3DApp*)cs->lpCreateParams;
 21         return 0;
 22     }
 23     }
 24
 25     // Don‘t start processing messages until after WM_CREATE.
 26     if (app)
 27         return app->msgProc(msg, wParam, lParam);
 28     else
 29         return DefWindowProc(hwnd, msg, wParam, lParam);
 30 }
 31
 32 D3DApp::D3DApp(HINSTANCE hInstance)
 33 {
 34     mhAppInst = hInstance;
 35     mhMainWnd = 0;
 36     mAppPaused = false;
 37     mMinimized = false;
 38     mMaximized = false;
 39     mResizing = false;
 40
 41     mFrameStats = L"";
 42
 43     md3dDevice = 0;
 44     mSwapChain = 0;
 45     mDepthStencilBuffer = 0;
 46     mRenderTargetView = 0;
 47     mDepthStencilView = 0;
 48     mFont = 0;
 49
 50     mMainWndCaption = L"D3D10 Application";
 51     md3dDriverType = D3D10_DRIVER_TYPE_HARDWARE;
 52     mClearColor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // Set background color
 53     mClientWidth = 800;
 54     mClientHeight = 600;
 55 }
 56
 57 D3DApp::~D3DApp()
 58 {
 59     ReleaseCOM(mRenderTargetView);
 60     ReleaseCOM(mDepthStencilView);
 61     ReleaseCOM(mSwapChain);
 62     ReleaseCOM(mDepthStencilBuffer);
 63     ReleaseCOM(md3dDevice);
 64     ReleaseCOM(mFont);
 65 }
 66
 67 HINSTANCE D3DApp::getAppInst()
 68 {
 69     return mhAppInst;
 70 }
 71
 72 HWND D3DApp::getMainWnd()
 73 {
 74     return mhMainWnd;
 75 }
 76
 77 int D3DApp::run()
 78 {
 79     MSG msg = { 0 };
 80
 81     mTimer.reset();
 82
 83     while (msg.message != WM_QUIT)
 84     {
 85         // If there are Window messages then process them.
 86         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
 87         {
 88             TranslateMessage(&msg);
 89             DispatchMessage(&msg);
 90         }
 91         // Otherwise, do animation/game.
 92         else
 93         {
 94             mTimer.tick();
 95
 96             if (!mAppPaused)
 97                 updateScene(mTimer.getDeltaTime());
 98             else
 99                 Sleep(50);
100
101             drawScene();
102         }
103     }
104     return (int)msg.wParam;
105 }
106
107 void D3DApp::initApp()
108 {
109     initMainWindow();
110     initDirect3D();
111
112     D3DX10_FONT_DESC fontDesc;
113     fontDesc.Height = 20;
114     fontDesc.Width = 0;
115     fontDesc.Weight = 500; // 字体的粗细0~1000
116     fontDesc.MipLevels = 1;
117     fontDesc.Italic = false;//非斜体
118     fontDesc.CharSet = DEFAULT_CHARSET;
119     fontDesc.OutputPrecision = OUT_DEFAULT_PRECIS;
120     fontDesc.Quality = DEFAULT_QUALITY;
121     fontDesc.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
122     wcscpy_s(fontDesc.FaceName, L"Arial");// font style
123
124     D3DX10CreateFontIndirect(md3dDevice, &fontDesc, &mFont);
125     ////文本输出示例:
126     //// We specify DT_NOCLIP, so we do not care about width/height of the rect.
127     //const D3DXCOLOR BLACK(0.0f, 0.0f, 0.0f, 1.0f);
128     //RECT R = { 5, 5, 0, 0 };
129     //mFont->DrawText(0, L"Hello, Direct3D!", -1, &R, DT_NOCLIP, BLACK);
130 }
131
132 void D3DApp::onResize()
133 {
134     // Release the old views, as they hold references to the buffers we
135     // will be destroying.  Also release the old depth/stencil buffer.
136
137     ReleaseCOM(mRenderTargetView);
138     ReleaseCOM(mDepthStencilView);
139     ReleaseCOM(mDepthStencilBuffer);
140
141
142     // Resize the swap chain and recreate the render target view.
143
144     HR(mSwapChain->ResizeBuffers(1, mClientWidth, mClientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
145     ID3D10Texture2D* backBuffer;
146     HR(mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer)));
147     HR(md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView));
148     ReleaseCOM(backBuffer);
149
150
151     // Create the depth/stencil buffer and view.
152
153     D3D10_TEXTURE2D_DESC depthStencilDesc;
154
155     depthStencilDesc.Width = mClientWidth;
156     depthStencilDesc.Height = mClientHeight;
157     depthStencilDesc.MipLevels = 1;
158     depthStencilDesc.ArraySize = 1;
159     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
160     depthStencilDesc.SampleDesc.Count = 1; // multisampling must match
161     depthStencilDesc.SampleDesc.Quality = 0; // swap chain values.
162     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
163     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
164     depthStencilDesc.CPUAccessFlags = 0;
165     depthStencilDesc.MiscFlags = 0;
166
167     HR(md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer));
168     HR(md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView));
169
170
171     // Bind the render target view and depth/stencil view to the pipeline.
172
173     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
174
175
176     // Set the viewport transform.
177
178     D3D10_VIEWPORT vp;
179     vp.TopLeftX = 0;
180     vp.TopLeftY = 0;
181     vp.Width = mClientWidth;
182     vp.Height = mClientHeight;
183     vp.MinDepth = 0.0f;
184     vp.MaxDepth = 1.0f;
185
186     md3dDevice->RSSetViewports(1, &vp);
187 }
188
189 void D3DApp::updateScene(float dt)
190 {
191     // Code computes the average frames per second, and also the
192     // average time it takes to render one frame.
193
194     static int frameCnt = 0;
195     static float t_base = 0.0f;
196
197     frameCnt++;
198
199     // Compute averages over one second period.
200     if ((mTimer.getGameTime() - t_base) >= 1.0f)
201     {
202         float fps = (float)frameCnt; // fps = frameCnt / 1
203         float mspf = 1000.0f / fps;
204
205         std::wostringstream outs;
206         outs.precision(6);
207         outs << L"FPS: " << fps << L"\n"
208             << "Milliseconds(Per Frame): " << mspf;
209         mFrameStats = outs.str();
210
211         // Reset for next average.
212         frameCnt = 0;
213         t_base += 1.0f;
214     }
215 }
216
217 void D3DApp::drawScene()
218 {
219     // Set all the elements in a render target to one value
220     md3dDevice->ClearRenderTargetView(mRenderTargetView, mClearColor);
221
222     // Clears the depth-stencil resource
223     md3dDevice->ClearDepthStencilView(mDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0);
224 }
225
226 LRESULT D3DApp::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
227 {
228     switch (msg)
229     {
230         // WM_ACTIVATE is sent when the window is activated or deactivated.
231         // We pause the game when the window is deactivated and unpause it
232         // when it becomes active.
233     case WM_ACTIVATE:
234         if (LOWORD(wParam) == WA_INACTIVE)
235         {
236             mAppPaused = true;
237             mTimer.stop();
238         }
239         else
240         {
241             mAppPaused = false;
242             mTimer.start();
243         }
244         return 0;
245
246         // WM_SIZE is sent when the user resizes the window.
247     case WM_SIZE:
248         // Save the new client area dimensions.
249         mClientWidth = LOWORD(lParam);
250         mClientHeight = HIWORD(lParam);
251         if (md3dDevice)
252         {
253             if (wParam == SIZE_MINIMIZED)
254             {
255                 mAppPaused = true;
256                 mMinimized = true;
257                 mMaximized = false;
258             }
259             else if (wParam == SIZE_MAXIMIZED)
260             {
261                 mAppPaused = false;
262                 mMinimized = false;
263                 mMaximized = true;
264                 onResize();
265             }
266             else if (wParam == SIZE_RESTORED)
267             {
268
269                 // Restoring from minimized state?
270                 if (mMinimized)
271                 {
272                     mAppPaused = false;
273                     mMinimized = false;
274                     onResize();
275                 }
276
277                 // Restoring from maximized state?
278                 else if (mMaximized)
279                 {
280                     mAppPaused = false;
281                     mMaximized = false;
282                     onResize();
283                 }
284                 else if (mResizing)
285                 {
286                     // If user is dragging the resize bars, we do not resize
287                     // the buffers here because as the user continuously
288                     // drags the resize bars, a stream of WM_SIZE messages are
289                     // sent to the window, and it would be pointless (and slow)
290                     // to resize for each WM_SIZE message received from dragging
291                     // the resize bars.  So instead, we reset after the user is
292                     // done resizing the window and releases the resize bars, which
293                     // sends a WM_EXITSIZEMOVE message.
294                 }
295                 else // API call such as SetWindowPos or mSwapChain->SetFullscreenState.
296                 {
297                     onResize();
298                 }
299             }
300         }
301         return 0;
302
303         // WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
304     case WM_ENTERSIZEMOVE:
305         mAppPaused = true;
306         mResizing = true;
307         mTimer.stop();
308         return 0;
309
310         // WM_EXITSIZEMOVE is sent when the user releases the resize bars.
311         // Here we reset everything based on the new window dimensions.
312     case WM_EXITSIZEMOVE:
313         mAppPaused = false;
314         mResizing = false;
315         mTimer.start();
316         onResize();
317         return 0;
318
319         // WM_DESTROY is sent when the window is being destroyed.
320     case WM_DESTROY:
321         PostQuitMessage(0);
322         return 0;
323
324         // The WM_MENUCHAR message is sent when a menu is active and the user presses
325         // a key that does not correspond to any mnemonic or accelerator key.
326     case WM_MENUCHAR:
327         // Don‘t beep when we alt-enter.
328         return MAKELRESULT(0, MNC_CLOSE);
329
330         // Catch this message so to prevent the window from becoming too small.
331     case WM_GETMINMAXINFO:
332         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
333         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200;
334         return 0;
335     }
336
337     return DefWindowProc(mhMainWnd, msg, wParam, lParam);
338 }
339
340 void D3DApp::initMainWindow()
341 {
342     WNDCLASS wc;
343     wc.style = CS_HREDRAW | CS_VREDRAW;
344     wc.lpfnWndProc = MainWndProc;
345     wc.cbClsExtra = 0;
346     wc.cbWndExtra = 0;
347     wc.hInstance = mhAppInst;
348     wc.hIcon = LoadIcon(0, IDI_APPLICATION);
349     wc.hCursor = LoadCursor(0, IDC_ARROW);
350     wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
351     wc.lpszMenuName = 0;
352     wc.lpszClassName = L"D3DWndClassName";
353
354     if (!RegisterClass(&wc))
355     {
356         MessageBox(0, L"RegisterClass FAILED", 0, 0);
357         PostQuitMessage(0);
358     }
359
360     // Compute window rectangle dimensions based on requested client area dimensions.
361     RECT R = { 0, 0, mClientWidth, mClientHeight };
362     AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
363     int width = R.right - R.left;
364     int height = R.bottom - R.top;
365
366     mhMainWnd = CreateWindow(L"D3DWndClassName", mMainWndCaption.c_str(),
367         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInst, this);
368     if (!mhMainWnd)
369     {
370         MessageBox(0, L"CreateWindow FAILED", 0, 0);
371         PostQuitMessage(0);
372     }
373
374     ShowWindow(mhMainWnd, SW_SHOW);
375     UpdateWindow(mhMainWnd);
376 }
377
378 void D3DApp::initDirect3D()
379 {
380     // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain.
381     DXGI_SWAP_CHAIN_DESC sd;
382
383     // describes the backbuffer display mode
384     sd.BufferDesc.Width = mClientWidth;
385     sd.BufferDesc.Height = mClientHeight;
386     sd.BufferDesc.RefreshRate.Numerator = 60;
387     sd.BufferDesc.RefreshRate.Denominator = 1;
388     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
389     sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
390     sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
391
392     // describes multi-sampling parameters
393     // No multisampling.
394     sd.SampleDesc.Count = 1;
395     sd.SampleDesc.Quality = 0;
396
397     // The back buffer can be used for shader input or render-target output
398     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
399
400     sd.BufferCount = 1;
401
402     sd.OutputWindow = mhMainWnd;
403
404     sd.Windowed = true;
405
406     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
407
408     sd.Flags = 0;
409
410
411     // Create the device.
412     UINT createDeviceFlags = 0;
413 #if defined(DEBUG) || defined(_DEBUG)
414     createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
415 #endif
416
417     HR(D3D10CreateDeviceAndSwapChain(
418         0,                 //default adapter
419         md3dDriverType,
420         0,                 // no software device
421         createDeviceFlags,
422         D3D10_SDK_VERSION,
423         &sd,
424         &mSwapChain,
425         &md3dDevice));
426
427     onResize();
428 }
 1 /*
 2 2015.4
 3 Box.h
 4
 5 */
 6 #ifndef BOX_H
 7 #define BOX_H
 8
 9 #include "d3dUtil.h"
10
11 struct Vertex
12 {
13     D3DXVECTOR3 pos;
14     D3DXCOLOR   color;
15 };
16
17 class Box
18 {
19 public:
20     Box();
21     ~Box();
22
23     void init(ID3D10Device* device, float scale);
24     void draw();
25
26 private:
27     DWORD mNumVertices;
28     DWORD mNumFaces;
29
30     ID3D10Device* md3dDevice;
31     ID3D10Buffer* mVB;
32     ID3D10Buffer* mIB;
33 };
34
35 #endif // BOX_H
  1 /*
  2 2015.4
  3 Box.cpp
  4
  5 */
  6
  7 #include "Box.h"
  8
  9 Box::Box()
 10 : mNumVertices(0), mNumFaces(0), md3dDevice(0), mVB(0), mIB(0)
 11 {
 12 }
 13
 14 Box::~Box()
 15 {
 16     ReleaseCOM(mVB);
 17     ReleaseCOM(mIB);
 18 }
 19
 20 void Box::init(ID3D10Device* device, float scale)
 21 {
 22     md3dDevice = device;
 23
 24     mNumVertices = 8;
 25     mNumFaces    = 12;
 26
 27     // Create vertex buffer
 28     Vertex vertices[] =
 29     {
 30         { D3DXVECTOR3(-1.0f, -1.0f, -1.0f), WHITE},
 31         { D3DXVECTOR3(-1.0f, +1.0f, -1.0f), BLACK},
 32         { D3DXVECTOR3(+1.0f, +1.0f, -1.0f), RED},
 33         { D3DXVECTOR3(+1.0f, -1.0f, -1.0f), GREEN},
 34         { D3DXVECTOR3(-1.0f, -1.0f, +1.0f),  BLUE},
 35         { D3DXVECTOR3(-1.0f, +1.0f, +1.0f), YELLOW},
 36         { D3DXVECTOR3(+1.0f, +1.0f, +1.0f), CYAN},
 37         { D3DXVECTOR3(+1.0f, -1.0f, +1.0f), MAGENTA},
 38     };
 39
 40     // Scale the box.
 41     // 乘上比例
 42     for(DWORD i = 0; i < mNumVertices; ++i)
 43         vertices[i].pos *= scale;
 44
 45     // Describes a buffer resource
 46     /*
 47     typedef enum D3D10_USAGE {
 48         D3D10_USAGE_DEFAULT    = 0,
 49         D3D10_USAGE_IMMUTABLE  = 1,    // only be read by the GPU.
 50         D3D10_USAGE_DYNAMIC    = 2,    // is accessible by both the GPU and the CPU (write only).
 51         D3D10_USAGE_STAGING    = 3
 52     } D3D10_USAGE;
 53
 54     */
 55     D3D10_BUFFER_DESC vbd;
 56     vbd.Usage = D3D10_USAGE_IMMUTABLE;
 57     vbd.ByteWidth = sizeof(Vertex) * mNumVertices;
 58     vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
 59     vbd.CPUAccessFlags = 0;
 60     vbd.MiscFlags = 0;
 61
 62     // Specifies data for initializing a subresource
 63     D3D10_SUBRESOURCE_DATA vinitData;
 64     vinitData.pSysMem = vertices;
 65
 66     // Create a buffer (vertex buffer, index buffer, or shader-constant buffer)
 67     /*
 68     HRESULT CreateBuffer(
 69         [in]   const D3D10_BUFFER_DESC *pDesc,
 70         [in]   const D3D10_SUBRESOURCE_DATA *pInitialData,
 71         [out]  ID3D10Buffer **ppBuffer );
 72     */
 73     HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB));
 74
 75     // Create the index buffer
 76     // Box 六面
 77     DWORD indices[] = {
 78         // front face
 79         0, 1, 2,
 80         0, 2, 3,
 81
 82         // back face
 83         4, 6, 5,
 84         4, 7, 6,
 85
 86         // left face
 87         4, 5, 1,
 88         4, 1, 0,
 89
 90         // right face
 91         3, 2, 6,
 92         3, 6, 7,
 93
 94         // top face
 95         1, 5, 6,
 96         1, 6, 2,
 97
 98         // bottom face
 99         4, 0, 3,
100         4, 3, 7
101     };
102
103     D3D10_BUFFER_DESC ibd;
104     ibd.Usage = D3D10_USAGE_IMMUTABLE;
105     ibd.ByteWidth = sizeof(DWORD) * mNumFaces*3;
106     ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
107     ibd.CPUAccessFlags = 0;
108     ibd.MiscFlags = 0;
109
110     D3D10_SUBRESOURCE_DATA iinitData;
111     iinitData.pSysMem = indices;
112     HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));
113 }
114
115 void Box::draw()
116 {
117     UINT stride = sizeof(Vertex);
118     UINT offset = 0;
119     /*
120     Bind an array of vertex buffers to the input-assembler stage
121
122     void IASetVertexBuffers(
123         [in]  UINT StartSlot,
124         [in]  UINT NumBuffers,
125         [in]  ID3D10Buffer *const *ppVertexBuffers,
126         [in]  const UINT *pStrides,
127         [in]  const UINT *pOffsets );    //Pointer to an array of offset values;
128     */
129     md3dDevice->IASetVertexBuffers(0, 1, &mVB, &stride, &offset);
130
131     /*
132     Bind an index buffer to the input-assembler stage.
133     将一个索引缓冲区绑定到输入汇编器阶段
134     void IASetIndexBuffer(
135         [in]  ID3D10Buffer *pIndexBuffer,
136         [in]  DXGI_FORMAT Format,
137         [in]  UINT Offset );
138     */
139     md3dDevice->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0);
140
141     /*
142     void DrawIndexed(
143         [in]  UINT IndexCount,
144         [in]  UINT StartIndexLocation,
145         [in]  INT BaseVertexLocation );    //Offset from the start of the vertex buffer to the first vertex
146     */
147     md3dDevice->DrawIndexed(mNumFaces*3, 0, 0);
148
149
150     /*
151     完成图元汇编后,顶点将被送往顶点着色器(vertex shader)阶段。顶点着色器可以被看成是一个以顶点作为输入输出数据的函数,
152     每个将要绘制的顶点都会通过顶点着色器推送至硬件.
153     */
154 }
 1 /*
 2 2015.4
 3 color.fx
 4
 5 Transforms and colors geometry.
 6 使用下面的后缀来表示空间:L(局部空间)、W(世界空间)、V(观察空间)、H(齐次裁剪空间)
 7 */
 8
 9
10 cbuffer cbPerObject
11 {
12     // 常量缓冲区,由着色器来访问
13     float4x4 gWVP;
14 };
15
16 void VS(float3 iPosL  : POSITION,
17         float4 iColor : COLOR,
18         out float4 oPosH  : SV_POSITION,
19         out float4 oColor : COLOR)
20 {
21     // Transform to homogeneous clip space.
22     // 将顶点位置从局部空间变换到齐次裁剪空间,矩阵gWVP是世界矩阵、观察矩阵和投影矩阵的组合矩阵
23     // float4(iPosL, 1.0f)相当于“float4(iPosL.x,iPosL.y, iPosL.z, 1.0f)
24     oPosH = mul(float4(iPosL, 1.0f), gWVP);
25
26     oColor = iColor;
27 }
28
29 float4 PS(float4 posH  : SV_POSITION,
30           float4 color : COLOR) : SV_Target
31 {
32     // 这里像素着色器只是简单地返回插值颜色
33     return color;
34 }
35
36 // 一个technique 由一个或多个pass 组成,每个pass实现一种不同的几何体渲染方式
37 technique10 ColorTech
38 {
39     // 一个pass 由一个顶点着色器、一个可选的几何着色器、一个像素着色器和一些渲染状态组成
40     pass P0
41     {
42         // 顶点着色器设置为版本4.0, 4.0不再使用常量寄存器,而是使用常量缓存Constant Buffer
43         SetVertexShader( CompileShader( vs_4_0, VS() ) );
44         SetGeometryShader( NULL );
45         SetPixelShader( CompileShader( ps_4_0, PS() ) );
46     }
47 }
  1 /*
  2 2015.4
  3 main_Box.cpp
  4
  5 Color Cube
  6 Controls:
  7 ‘A‘/‘D‘/‘W‘/‘S‘ - Rotate
  8 */
  9
 10 #include "d3dApp.h"
 11 #include "Box.h"
 12
 13 class ColoredCubeApp : public D3DApp
 14 {
 15 public:
 16     ColoredCubeApp(HINSTANCE hInstance);
 17     ~ColoredCubeApp();
 18
 19     void initApp();
 20     void onResize();
 21     void updateScene(float dt);
 22     void drawScene();
 23
 24 private:
 25     void buildFX();
 26     void buildVertexLayouts();
 27
 28 private:
 29     Box mBox;
 30
 31     ID3D10Effect* mFX;
 32     ID3D10EffectTechnique* mTech;
 33     ID3D10InputLayout* mVertexLayout;
 34     ID3D10EffectMatrixVariable* mfxWVPVar;
 35
 36     D3DXMATRIX mView;
 37     D3DXMATRIX mProj;
 38     D3DXMATRIX mWVP;
 39
 40     float mTheta;
 41     float mPhi;
 42 };
 43
 44 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,PSTR cmdLine, int showCmd)
 45 {
 46     // Enable run-time memory check for debug builds.
 47 #if defined(DEBUG) | defined(_DEBUG)
 48     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 49 #endif
 50
 51     ColoredCubeApp theApp(hInstance);
 52     theApp.initApp();
 53
 54     return theApp.run();
 55 }
 56
 57 ColoredCubeApp::ColoredCubeApp(HINSTANCE hInstance)
 58 : D3DApp(hInstance), mFX(0), mTech(0), mVertexLayout(0),
 59 mfxWVPVar(0), mTheta(0.0f), mPhi(PI*0.25f)
 60 {
 61     // 设为单位矩阵
 62     D3DXMatrixIdentity(&mView);
 63     D3DXMatrixIdentity(&mProj);
 64     D3DXMatrixIdentity(&mWVP);
 65 }
 66
 67 ColoredCubeApp::~ColoredCubeApp()
 68 {
 69     if (md3dDevice)
 70         md3dDevice->ClearState();
 71
 72     ReleaseCOM(mFX);
 73     ReleaseCOM(mVertexLayout);
 74 }
 75
 76 void ColoredCubeApp::initApp()
 77 {
 78     D3DApp::initApp();
 79
 80     // Box 绑定到该 md3dDevice
 81     mBox.init(md3dDevice, 1.0f);
 82
 83     buildFX();
 84     buildVertexLayouts();
 85 }
 86
 87 void ColoredCubeApp::onResize()
 88 {
 89     D3DApp::onResize();
 90
 91     float aspect = (float)mClientWidth / mClientHeight;
 92     D3DXMatrixPerspectiveFovLH(&mProj, 0.25f*PI, aspect, 1.0f, 1000.0f);
 93 }
 94
 95 void ColoredCubeApp::updateScene(float dt)
 96 {
 97     D3DApp::updateScene(dt);
 98
 99     // Update angles based on input to orbit camera around box.
100     //改变夹角
101     if (GetAsyncKeyState(‘A‘) & 0x8000)    mTheta -= 5.0f*dt;
102     if (GetAsyncKeyState(‘D‘) & 0x8000)    mTheta += 5.0f*dt;
103     if (GetAsyncKeyState(‘W‘) & 0x8000)    mPhi -= 5.0f*dt;
104     if (GetAsyncKeyState(‘S‘) & 0x8000)    mPhi += 5.0f*dt;
105
106     // Restrict the angle mPhi.
107     if (mPhi < 0.1f)    mPhi = 0.1f;
108     if (mPhi > PI - 0.1f)    mPhi = PI - 0.1f;
109
110     // Convert Spherical to Cartesian coordinates: mPhi measured from +y
111     // and mTheta measured counterclockwise from -z.
112     float x = 5.0f*sinf(mPhi)*sinf(mTheta);
113     float z = -5.0f*sinf(mPhi)*cosf(mTheta);
114     float y = 5.0f*cosf(mPhi);
115
116     // Build the view matrix.
117     D3DXVECTOR3 pos(x, y, z);
118     D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
119     D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
120
121     D3DXMatrixLookAtLH(&mView, &pos, &target, &up);
122 }
123
124 void ColoredCubeApp::drawScene()
125 {
126     D3DApp::drawScene();
127
128     // Restore default states, input layout and primitive topology
129     // because mFont->DrawText changes them.  Note that we can
130     // restore the default states by passing null.
131     md3dDevice->OMSetDepthStencilState(0, 0);
132     float blendFactors[] = { 0.0f, 0.0f, 0.0f, 0.0f };
133     md3dDevice->OMSetBlendState(0, blendFactors, 0xffffffff);
134
135     // 当一个input layout被创建以后, 调用IASetInputLayout函数可以把它绑定一个divece中
136     md3dDevice->IASetInputLayout(mVertexLayout);
137
138     // vertex buffer只是在内存中存储了一系列内存点,用Primitive Topology告诉Direct3D用点形成几何图形的方式
139     md3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
140
141     // set constants
142     mWVP = mView*mProj;
143     mfxWVPVar->SetMatrix((float*)&mWVP);
144
145     D3D10_TECHNIQUE_DESC techDesc;
146     mTech->GetDesc(&techDesc);
147     for (UINT p = 0; p < techDesc.Passes; ++p)
148     {
149         /*Apply方法的作用:
150         更新存储在GPU 内存中的常量缓冲区、将着色器程序绑定到管线、并启用在pass中指定的各种渲染状态。
151         */
152         mTech->GetPassByIndex(p)->Apply(0);
153
154         mBox.draw();
155     }
156
157     // We specify DT_NOCLIP, so we do not care about width/height of the rect.
158     RECT R = { 5, 5, 0, 0 };
159     mFont->DrawText(0, mFrameStats.c_str(), -1, &R, DT_NOCLIP, BLACK);
160
161     mSwapChain->Present(0, 0);
162 }
163
164 // 着色器
165 void ColoredCubeApp::buildFX()
166 {
167     DWORD shaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
168 #if defined( DEBUG ) || defined( _DEBUG )
169     shaderFlags |= D3D10_SHADER_DEBUG;
170     shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION;
171 #endif
172
173     // 通用内存块,使用时应该对它执行相应的类型转换
174     // used to return object code and error messages in APIs that compile vertex, geometry and pixel shaders.
175     ID3D10Blob* compilationErrors = 0;
176
177     HRESULT hr = 0;
178     // 编译着色器
179     hr = D3DX10CreateEffectFromFile(L"color.fx", 0, 0,
180         "fx_4_0", shaderFlags, 0, md3dDevice, 0, 0, &mFX, &compilationErrors, 0);
181     if (FAILED(hr))
182     {
183         if (compilationErrors)
184         {
185             MessageBoxA(0, (char*)compilationErrors->GetBufferPointer(), 0, 0);
186             ReleaseCOM(compilationErrors);
187         }
188         // Outputs a formatted error message to the debug stream
189         DXTrace(__FILE__, (DWORD)__LINE__, hr, L"D3DX10CreateEffectFromFile", true);
190     }
191
192     // 获得指向technique对象的指针
193     mTech = mFX->GetTechniqueByName("ColorTech");
194
195     /*
196     ID3D10Effect::GetVariableByName方法返回一个ID3D10EffectVariable指针。
197     它是一种通用效果变量类型;要获得指向特定类型变量的指针(例如,矩阵、向量、标量),
198     你必须使用相应的As*****方法(例如,AsMatrix、AsVector、AsScalar)。
199     然后可以通过C++接口来更新它们
200     */
201     mfxWVPVar = mFX->GetVariableByName("gWVP")->AsMatrix();
202 }
203
204 // 构建图元
205 void ColoredCubeApp::buildVertexLayouts()
206 {
207     /*
208     typedef struct D3D10_INPUT_ELEMENT_DESC {
209         LPCSTR                     SemanticName;
210         UINT                       SemanticIndex;
211         DXGI_FORMAT                Format;
212         UINT                       InputSlot;        // between 0 and 15
213         UINT                       AlignedByteOffset;
214         D3D10_INPUT_CLASSIFICATION InputSlotClass;
215         UINT                       InstanceDataStepRate;
216     } D3D10_INPUT_ELEMENT_DESC;
217     */
218     D3D10_INPUT_ELEMENT_DESC vertexDesc[] =
219     {
220         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
221         { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }
222     };
223
224     D3D10_PASS_DESC PassDesc;
225     // Get a pass description by calling ID3D10EffectPass::GetDesc
226     mTech->GetPassByIndex(0)->GetDesc(&PassDesc);
227
228     /*
229     Create an input-layout object to describe the input-buffer data for the input-assembler stage.
230
231     HRESULT CreateInputLayout(
232         [in]   const D3D10_INPUT_ELEMENT_DESC *pInputElementDescs,
233         [in]   UINT NumElements,
234         [in]   const void *pShaderBytecodeWithInputSignature,
235         [in]   SIZE_T BytecodeLength,
236         [out]  ID3D10InputLayout **ppInputLayout );
237
238     After creating an input layout object, it must be bound to the input-assembler stage
239     before calling a draw API.
240     */
241     HR(md3dDevice->CreateInputLayout(vertexDesc, 2, PassDesc.pIAInputSignature,
242         PassDesc.IAInputSignatureSize, &mVertexLayout));
243 }
时间: 2024-10-12 22:05:44

DirectX Box的相关文章

DirectX 读书笔记(14) Cube mapping之SkyBox

作者:i_dovelemon 来源:CSDN 日期:2014 / 10 / 26 主题:Cube mapping, SkyBox 引言 在3D游戏中,特别是在室外游戏场景中,往往需要模拟出天空的效果.如下图所示: 在这张图片中,读者可以发现,场景中存在这天空,而且不管游戏角色如何在场景中进行移动,都无法靠近天空.通过添加这样的效果,使得游戏世界更加的丰富多彩,更加的接近现实的世界.本节,就想大家讲述,如何在DirectX中实现这样的天空效果. Cube Mapping Cube Mapping是

DirectX (13) 粒子系统

笔者:i_dovelemon 资源:CSDN 日期:2014 / 10 / 16 主题:Point Sprite, Particle System 介绍 在游戏中.非常多的绚丽,灿烂的特效,都能够使用粒子系统制作出来.那么粒子系统.究竟是什么?它是怎样工作的?接下来的文章,将会向大家讲述怎样构建一个简单的粒子系统. 粒子系统 所谓的粒子系统,指的是一个粒子管理器,用于在特定条件下产生特定的粒子.而且赋予粒子以运动. 所以,可以将粒子系统看成是一个个粒子的集合. 而不同的效果.是要我们自己来控制粒

Windows10 使用Virtual Box一启动虚拟机就蓝屏(错误代码SYSTEM_SERVICE_EXCEPTION)解决方案

原文:Windows10 使用Virtual Box一启动虚拟机就蓝屏(错误代码SYSTEM_SERVICE_EXCEPTION)解决方案 一打开虚拟机电脑就立马蓝屏重启,新建虚拟机也没用,然后就开始百度,百度上全说什么驱动不对,然后我就卸载升级各种驱动,然后各种重装VirtualBox,还是不行,搞了一两个小时,都快放弃了.决定上个google,终于看到一篇文章说是因为Hyper-V与Virtual Box冲突了,只需要在控制面板关闭就行.然后抱着试一试的心态. 首先我们先打开控制面板.按Wi

CloudFoundry in 1 Box简介:PCF-Dev篇

在<CloudFoundry in 1 Box简介:Bosh-lite篇>我们介绍了Bosh-lite的架构和部署.在本篇中,我们将详细描述另一个CloudFoundry in 1 Box解决方案PCF-Dev. 1PCF-dev简介 PCF是Pivotal发行的Cloud Foundry商业版,PCF-Dev原名MicroPCF,是Pivotal为PCF的应用开发人员准备的一款App单虚拟机版的CloudFoundry.但是,麻雀虽小,五脏俱全.PCF-Dev虽然可以在仅仅一台虚拟式上即可运

CodeForces 388A Fox and Box Accumulation 贪心

Fox Ciel has n boxes in her room. They have the same size and weight, but they might have different strength. The i-th box can hold at most xi boxes on its top (we'll call xi the strength of the box). Since all the boxes have the same size, Ciel cann

poj1442(Black Box)

题目地址:Black Box 题目大意: 有一个黑盒子可以进行两种操作,一种是ADD往盒子里存数,一种是GET查找盒子里的第几个数,默认盒子里始终是从小到大排列,然后A(1).A(2)....A(M)为要存进盒子的数,u(1).u(2).....u(N)的数并不是取出第几个数,而这里u(N)存的数是插入几个A(M)到盒子里去,这里有一个P(1 <= p <= N) 和u是同序列的.输出 p-minimum number from our A(1), A(2), ..., A(u(p)) seq

Flexible Box布局基础知识详解

1.基本概念,借用阮一峰老师的一张图: 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis).主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end:交叉轴的开始位置叫做cross start,结束位置叫做cross end. 项目默认沿主轴排列.单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size. 2.容器的基本属性 flex-direction flex-wrap flex-flow j

Vagrant box ubuntu/xenial64 没有密码的解决方法

参考了Vagrant box ubuntu/xenial64 の ubuntuユーザ の passwordについて 1. 可以通过 Git Bash 使用  vagrant ssh 登录到Ubuntu/xenial64的终端中 2. 在终端中输入: vim useradd.sh 文件内容 #!/bin/bash set -Ceu USER="vagrant" # password "vagrant" を SHA-512 でハッシュ化 PASSWORD=$(perl

adminLTE 教程 -6 多box

多box相比box来说使用的场景并不多 <div class="box box-solid"> <div class="box-header with-border"> <h3 class="box-title">Collapsible Accordion</h3> </div> <!-- /.box-header --> <div class="box-bo