braynzarsoft-D3D11
+ -

05.颜色

2024-06-11 14 0

本课程直接建立在上一课程的基础上。
在这里,我们将在我们的顶点结构中包括四个额外的浮点,它将定义顶点的颜色RGBA。然后,我们将向输入布局添加另一个元素,它将告诉管道中的IA我们的顶点结构具有颜色值。之后,我们修改效果文件以包括顶点颜色。在顶点级别指定颜色时,光栅化阶段(RS)将在每个像素的三角形上插值颜色。我们仍然不会在像素着色器中进行任何计算,因为RS将为我们进行计算。

本节的DEMO下载地址:

效果文件

让我们先来看Effect文件,在其中创建顶点和像素着色器。
首先,我们创建一个新的结构。这个结构将是VS的返回类型,也是PS的输入类型。我们这样做是为了可以返回多个类型,因为现在我们有了顶点的位置和颜色,我们需要能够返回的不仅仅是位置。我们在VS中所做的就是将为顶点接收的值向下传递到管道中的下一阶段。颜色值最终将在到达PS之前到达RS,在PS中,顶点颜色将在三角形表面上进行插值,并且在完成颜色插值计算后,每个像素都将被发送到PS,在那里我们所做的就是将像素的颜色值传递到OM,以放在渲染目标(Backbuffer)上。

  1. //参数列表由输入布局决定
  2. VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
  3. {
  4. VS_OUTPUT output;
  5. output.Pos = inPos;
  6. output.Color = inColor;
  7. return output;
  8. }
  9. float4 PS(VS_OUTPUT input) : SV_TARGET
  10. {
  11. return input.Color;
  12. }

顶点结构

顶点结构体定义如下:

  1. struct Vertex //Overloaded Vertex Structure
  2. {
  3. Vertex(){}
  4. Vertex(float x, float y, float z,
  5. float cr, float cg, float cb, float ca)
  6. : pos(x,y,z), color(cr, cg, cb, ca){}
  7. XMFLOAT3 pos;
  8. XMFLOAT4 color;
  9. };

输入布局

现在,我们向输入布局数组添加了一个新元素。这个元素表示前12个字节之后的下一个16个字节将被发送到VS中的第一个COLOR变量。你可能认为这听起来更像是在谈论字节,但这就是输入布局的工作方式。
第一个元素是我们的位置,其格式为DXGI_format_R32B32_FLOAT枚举类型,这为R、G和B分别保留了32位或4个字节。这相当于12个字节。因此,位置元素的偏移量将为0,因为它是数组中的第一个元素。
颜色是第二个,位于位置元素后12个字节。由于颜色使用DXGI_FORMAT_R32B32A32_FLOAT枚举类型作为格式,即16个字节,因此如果我们要将另一个元素添加到输入布局中,则下一个元素必须为第5个参数放置28,因为它位于距离数组开头28个字节的位置。

  1. D3D11_INPUT_ELEMENT_DESC layout[] =
  2. {
  3. { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  4. { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  5. };

初始化场景

现在剩下要做的就是在创建缓冲区之前将颜色值添加到顶点数组中。我们把第一个变成了红色,第二个变成了绿色,第三个变成了蓝色!这些颜色将在三角形上插值。

  1. bool InitScene()
  2. Vertex v[] =
  3. {
  4. Vertex( 0.0f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f ),
  5. Vertex( 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f ),
  6. Vertex( -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f ),
  7. };

像素着色器依旧

  1. float4 PS() : SV_TARGET
  2. {
  3. return float4(0.0f, 0.0f, 1.0f, 1.0f);
  4. }

代码

main.cpp

  1. //Include and link appropriate libraries and headers//
  2. #pragma comment(lib, "d3d11.lib")
  3. #pragma comment(lib, "d3dx11.lib")
  4. #pragma comment(lib, "d3dx10.lib")
  5. #include <windows.h>
  6. #include <d3d11.h>
  7. #include <d3dx11.h>
  8. #include <d3dx10.h>
  9. #include <xnamath.h>
  10. //Global Declarations - Interfaces//
  11. IDXGISwapChain* SwapChain;
  12. ID3D11Device* d3d11Device;
  13. ID3D11DeviceContext* d3d11DevCon;
  14. ID3D11RenderTargetView* renderTargetView;
  15. ID3D11Buffer* triangleVertBuffer;
  16. ID3D11VertexShader* VS;
  17. ID3D11PixelShader* PS;
  18. ID3D10Blob* VS_Buffer;
  19. ID3D10Blob* PS_Buffer;
  20. ID3D11InputLayout* vertLayout;
  21. //Global Declarations - Others//
  22. LPCTSTR WndClassName = L"firstwindow";
  23. HWND hwnd = NULL;
  24. HRESULT hr;
  25. const int Width = 300;
  26. const int Height = 300;
  27. //Function Prototypes//
  28. bool InitializeDirect3d11App(HINSTANCE hInstance);
  29. void CleanUp();
  30. bool InitScene();
  31. void UpdateScene();
  32. void DrawScene();
  33. bool InitializeWindow(HINSTANCE hInstance,
  34. int ShowWnd,
  35. int width, int height,
  36. bool windowed);
  37. int messageloop();
  38. LRESULT CALLBACK WndProc(HWND hWnd,
  39. UINT msg,
  40. WPARAM wParam,
  41. LPARAM lParam);
  42. ///////////////**************new**************////////////////////
  43. //Vertex Structure and Vertex Layout (Input Layout)//
  44. struct Vertex //Overloaded Vertex Structure
  45. {
  46. Vertex(){}
  47. Vertex(float x, float y, float z,
  48. float cr, float cg, float cb, float ca)
  49. : pos(x,y,z), color(cr, cg, cb, ca){}
  50. XMFLOAT3 pos;
  51. XMFLOAT4 color;
  52. };
  53. D3D11_INPUT_ELEMENT_DESC layout[] =
  54. {
  55. { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  56. { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  57. };
  58. UINT numElements = ARRAYSIZE(layout);
  59. ///////////////**************new**************////////////////////
  60. int WINAPI WinMain(HINSTANCE hInstance, //Main windows function
  61. HINSTANCE hPrevInstance,
  62. LPSTR lpCmdLine,
  63. int nShowCmd)
  64. {
  65. if(!InitializeWindow(hInstance, nShowCmd, Width, Height, true))
  66. {
  67. MessageBox(0, L"Window Initialization - Failed",
  68. L"Error", MB_OK);
  69. return 0;
  70. }
  71. if(!InitializeDirect3d11App(hInstance)) //Initialize Direct3D
  72. {
  73. MessageBox(0, L"Direct3D Initialization - Failed",
  74. L"Error", MB_OK);
  75. return 0;
  76. }
  77. if(!InitScene()) //Initialize our scene
  78. {
  79. MessageBox(0, L"Scene Initialization - Failed",
  80. L"Error", MB_OK);
  81. return 0;
  82. }
  83. messageloop();
  84. CleanUp();
  85. return 0;
  86. }
  87. bool InitializeWindow(HINSTANCE hInstance,
  88. int ShowWnd,
  89. int width, int height,
  90. bool windowed)
  91. {
  92. typedef struct _WNDCLASS {
  93. UINT cbSize;
  94. UINT style;
  95. WNDPROC lpfnWndProc;
  96. int cbClsExtra;
  97. int cbWndExtra;
  98. HANDLE hInstance;
  99. HICON hIcon;
  100. HCURSOR hCursor;
  101. HBRUSH hbrBackground;
  102. LPCTSTR lpszMenuName;
  103. LPCTSTR lpszClassName;
  104. } WNDCLASS;
  105. WNDCLASSEX wc;
  106. wc.cbSize = sizeof(WNDCLASSEX);
  107. wc.style = CS_HREDRAW | CS_VREDRAW;
  108. wc.lpfnWndProc = WndProc;
  109. wc.cbClsExtra = NULL;
  110. wc.cbWndExtra = NULL;
  111. wc.hInstance = hInstance;
  112. wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  113. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  114. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
  115. wc.lpszMenuName = NULL;
  116. wc.lpszClassName = WndClassName;
  117. wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  118. if (!RegisterClassEx(&wc))
  119. {
  120. MessageBox(NULL, L"Error registering class",
  121. L"Error", MB_OK | MB_ICONERROR);
  122. return 1;
  123. }
  124. hwnd = CreateWindowEx(
  125. NULL,
  126. WndClassName,
  127. L"Lesson 4 - Begin Drawing",
  128. WS_OVERLAPPEDWINDOW,
  129. CW_USEDEFAULT, CW_USEDEFAULT,
  130. width, height,
  131. NULL,
  132. NULL,
  133. hInstance,
  134. NULL
  135. );
  136. if (!hwnd)
  137. {
  138. MessageBox(NULL, L"Error creating window",
  139. L"Error", MB_OK | MB_ICONERROR);
  140. return 1;
  141. }
  142. ShowWindow(hwnd, ShowWnd);
  143. UpdateWindow(hwnd);
  144. return true;
  145. }
  146. bool InitializeDirect3d11App(HINSTANCE hInstance)
  147. {
  148. //Describe our Buffer
  149. DXGI_MODE_DESC bufferDesc;
  150. ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
  151. bufferDesc.Width = Width;
  152. bufferDesc.Height = Height;
  153. bufferDesc.RefreshRate.Numerator = 60;
  154. bufferDesc.RefreshRate.Denominator = 1;
  155. bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  156. bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  157. bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  158. //Describe our SwapChain
  159. DXGI_SWAP_CHAIN_DESC swapChainDesc;
  160. ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
  161. swapChainDesc.BufferDesc = bufferDesc;
  162. swapChainDesc.SampleDesc.Count = 1;
  163. swapChainDesc.SampleDesc.Quality = 0;
  164. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  165. swapChainDesc.BufferCount = 1;
  166. swapChainDesc.OutputWindow = hwnd;
  167. swapChainDesc.Windowed = TRUE;
  168. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  169. //Create our SwapChain
  170. hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
  171. D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);
  172. //Create our BackBuffer
  173. ID3D11Texture2D* BackBuffer;
  174. hr = SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (void**)&BackBuffer );
  175. //Create our Render Target
  176. hr = d3d11Device->CreateRenderTargetView( BackBuffer, NULL, &renderTargetView );
  177. BackBuffer->Release();
  178. //Set our Render Target
  179. d3d11DevCon->OMSetRenderTargets( 1, &renderTargetView, NULL );
  180. return true;
  181. }
  182. void CleanUp()
  183. {
  184. //Release the COM Objects we created
  185. SwapChain->Release();
  186. d3d11Device->Release();
  187. d3d11DevCon->Release();
  188. renderTargetView->Release();
  189. triangleVertBuffer->Release();
  190. VS->Release();
  191. PS->Release();
  192. VS_Buffer->Release();
  193. PS_Buffer->Release();
  194. vertLayout->Release();
  195. }
  196. bool InitScene()
  197. {
  198. //Compile Shaders from shader file
  199. hr = D3DX11CompileFromFile(L"Effects.fx", 0, 0, "VS", "vs_4_0", 0, 0, 0, &VS_Buffer, 0, 0);
  200. hr = D3DX11CompileFromFile(L"Effects.fx", 0, 0, "PS", "ps_4_0", 0, 0, 0, &PS_Buffer, 0, 0);
  201. //Create the Shader Objects
  202. hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
  203. hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
  204. //Set Vertex and Pixel Shaders
  205. d3d11DevCon->VSSetShader(VS, 0, 0);
  206. d3d11DevCon->PSSetShader(PS, 0, 0);
  207. //Create the vertex buffer
  208. Vertex v[] =
  209. {
  210. ///////////////**************new**************////////////////////
  211. Vertex( 0.0f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f ),
  212. Vertex( 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f ),
  213. Vertex( -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f ),
  214. ///////////////**************new**************////////////////////
  215. };
  216. D3D11_BUFFER_DESC vertexBufferDesc;
  217. ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );
  218. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  219. vertexBufferDesc.ByteWidth = sizeof( Vertex ) * 3;
  220. vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  221. vertexBufferDesc.CPUAccessFlags = 0;
  222. vertexBufferDesc.MiscFlags = 0;
  223. D3D11_SUBRESOURCE_DATA vertexBufferData;
  224. ZeroMemory( &vertexBufferData, sizeof(vertexBufferData) );
  225. vertexBufferData.pSysMem = v;
  226. hr = d3d11Device->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);
  227. //Set the vertex buffer
  228. UINT stride = sizeof( Vertex );
  229. UINT offset = 0;
  230. d3d11DevCon->IASetVertexBuffers( 0, 1, &triangleVertBuffer, &stride, &offset );
  231. //Create the Input Layout
  232. hr = d3d11Device->CreateInputLayout( layout, numElements, VS_Buffer->GetBufferPointer(),
  233. VS_Buffer->GetBufferSize(), &vertLayout );
  234. //Set the Input Layout
  235. d3d11DevCon->IASetInputLayout( vertLayout );
  236. //Set Primitive Topology
  237. d3d11DevCon->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
  238. //Create the Viewport
  239. D3D11_VIEWPORT viewport;
  240. ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
  241. viewport.TopLeftX = 0;
  242. viewport.TopLeftY = 0;
  243. viewport.Width = Width;
  244. viewport.Height = Height;
  245. //Set the Viewport
  246. d3d11DevCon->RSSetViewports(1, &viewport);
  247. return true;
  248. }
  249. void UpdateScene()
  250. {
  251. }
  252. void DrawScene()
  253. {
  254. //Clear our backbuffer
  255. float bgColor[4] = {(0.0f, 0.0f, 0.0f, 0.0f)};
  256. d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor);
  257. //Draw the triangle
  258. d3d11DevCon->Draw( 3, 0 );
  259. //Present the backbuffer to the screen
  260. SwapChain->Present(0, 0);
  261. }
  262. int messageloop(){
  263. MSG msg;
  264. ZeroMemory(&msg, sizeof(MSG));
  265. while(true)
  266. {
  267. BOOL PeekMessageL(
  268. LPMSG lpMsg,
  269. HWND hWnd,
  270. UINT wMsgFilterMin,
  271. UINT wMsgFilterMax,
  272. UINT wRemoveMsg
  273. );
  274. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  275. {
  276. if (msg.message == WM_QUIT)
  277. break;
  278. TranslateMessage(&msg);
  279. DispatchMessage(&msg);
  280. }
  281. else{
  282. // run game code
  283. UpdateScene();
  284. DrawScene();
  285. }
  286. }
  287. return msg.wParam;
  288. }
  289. LRESULT CALLBACK WndProc(HWND hwnd,
  290. UINT msg,
  291. WPARAM wParam,
  292. LPARAM lParam)
  293. {
  294. switch( msg )
  295. {
  296. case WM_KEYDOWN:
  297. if( wParam == VK_ESCAPE ){
  298. DestroyWindow(hwnd);
  299. }
  300. return 0;
  301. case WM_DESTROY:
  302. PostQuitMessage(0);
  303. return 0;
  304. }
  305. return DefWindowProc(hwnd,
  306. msg,
  307. wParam,
  308. lParam);
  309. }

Effects.fx

  1. struct VS_OUTPUT
  2. {
  3. float4 Pos : SV_POSITION;
  4. float4 Color : COLOR;
  5. };
  6. VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
  7. {
  8. VS_OUTPUT output;
  9. output.Pos = inPos;
  10. output.Color = inColor;
  11. return output;
  12. }
  13. float4 PS(VS_OUTPUT input) : SV_TARGET
  14. {
  15. return input.Color;
  16. }

0 篇笔记 写笔记

作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!