DirectX11用起来好爽啊

DirectX11用起来好爽啊
    DirectX最振奋人心的一点就是,取消了所有固定管线,功能全部用shader来做。这样就再也不需要受到各种功能上的限制的束缚了。譬如opengl旧版本的时候,可以输入多个贴图,然后每一层的贴图给一个blend function,搞得好生复杂。到了后来,大家都不用固定管线了。现在DirectX11直接取消了固定管线,API反而简洁了许多,也不会有各种鸟事发生。

    上图:


    这里使用的功能有
    1:顶点缓冲区和索引缓冲区
    2:像素点光源(每一个像素分别计算,而不是在顶点计算完插值)
    3:CubeMap+多层贴图混合
    4:渲染到贴图(动态生成CubeMap)

    代码上传在了 Vczh Library++ 3.0的Candidate目录里面(Candidate\Simulator\DirectX\Beginning\Beginning.sln)

    下面贴出中间那个球的shader:
 1  cbuffer MatrixBuffer : register(b0)
 2  {
 3      matrix worldMatrix;
 4      matrix viewMatrix;
 5      matrix projectionMatrix;
 6      float4 lightPosition;
 7      float4 lightColor;
 8      float4 lightProperty;  // (minimumDistance, minimumStrenght, _, _)
 9      float4 environmentColor;
10  };
11 
12  Texture2D shaderTexture : register(t0);
13  SamplerState shaderSampler : register(s0);
14  TextureCube cubeMap : register(t1);
15 
16  struct  VIn
17  {
18      float4 position : POSITION;
19      float3 normal : NORMAL;
20      float2 texcoord0 : TEXCOORD0;
21  };
22 
23  struct  PIn
24  {
25      float4 position : SV_POSITION;
26      float4 worldPosition : POSITION0;
27      float3 worldNormal : NORMAL0;
28      float4 viewPosition : POSITION1;
29      float3 viewNormal : NORMAL1;
30      float2 texcoord0 : TEXCOORD0;
31  };
32 
33  PIn VShader(VIn input)
34  {
35      PIn output;
36      input.position.w  =   1.0f ;
37 
38      output.position  =  mul(input.position, worldMatrix);
39      output.worldPosition  =  output.position;
40      output.position  =  mul(output.position, viewMatrix);
41      output.viewPosition  =  output.position;
42      output.position  =  mul(output.position, projectionMatrix);
43      
44      output.worldNormal  =  mul(input.normal, (float3x3)worldMatrix);
45      output.worldNormal  =  normalize(output.worldNormal);
46      output.viewNormal  =  mul(output.worldNormal, (float3x3)viewMatrix);
47      output.viewNormal  =  normalize(output.viewNormal);
48      
49      output.texcoord0  =  input.texcoord0;
50      
51       return  output;
52  }
53 
54  float4 PShader(PIn input) : SV_TARGET
55  {
56      float3 cubeMapNormal  =  reflect(input.viewPosition.xyz / input.viewPosition.w, input.viewNormal);
57      float4 cubeMapColor  =  cubeMap.Sample(shaderSampler, cubeMapNormal);
58      float4 textureColor  =  shaderTexture.Sample(shaderSampler, input.texcoord0);
59      float4 materialColor  =  textureColor * 0.4   +  cubeMapColor * 0.6 ;
60      
61      float4 lightDirection  =  lightPosition - input.worldPosition;
62       float  lightCos  =  max( 0 , dot(normalize(lightDirection), input.worldNormal));
63       float  lightDistance  =  length(lightDirection);
64       float  lightStrength  =  lightCos / max( 1 , (lightDistance * lightDistance) / lightProperty.x) * lightProperty.y;
65      float4 diffuseColor  =  environmentColor + lightColor * float4(lightStrength,lightStrength,lightStrength, 1 );
66 
67      float4 color  =  materialColor * diffuseColor;
68       return  color;
69  }

    为了便于调试和修改,我还封装了一个简单的DirectX11的库(Candidate\Simulator\DirectX\Beginning\Shared)。当然现在功能肯定还不够全面。下面是使用这个小库写的渲染上面的图的代码:
  1  #include  " ModelBuilder.h "
  2  #include  " ..\..\..\..\..\Library\Pointer.h "
  3 
  4  using   namespace  vl;
  5 
  6  struct  ConstantBufferType
  7  {
  8      D3DXMATRIX world;
  9      D3DXMATRIX view;
 10      D3DXMATRIX projection;
 11      D3DXVECTOR4 lightPosition;
 12      D3DXCOLOR lightColor;
 13       float  lightMinimunDistanceSquare;
 14       float  lightMinimumStrenght;
 15       float  unused0[ 2 ];
 16      D3DXCOLOR environmentColor;
 17  };
 18 
 19  struct  World
 20  {
 21  private :
 22       const  DirectXEnvironment *                     env;
 23       int                                             clientWidth, clientHeight;
 24      D3DXMATRIX                                    viewMatrix, worldMatrix[ 4 ];
 25 
 26      DirectXConstantBuffer < ConstantBufferType >     constantBuffer;
 27      DirectXDepthBuffer                            depthBuffer;
 28      DirectXWindowRenderTarget                    windowRenderTarget;
 29      DirectXRenderer                                renderer;
 30      DirectXViewport                                viewport;
 31 
 32      DirectXTextureBuffer                        cubeMapTextures;
 33      Ptr < DirectXTextureRenderTarget >                 cubeMapRenderTargets[ 6 ];
 34      DirectXDepthBuffer                            cubeMapDepthBuffer;
 35      DirectXCubeMapReference                        cubeMap;
 36      
 37      DirectXVertexBuffer < LightVertex >             lightGeometry;
 38      DirectXVertexBuffer < ColorVertex >             cube1;
 39      DirectXVertexBuffer < TextureVertex >             cube2, sphere;
 40 
 41      DirectXShader < LightVertex >                     lightShader;
 42      DirectXShader < ColorVertex >                     colorShader;
 43      DirectXShader < TextureVertex >                 textureShader;
 44      DirectXTextureBuffer                        textureColumn;
 45      DirectXTextureBuffer                        textureEarth;
 46      DirectXSamplerBuffer                        textureSampler;
 47      DirectXShader < TextureVertex >                 cubeShader;
 48 
 49       void  WriteConstantBuffer( int  worldMatrixIndex)
 50      {
 51          D3DXMatrixTranspose( & constantBuffer -> world,  & worldMatrix[worldMatrixIndex]);
 52          D3DXMatrixTranspose( & constantBuffer -> view,  & viewMatrix);
 53          D3DXMatrixTranspose( & constantBuffer -> projection,  & viewport.projectionMatrix);
 54          constantBuffer.Update();
 55      }
 56  public :
 57      World( const  DirectXEnvironment *  _env,  int  _clientWidth,  int  _clientHeight)
 58          :env(_env)
 59          ,clientWidth(_clientWidth), clientHeight(_clientHeight)
 60          ,constantBuffer(_env)
 61          ,depthBuffer(_env), windowRenderTarget(_env), renderer(_env), viewport(_env)
 62          ,cubeMapTextures(_env), cubeMapDepthBuffer(_env), cubeMap(_env)
 63          ,lightGeometry(_env) ,cube1(_env) ,cube2(_env) ,sphere(_env)
 64          ,lightShader(_env) ,colorShader(_env) ,textureShader(_env)
 65          ,textureColumn(_env) ,textureEarth(_env) ,textureSampler(_env)
 66          ,cubeShader(_env)
 67      {
 68          {
 69              depthBuffer.Update(clientWidth, clientHeight);
 70              cubeMapDepthBuffer.Update( 512 512 );
 71              cubeMapTextures.Update( 512 512 6 true );
 72               for ( int  i = 0 ;i < 6 ;i ++ )
 73              {
 74                  cubeMapRenderTargets[i] = new  DirectXTextureRenderTarget(_env);
 75                  cubeMapRenderTargets[i] -> Update( & cubeMapTextures, i);
 76              }
 77              cubeMap.Update( & cubeMapTextures);
 78          }
 79          BuildLightGeometry(lightGeometry);
 80          BuildColorCube(cube1);
 81          BuildTextureCube(cube2);
 82          BuildTextureSphere(sphere);
 83          {
 84              lightShader.Fill(L " LightShader.txt " , L " VShader " , L " PShader " )
 85                  .Field(L " POSITION " & LightVertex::Position)
 86                  ;
 87 
 88              colorShader.Fill(L " ColorShader.txt " , L " VShader " , L " PShader " )
 89                  .Field(L " POSITION " & ColorVertex::Position)
 90                  .Field(L " NORMAL " & ColorVertex::Normal)
 91                  .Field(L " COLOR " & ColorVertex::Color)
 92                  ;
 93 
 94              textureShader.Fill(L " TextureShader.txt " , L " VShader " , L " PShader " )
 95                  .Field(L " POSITION " & TextureVertex::Position)
 96                  .Field(L " NORMAL " & TextureVertex::Normal)
 97                  .Field(L " TEXCOORD " & TextureVertex::Texcoord0)
 98                  ;
 99 
100              textureColumn.Update(L " TextureColumn.jpg " );
101              textureEarth.Update(L " earth.bmp " );
102              textureSampler.Update(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_WRAP, D3DXCOLOR( 1 1 1 1 ));
103 
104              cubeShader.Fill(L " CubeShader.txt " , L " VShader " , L " PShader " )
105                  .Field(L " POSITION " & TextureVertex::Position)
106                  .Field(L " NORMAL " & TextureVertex::Normal)
107                  .Field(L " TEXCOORD " & TextureVertex::Texcoord0)
108                  ;
109          }
110          {
111              {
112                  D3DXMATRIX scaling;
113                  D3DXMatrixScaling( & scaling,  1.4f 1.4f 1.4f );
114 
115                  D3DXMatrixTranslation( & worldMatrix[ 0 ],  - 2 0 0 );
116                  D3DXMatrixMultiply( & worldMatrix[ 0 ],  & worldMatrix[ 0 ],  & scaling);
117                  D3DXMatrixTranslation( & worldMatrix[ 1 ],  2 0 0 );
118                  D3DXMatrixMultiply( & worldMatrix[ 1 ],  & worldMatrix[ 1 ],  & scaling);
119              }
120              {
121                  D3DXMATRIX matrix;
122                  D3DXMatrixScaling( & worldMatrix[ 2 ],  0.2f 0.2f 0.2f );
123 
124                  D3DXMatrixTranslation( & matrix,  4.7f 0 0 );
125                  D3DXMatrixMultiply( & worldMatrix[ 2 ],  & worldMatrix[ 2 ],  & matrix);
126 
127                  D3DXMatrixRotationY( & matrix, ( float )D3DX_PI / 4 );
128                  D3DXMatrixMultiply( & worldMatrix[ 2 ],  & worldMatrix[ 2 ],  & matrix);
129 
130                  D3DXMatrixRotationX( & matrix, ( float )D3DX_PI / 5 );
131                  D3DXMatrixMultiply( & worldMatrix[ 2 ],  & worldMatrix[ 2 ],  & matrix);
132              }
133              {
134                  D3DXMatrixScaling( & worldMatrix[ 3 ],  1.0f 1.0f 1.0f );
135              }
136          }
137          {
138              constantBuffer -> lightPosition = D3DXVECTOR4( 0 0 0 1 );
139              D3DXVec4Transform( & constantBuffer -> lightPosition,  & constantBuffer -> lightPosition,  & worldMatrix[ 2 ]);
140              constantBuffer -> lightColor = D3DXCOLOR( 0.7f 0.7f 0.7f 1.0f );
141              constantBuffer -> lightMinimunDistanceSquare = 9 ;
142              constantBuffer -> lightMinimumStrenght = 3 ;
143              constantBuffer -> environmentColor = D3DXCOLOR( 0.3f 0.3f 0.3f 1.0f );
144          }
145      }
146 
147       ~ World()
148      {
149      }
150 
151       void  Render()
152      {
153          {
154              D3DXVECTOR3 ats[] =
155              {
156                  D3DXVECTOR3(  1 ,   0 ,   0 ),
157                  D3DXVECTOR3( - 1 ,   0 ,   0 ),
158                  D3DXVECTOR3(  0 ,   1 ,   0 ),
159                  D3DXVECTOR3(  0 - 1 ,   0 ),
160                  D3DXVECTOR3(  0 ,   0 ,   1 ),
161                  D3DXVECTOR3(  0 ,   0 - 1 ),
162              };
163              D3DXVECTOR3 ups[] =
164              {
165                  D3DXVECTOR3(  0 ,   1 ,   0 ),
166                  D3DXVECTOR3(  0 ,   1 ,   0 ),
167                  D3DXVECTOR3(  0 ,   0 - 1 ),
168                  D3DXVECTOR3(  0 ,   0 ,   1 ),
169                  D3DXVECTOR3(  0 ,   1 ,   0 ),
170                  D3DXVECTOR3(  0 ,   1 ,   0 ),
171              };
172               for ( int  i = 0 ;i < 6 ;i ++ )
173              {
174                  D3DXMatrixLookAtLH( & viewMatrix,  & D3DXVECTOR3( 0 0 0 ),  & ats[i],  & ups[i]);
175                  renderer.SetRenderTarget(cubeMapRenderTargets[i].Obj(),  & cubeMapDepthBuffer);
176                  viewport.SetViewport( 512 512 , ( float )D3DX_PI / 2 0.1f 100.0f );
177                  cubeMapRenderTargets[i] -> Clear(D3DXCOLOR( 0.0f 0.2f 0.4f 1.0f ));
178                  cubeMapDepthBuffer.Clear();
179 
180                  constantBuffer.VSBindToRegisterBN( 0 );
181                  constantBuffer.PSBindToRegisterBN( 0 );
182 
183                  WriteConstantBuffer( 0 );
184                  cube1.SetCurrentAndRender( & colorShader);
185              
186                  WriteConstantBuffer( 1 );
187                  textureColumn.PSBindToRegisterTN( 0 );
188                  textureSampler.PSBindToRegisterSN( 0 );
189                  cube2.SetCurrentAndRender( & textureShader);
190 
191                  WriteConstantBuffer( 2 );
192                  lightGeometry.SetCurrentAndRender( & lightShader);
193              }
194          }
195          {
196              D3DXMatrixLookAtLH( & viewMatrix,  & D3DXVECTOR3( 0 0 - 10 ),  & D3DXVECTOR3( 0 0 1 ),  & D3DXVECTOR3( 0 1 0 ));
197              renderer.SetRenderTarget( & windowRenderTarget,  & depthBuffer);
198              viewport.SetViewport(clientWidth, clientHeight, ( float )D3DX_PI / 4 0.1f 100.0f );
199              windowRenderTarget.Clear(D3DXCOLOR( 0.0f 0.2f 0.4f 1.0f ));
200              depthBuffer.Clear();
201 
202              constantBuffer.VSBindToRegisterBN( 0 );
203              constantBuffer.PSBindToRegisterBN( 0 );
204 
205              WriteConstantBuffer( 0 );
206              cube1.SetCurrentAndRender( & colorShader);
207              
208              WriteConstantBuffer( 1 );
209              textureColumn.PSBindToRegisterTN( 0 );
210              textureSampler.PSBindToRegisterSN( 0 );
211              cube2.SetCurrentAndRender( & textureShader);
212 
213              WriteConstantBuffer( 2 );
214              lightGeometry.SetCurrentAndRender( & lightShader);
215              
216              WriteConstantBuffer( 3 );
217              textureEarth.PSBindToRegisterTN( 0 );
218              textureSampler.PSBindToRegisterSN( 0 );
219              cubeMap.PSBindToRegisterTN( 1 );
220              sphere.SetCurrentAndRender( & cubeShader);
221          }
222          env -> swapChain -> Present( 0 0 );
223      }
224 
225       void  Rotate( float  x,  float  y)
226      {
227          D3DXMATRIX rotation;
228          D3DXMatrixRotationYawPitchRoll( & rotation,  - x,  - y,  0 );
229          D3DXMatrixMultiply( & worldMatrix[ 0 ],  & worldMatrix[ 0 ],  & rotation);
230          D3DXMatrixMultiply( & worldMatrix[ 1 ],  & worldMatrix[ 1 ],  & rotation);
231          D3DXMatrixMultiply( & worldMatrix[ 3 ],  & worldMatrix[ 3 ],  & rotation);
232      }
233  };
234  World *  world = 0 ;
235  int  oldX = 0 ;
236  int  oldY = 0 ;
237  bool  mouseTracking = false ;
238 
239  void  CALLBACK DirectXProcIdle()
240  {
241       if (world)
242      {
243          world -> Render();
244      }
245  }
246 
247  LRESULT CALLBACK DirectXProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,  bool &  callDefWindowProc)
248  {
249       switch (uMsg)
250      {
251       case  WM_SHOWWINDOW:
252          {
253               if (wParam == TRUE)
254              {
255                   if ( ! world)
256                  {
257                      SIZE size = WindowGetClient(hwnd);
258                       const  DirectXEnvironment *  env = CreateDirectXEnvironment(hwnd);
259                      world = new  World(env, size.cx, size.cy);
260                  }
261              }
262          }
263           break ;
264       case  WM_DESTROY:
265          {
266               if (world)
267              {
268                  delete world;
269                  world = 0 ;
270                  DestroyDirectXEnvironment();
271              }
272          }
273           break ;
274       case  WM_LBUTTONDOWN:
275          {
276              SetCapture(hwnd);
277              WindowMouseInfo info(wParam, lParam,  false );
278              oldX = info.x;
279              oldY = info.y;
280              mouseTracking = true ;
281          }
282           break ;
283       case  WM_MOUSEMOVE:
284          {
285               if (mouseTracking)
286              {
287                  WindowMouseInfo info(wParam, lParam,  false );
288 
289                   int  offsetX = info.x - oldX;
290                   int  offsetY = info.y - oldY;
291                   float  rotateX = ( float )D3DX_PI * offsetX / 200 ;
292                   float  rotateY = ( float )D3DX_PI * offsetY / 200 ;
293                  world -> Rotate(rotateX, rotateY);
294 
295                  oldX = info.x;
296                  oldY = info.y;
297              }
298          }
299           break ;
300       case  WM_LBUTTONUP:
301          {
302              ReleaseCapture();
303              mouseTracking = false ;
304          }
305           break ;
306      }
307       return   0 ;
308  }



你可能感兴趣的:(DirectX11用起来好爽啊)