网站首页设计创意,类似游侠客网站建设,小程序怎么制作开发,南宁市网站设计作业内容 请勿抄袭
代码功能#xff1a;渲染一个绕中心轴自转的圆柱体。要求该圆柱体高度为3.0#xff0c;半径为0.5。
#include windows.h
#include d3d11.h
#include d3dx11.h
#include d3dcompiler.h
#include xnamath.h
#incl…作业内容 请勿抄袭
代码功能渲染一个绕中心轴自转的圆柱体。要求该圆柱体高度为3.0半径为0.5。
#include windows.h
#include d3d11.h
#include d3dx11.h
#include d3dcompiler.h
#include xnamath.h
#include cmath
#include random
#include resource.h
using namespace std;//自定义圆周率常量的近似值
const float pi 3.1415926536;//设置基本的参数包括圆面的顶点数量 圆柱体高度和底面半径
float TotalHeight 3.0;
float radius 0.5;
const int RoundPointNum 50;//通过结构体定义的方式来定义一个简单的顶点类型
struct SimpleVertex
{XMFLOAT3 Pos; //通过一个三维向量表示顶点的三维坐标信息XMFLOAT4 Color; //通过一个四维向量表示顶点的颜色信息RGB和透明度
};//通过结构体的方式定义常量缓冲区的数据格式
struct ConstantBuffer
{XMMATRIX mWorld; //存储世界矩阵将顶点变换到世界空间XMMATRIX mView; //存储观察矩阵将顶点变换到观察空间XMMATRIX mProjection; //存储投影矩阵将顶点坐标变换到裁剪空间
};//全局变量定义区
HINSTANCE g_hInst NULL; //存储应用程序的实例句柄
HWND g_hWnd NULL; //存储应用程序的主窗口句柄
D3D_DRIVER_TYPE g_driverType D3D_DRIVER_TYPE_NULL; //存储Direct3D驱动类型
D3D_FEATURE_LEVEL g_featureLevel D3D_FEATURE_LEVEL_11_0; //指定Direct3D特性级别
ID3D11Device* g_pd3dDevice NULL; //指定Direct3D设备对象
ID3D11DeviceContext* g_pImmediateContext NULL;
IDXGISwapChain* g_pSwapChain NULL;
ID3D11RenderTargetView* g_pRenderTargetView NULL;
ID3D11VertexShader* g_pVertexShader NULL;
ID3D11PixelShader* g_pPixelShader NULL;
ID3D11InputLayout* g_pVertexLayout NULL;
ID3D11Buffer* g_pVertexBuffer NULL;
ID3D11Buffer* g_pIndexBuffer NULL;
ID3D11Buffer* g_pConstantBuffer NULL;
XMMATRIX g_World;
XMMATRIX g_View;
XMMATRIX g_Projection;//前向函数声明用于后续的过程中
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Render();//程序入口进行了初始化并进入消息循环在空闲时间内进行场景渲染
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{//消除未使用参数的编译警告UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);//对窗口进行初始化if (FAILED(InitWindow(hInstance, nCmdShow)))return 0;//初始化Direct3D的设备和相关资源if (FAILED(InitDevice())){CleanupDevice();return 0;}//处理窗口消息和渲染场景MSG msg { 0 };//循环一直运行知道窗口关闭while (WM_QUIT ! msg.message){//判断消息队列中是否还有消息没有处理if (PeekMessage(msg, NULL, 0, 0, PM_REMOVE)){//将未处理的消息转换为合适的形式发送给窗口过程TranslateMessage(msg);DispatchMessage(msg);}//空闲时间则进行渲染else{Render();}}//清理所占用的资源CleanupDevice();//消息循环的退出代码return (int)msg.wParam;
}//初始化窗口并注册窗口类
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{//对窗口的相关属性进行设置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(NULL, IDC_ARROW);wcex.hbrBackground (HBRUSH)(COLOR_WINDOW 1);wcex.lpszMenuName NULL;wcex.lpszClassName LTutorialWindowClass;wcex.hIconSm LoadIcon(wcex.hInstance, (LPCTSTR)IDI_TUTORIAL1);//对窗口进行创建if (!RegisterClassEx(wcex))return E_FAIL;//完成创建窗口的过程g_hInst hInstance;RECT rc { 0, 0, 640, 480 };AdjustWindowRect(rc, WS_OVERLAPPEDWINDOW, FALSE);g_hWnd CreateWindow(LTutorialWindowClass, LDirect3D 11 Tutorial 4: 3D Spaces, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,NULL);if (!g_hWnd)return E_FAIL;ShowWindow(g_hWnd, nCmdShow);return S_OK;
}//用于编译着色器的辅助函数
HRESULT CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{HRESULT hr S_OK;DWORD dwShaderFlags D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.// Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program.dwShaderFlags | D3DCOMPILE_DEBUG;
#endifID3DBlob* pErrorBlob;hr D3DX11CompileFromFile(szFileName, NULL, NULL, szEntryPoint, szShaderModel,dwShaderFlags, 0, NULL, ppBlobOut, pErrorBlob, NULL);if (FAILED(hr)){if (pErrorBlob ! NULL)OutputDebugStringA((char*)pErrorBlob-GetBufferPointer());if (pErrorBlob) pErrorBlob-Release();return hr;}if (pErrorBlob) pErrorBlob-Release();return S_OK;
}// 初始化和设置一些与图形渲染相关的对象和参数
HRESULT InitDevice(void)
{//定义了一个名为hr的变量类型为HRESULT并将其初始化为S_OKHRESULT hr S_OK;//定义了一个名为rc的变量类型为RECT用于存储窗口的矩形区域RECT rc;//调用GetClientRect函数将窗口g_hWnd的客户区域的矩形信息存储到rc变量中GetClientRect(g_hWnd, rc);//计算窗口宽度UINT width rc.right - rc.left;//计算窗口高度UINT height rc.bottom - rc.top;//存储创建Direct3D设备时的标志UINT createDeviceFlags 0;//如果定义了_DEBUG宏则执行#ifdef _DEBUG和#endif之间的代码块
#ifdef _DEBUG//如果处于调试模式将D3D11_CREATE_DEVICE_DEBUG标志位按位或运算 | 到createDeviceFlags变量上createDeviceFlags | D3D11_CREATE_DEVICE_DEBUG;
#endif//定义了一个名为driverTypes的数组包含了三种Direct3D驱动类型硬件驱动、WARP驱动和参考驱动D3D_DRIVER_TYPE driverTypes[] {D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP,D3D_DRIVER_TYPE_REFERENCE,};//计算driverTypes数组中驱动类型的数量UINT numDriverTypes ARRAYSIZE(driverTypes);//定义了一个名为featureLevels的数组包含了三种Direct3D功能级别11.0、10.1和10.0D3D_FEATURE_LEVEL featureLevels[] {D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0,};//计算featureLevels数组中功能级别的数量UINT numFeatureLevels ARRAYSIZE(featureLevels);//设置交换链的描述信息//包括缓冲区数量、尺寸、像素格式、刷新率、使用方式、输出窗口、抗锯齿采样等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;//使用一个循环来尝试不同的驱动类型创建Direct3D设备和交换链for (UINT driverTypeIndex 0; driverTypeIndex numDriverTypes; driverTypeIndex){g_driverType driverTypes[driverTypeIndex];hr D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,D3D11_SDK_VERSION, sd, g_pSwapChain, g_pd3dDevice, g_featureLevel, g_pImmediateContext);if (SUCCEEDED(hr))break;}//如果设备和交换链创建失败则返回错误代码if (FAILED(hr))return hr;//创建渲染目标视图ID3D11Texture2D* pBackBuffer NULL;hr g_pSwapChain-GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)pBackBuffer);if (FAILED(hr))return hr;hr g_pd3dDevice-CreateRenderTargetView(pBackBuffer, NULL, g_pRenderTargetView);pBackBuffer-Release();if (FAILED(hr))return hr;//将渲染目标视图设置为当前的渲染目标以便将渲染的图像输出到该渲染目标g_pImmediateContext-OMSetRenderTargets(1, g_pRenderTargetView, NULL);//设置视口,定义了渲染目标上的可见区域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);//编译顶点着色器ID3DBlob* pVSBlob NULL;hr CompileShaderFromFile(LCylinder Rendering.fx, VS, vs_4_0, pVSBlob);if (FAILED(hr)){MessageBox(NULL,LThe FX file cannot be compiled. Please run this executable from the directory that contains the FX file., LError, MB_OK);return hr;}//创建顶点着色器hr g_pd3dDevice-CreateVertexShader(pVSBlob-GetBufferPointer(), pVSBlob-GetBufferSize(), NULL, g_pVertexShader);if (FAILED(hr)){pVSBlob-Release();return hr;}// 定义输入布局,指定顶点数据的格式D3D11_INPUT_ELEMENT_DESC layout[] {{ POSITION, 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },{ COLOR, 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },};UINT numElements ARRAYSIZE(layout);//创建输入布局将输入布局元素与顶点着色器关联起来hr g_pd3dDevice-CreateInputLayout(layout, numElements, pVSBlob-GetBufferPointer(),pVSBlob-GetBufferSize(), g_pVertexLayout);pVSBlob-Release();if (FAILED(hr))return hr;//设置当前渲染管线中的输入布局g_pImmediateContext-IASetInputLayout(g_pVertexLayout);//编译像素着色器ID3DBlob* pPSBlob NULL;hr CompileShaderFromFile(LCylinder Rendering.fx, PS, ps_4_0, pPSBlob);if (FAILED(hr)){MessageBox(NULL,LThe FX file cannot be compiled. Please run this executable from the directory that contains the FX file., LError, MB_OK);return hr;}//创建像素着色器hr g_pd3dDevice-CreatePixelShader(pPSBlob-GetBufferPointer(), pPSBlob-GetBufferSize(), NULL, g_pPixelShader);pPSBlob-Release();if (FAILED(hr))return hr;//设置构成圆面的顶点的个数const int PointNum 2 * RoundPointNum 2;float angleUnit 360.0 / RoundPointNum;float halfHeight TotalHeight / 2;SimpleVertex vertices[PointNum];random_device device;mt19937 engine(device());uniform_real_distributionfloat getRandom(0.0f, 1.0f);//逐一为每一个顶点设置空间坐标和颜色for (int i(0); i RoundPointNum; i){float x radius * sin(i * angleUnit * pi / 180.0);float z radius * cos(i * angleUnit * pi / 180.0);float R getRandom(engine);float G getRandom(engine);float B getRandom(engine);vertices[i] { XMFLOAT3(x,-halfHeight,z) ,XMFLOAT4(R,G,B,1.0f)};vertices[i RoundPointNum] { XMFLOAT3(x,halfHeight,z),XMFLOAT4(R,G,B,1.0f) };}float R1 getRandom(engine);float G1 getRandom(engine);float B1 getRandom(engine);float R2 getRandom(engine);float G2 getRandom(engine);float B2 getRandom(engine);vertices[2 * RoundPointNum] { XMFLOAT3(0,halfHeight,0),XMFLOAT4(R1,G1,B1,1.0f) };vertices[2 * RoundPointNum 1] { XMFLOAT3(0,-halfHeight,0),XMFLOAT4(R2,G2,B2,1.0f) };D3D11_BUFFER_DESC bd;ZeroMemory(bd, sizeof(bd));//设置缓冲区的使用方式为默认bd.Usage D3D11_USAGE_DEFAULT;//设置缓冲区的字节宽度bd.ByteWidth sizeof(SimpleVertex) * PointNum;//设置缓冲区的绑定标志为顶点缓冲区bd.BindFlags D3D11_BIND_VERTEX_BUFFER;//定义了一个D3D11_SUBRESOURCE_DATA结构体变量并将其内存清零bd.CPUAccessFlags 0;//将顶点数据数组的指针赋给InitData的pSysMem成员D3D11_SUBRESOURCE_DATA InitData;ZeroMemory(InitData, sizeof(InitData));InitData.pSysMem vertices;//创建顶点缓冲区hr g_pd3dDevice-CreateBuffer(bd, InitData, g_pVertexBuffer);//检查创建顶点缓冲区是否失败if (FAILED(hr))return hr;//将顶点缓冲区绑定到输入装配阶段使得图形渲染管线能够使用该顶点缓冲区中的数据进行渲染UINT stride sizeof(SimpleVertex);UINT offset 0;g_pImmediateContext-IASetVertexBuffers(0, 1, g_pVertexBuffer, stride, offset);//创建一个索引数组WORD indices[12 * RoundPointNum];for (int i(0); i RoundPointNum - 1; i){//渲染下面的部分indices[i * 12] 2 * RoundPointNum;indices[i * 12 1] i;indices[i * 12 2] i 1;//渲染上面的部分indices[i * 12 3] 2 * RoundPointNum 1;indices[i * 12 4] i RoundPointNum;indices[i * 12 5] i RoundPointNum 1;//渲染侧面的第一个三角形indices[i * 12 6] i;indices[i * 12 7] i 1;indices[i * 12 8] i RoundPointNum;//渲染侧面的第二个三角形indices[i * 12 9] i 1;indices[i * 12 10] i RoundPointNum;indices[i * 12 11] i RoundPointNum - 1;}//渲染边界的情况int i(RoundPointNum - 1);//渲染下面的部分indices[i * 12] 2 * RoundPointNum;indices[i * 12 1] 0;indices[i * 12 2] RoundPointNum - 1;//渲染上面的部分indices[i * 12 3] 2 * RoundPointNum 1;indices[i * 12 4] RoundPointNum;indices[i * 12 5] 2 * RoundPointNum - 1;//渲染侧面的第一个三角形indices[i * 12 6] RoundPointNum - 1;indices[i * 12 7] 0;indices[i * 12 8] 2 * RoundPointNum - 1;//渲染侧面的第二个三角形indices[i * 12 9] 0;indices[i * 12 10] RoundPointNum;indices[i * 12 11] 2 * RoundPointNum - 1;//设置缓冲区的使用方式为默认bd.Usage D3D11_USAGE_DEFAULT;//设置缓冲区的字节宽度这里是每个索引的字节大小乘以索引数量36个索引bd.ByteWidth sizeof(WORD) * (12 * RoundPointNum);bd.BindFlags D3D11_BIND_INDEX_BUFFER;bd.CPUAccessFlags 0;InitData.pSysMem indices;hr g_pd3dDevice-CreateBuffer(bd, InitData, g_pIndexBuffer);if (FAILED(hr))return hr;//设置索引缓冲区g_pImmediateContext-IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);//设置图元拓扑,表示要绘制的图元拓扑类型为三角形列表g_pImmediateContext-IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);//创建常量缓冲区bd.Usage D3D11_USAGE_DEFAULT;bd.ByteWidth sizeof(ConstantBuffer);bd.BindFlags D3D11_BIND_CONSTANT_BUFFER;bd.CPUAccessFlags 0;hr g_pd3dDevice-CreateBuffer(bd, NULL, g_pConstantBuffer);if (FAILED(hr))return hr;//初始化世界矩阵g_World XMMatrixIdentity();//初始化视图矩阵XMVECTOR Eye XMVectorSet(0.0f, 1.0f, -5.0f, 0.0f);XMVECTOR At XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);XMVECTOR Up XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);g_View XMMatrixLookAtLH(Eye, At, Up);//初始化投影矩阵g_Projection XMMatrixPerspectiveFovLH(XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f);return S_OK;
}//释放创建的对象的函数
void CleanupDevice()
{if (g_pImmediateContext) g_pImmediateContext-ClearState();if (g_pConstantBuffer) g_pConstantBuffer-Release();if (g_pVertexBuffer) g_pVertexBuffer-Release();if (g_pIndexBuffer) g_pIndexBuffer-Release();if (g_pVertexLayout) g_pVertexLayout-Release();if (g_pVertexShader) g_pVertexShader-Release();if (g_pPixelShader) g_pPixelShader-Release();if (g_pRenderTargetView) g_pRenderTargetView-Release();if (g_pSwapChain) g_pSwapChain-Release();if (g_pImmediateContext) g_pImmediateContext-Release();if (g_pd3dDevice) g_pd3dDevice-Release();
}//窗口过程函数用于处理程序接收到的消息
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;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}//用于渲染一帧的函数
void Render(void)
{//记录时间流逝的变量static float t 0.0f;//检查当前的驱动类型是否为参考驱动类型if (g_driverType D3D_DRIVER_TYPE_REFERENCE){//如果使用参考驱动类型将t增加一个固定的增量用于模拟动画效果。t (float)XM_PI * 0.0125f;}//如果不是参考驱动类型执行以下代码块else{//记录程序开始运行的时间static DWORD dwTimeStart 0;//获取当前的系统时间DWORD dwTimeCur GetTickCount();//如果dwTimeStart为0表示是第一次执行Render函数则将dwTimeStart设置为当前时间if (dwTimeStart 0)dwTimeStart dwTimeCur;//计算从程序开始运行到当前时间的经过的秒数t (dwTimeCur - dwTimeStart) / 1000.0f;}//根据时间计算旋转矩阵用于物体的旋转变换g_World XMMatrixRotationY(t);//定义一个清除元素数组包含RGBA分量的值float ClearColor[4] { 0.0f, 0.125f, 0.3f, 1.0f };//使用清除颜色清除后备缓冲区准备渲染新的帧g_pImmediateContext-ClearRenderTargetView(g_pRenderTargetView, ClearColor);//定义一个名为cb的常量缓冲区结构ConstantBuffer cb;//将g_World矩阵转置后赋值给cb结构的mWorld成员cb.mWorld XMMatrixTranspose(g_World);//将g_View矩阵转置后赋值给cb结构的mView成员cb.mView XMMatrixTranspose(g_View);//将g_Projection矩阵转置后赋值给cb结构的mProjection成员cb.mProjection XMMatrixTranspose(g_Projection);//将cb结构的数据更新到常量缓冲区g_pConstantBuffer中g_pImmediateContext-UpdateSubresource(g_pConstantBuffer, 0, NULL, cb, 0, 0);//设置顶点着色器为g_pVertexShaderg_pImmediateContext-VSSetShader(g_pVertexShader, NULL, 0);//将常量缓冲区g_pConstantBuffer绑定到顶点着色器的指定槽位g_pImmediateContext-VSSetConstantBuffers(0, 1, g_pConstantBuffer);//设置像素着色器为g_pPixelShaderg_pImmediateContext-PSSetShader(g_pPixelShader, NULL, 0);//使用索引缓冲区进行绘制//绘制36个顶点形成12个三角形。这是一个绘制立方体的操作g_pImmediateContext-DrawIndexed(12*RoundPointNum, 0, 0);//将后备缓冲区的内容呈现到屏幕上显示渲染结果g_pSwapChain-Present(0, 0);
}