初学DirectX11, 留个纪恋。

时间:2023-03-09 02:00:18
初学DirectX11, 留个纪恋。

  以前学的是openGL, 最近才开始学DirectX11,写了个很垃圾的代码,怀念以前的glPushMatrix(), glPopMatrix(), glBegin(), glEnd(), 多简单啊,可惜在openGL4后面的版本中放弃了这些经典的函数,改成了跟directX差不多的自定义管线, 我觉得openGL已经被改的面目全非了,可能是openGL慢的缘故吧。openGL4.3的VAO,VBO还是不能理解。  

写了个垃圾的程序,许多个几何体,自己写函数实现了以前glPushMatrix(),glPopMatrix()的功能。界面还是Qt写的,毕竟方便,调用API函数代码量太大。DirectX的代码真多啊,以后分装成一个类库试试。

贴一下主要的代码吧。

初学DirectX11, 留个纪恋。

几何体顶点过多变成球的时候,运行很卡,我的代码效率海水很差啊。

#ifndef DWIDGET_H
#define DWIDGET_H
#include "xBasic.h"
#include <d3d11.h>
#include <DirectXMath.h>
#include "DPainter.h"
#include <QWidget>
#include <stack> class DPainter; class DWidget : public QWidget
{
Q_OBJECT public:
DWidget(QWidget *parent = nullptr);
~DWidget();
void rotateX();
void rotateY();
void rotateZ(); protected:
virtual void paintEvent(QPaintEvent *event);
virtual void resizeEvent(QResizeEvent *event);
void mousePressEvent(QMouseEvent *event);
virtual QPaintEngine *paintEngine() const { return nullptr; } private:
void updateWVP();
void initializeD3D();
void pushWorldMatrix();
void multipyWorldMatrix(DirectX::XMMATRIX *matrix);
void popWorldMatrix();
void worldMatrixIdentity();
void setCurrentWorldMatrix(DirectX::XMMATRIX *matrix); std::stack<XMFLOAT4X4> worldStack;
DPainter *d3dPainter;
HWND hwnd; ID3D11Device *device;
ID3D11DeviceContext *context;
IDXGISwapChain *swapChain;
ID3D11RenderTargetView *renderTargetView;
ID3D11VertexShader *VS;
ID3D11PixelShader *PS;
ID3D10Blob *VS_Buffer;
ID3D10Blob *PS_Buffer;
ID3D11Buffer *constantBuffer;
ID3D11InputLayout *vertexLayout;
ID3D11Buffer *worldBuffer;
ID3D11Buffer *viewBuffer;
ID3D11Buffer *projectionBuffer;
ID3D11DepthStencilView *depthStencilView;
ID3D11Texture2D *depthStencilBuffer;
ID3D11DepthStencilState *depthStencilState; XMFLOAT4X4 world;
XMFLOAT4X4 view;
XMFLOAT4X4 projection;
XMFLOAT4 eye;
XMFLOAT4 target;
XMFLOAT4 up;
CPerObject WVP; const D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", , DXGI_FORMAT_R32G32B32_FLOAT, , , D3D11_INPUT_PER_VERTEX_DATA, },
{ "COLOR", , DXGI_FORMAT_R32G32B32A32_FLOAT, , , D3D11_INPUT_PER_VERTEX_DATA, },
};
int numElements = ;
}; #endif // DWIDGET_H

// cpp文件

#include "DWidget.h"
#include <qevent.h>
#include "GeometryProvider.h" ID3D11Buffer *boolBuffer;
ID3D11DepthStencilView* pDSV;
struct ABCD
{
bool a;
}isT; ID3D11Buffer *cylinderVertexBuffer;
ID3D11Buffer *cylinderIndexBuffer; DWidget::DWidget(QWidget *parent)
: QWidget(parent)
{
setAttribute(Qt::WA_PaintOnScreen, true);
setAttribute(Qt::WA_NativeWindow, true);
setAutoFillBackground(false);
setFocusPolicy(Qt::StrongFocus);
hwnd = (HWND)winId();
initializeD3D();
depthStencilBuffer = nullptr;
depthStencilView = nullptr;
d3dPainter = new DPainter;
d3dPainter->context = context;
d3dPainter->device = device;
d3dPainter->createSphere(, );
} DWidget::~DWidget()
{
context->Release();
device->Release();
} void DWidget::rotateX()
{
XMMATRIX tmpWord;// = XMLoadFloat4x4(&world);
XMVECTOR anx = XMVectorSet(, , , );
tmpWord = XMMatrixRotationAxis(anx, 0.05);
multipyWorldMatrix(&tmpWord);
update();
} void DWidget::rotateY()
{
XMMATRIX tmpWord;// = XMLoadFloat4x4(&world);
XMVECTOR anx = XMVectorSet(, , , );
tmpWord = XMMatrixRotationAxis(anx, 0.05);
multipyWorldMatrix(&tmpWord);
update();
} void DWidget::rotateZ()
{
XMMATRIX tmpWord;
XMVECTOR anx = XMVectorSet(, , , );
tmpWord = XMMatrixRotationAxis(anx, 0.01);
multipyWorldMatrix(&tmpWord);
update();
} void DWidget::paintEvent(QPaintEvent * event)
{
FLOAT bgColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
context->ClearRenderTargetView(renderTargetView, bgColor);
context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0.0f); {
pushWorldMatrix();
multipyWorldMatrix(&XMMatrixScaling(0.14, 0.14, 0.14));
multipyWorldMatrix(&XMMatrixTranslation(-, -, -)); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(Vertex);
UINT offset = ;
context->IASetVertexBuffers(, , &cylinderVertexBuffer, &stride, &offset);
context->IASetIndexBuffer(cylinderIndexBuffer, DXGI_FORMAT_R32_UINT, );
context->DrawIndexed(, , ); {
pushWorldMatrix();
multipyWorldMatrix(&XMMatrixTranslation(, , ));
multipyWorldMatrix(&XMMatrixScaling(0.1, 0.1, 0.1)); d3dPainter->drawSphere(); popWorldMatrix();
} for (int i = ; i < ; i++)
{
for (int j = ; j <= ; j++)
{
for (int k = ; k < ; k++)
{
pushWorldMatrix();
multipyWorldMatrix(&XMMatrixTranslation(i, j, k));
multipyWorldMatrix(&XMMatrixScaling(0.1, 0.1, 0.1));
d3dPainter->drawSphere();
popWorldMatrix(); }
}
} popWorldMatrix();
}//d3dPainter->drawSphere(); swapChain->Present(, ); } void DWidget::updateWVP()
{
XMStoreFloat4x4(&WVP.view, XMMatrixTranspose(XMLoadFloat4x4(&view)));
XMStoreFloat4x4(&WVP.world, XMMatrixTranspose(XMLoadFloat4x4(&world)));
XMStoreFloat4x4(&WVP.projection, XMMatrixTranspose(XMLoadFloat4x4(&projection)));
context->UpdateSubresource(constantBuffer, , NULL, &WVP, , );
context->VSSetConstantBuffers(, , &constantBuffer);
::isT.a = ;
} void DWidget::resizeEvent(QResizeEvent * event)
{
int width = this->width();
int height = this->height();
::xBasicChangeSize(device, context, swapChain, &renderTargetView, width, height); D3D11_TEXTURE2D_DESC depthStencilBufferDesc;
ZeroMemory(&depthStencilBufferDesc, sizeof(D3D11_TEXTURE2D_DESC));
depthStencilBufferDesc.Width = width;
depthStencilBufferDesc.Height = height;
depthStencilBufferDesc.MipLevels = ;
depthStencilBufferDesc.ArraySize = ;
depthStencilBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilBufferDesc.SampleDesc.Count = ;
depthStencilBufferDesc.SampleDesc.Quality = ;
depthStencilBufferDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilBufferDesc.CPUAccessFlags = ;
depthStencilBufferDesc.MiscFlags = ; device->CreateTexture2D(&depthStencilBufferDesc, NULL, &depthStencilBuffer); D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
ZeroMemory(&depthStencilDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState); context->OMSetDepthStencilState(depthStencilState, ); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
ZeroMemory(&depthStencilViewDesc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = ; device->CreateDepthStencilView(depthStencilBuffer, &depthStencilViewDesc, &depthStencilView);
context->OMSetRenderTargets(, &renderTargetView, depthStencilView); XMMATRIX tmpProjection = XMMatrixPerspectiveFovLH(XM_PIDIV2 / , (float)width / (float)height, 0.01f, 100.0f);
XMStoreFloat4x4(&projection, tmpProjection);
} void DWidget::mousePressEvent(QMouseEvent * event)
{
} void DWidget::initializeD3D()
{
::xBasicInitializeDirectX11(hwnd, &swapChain, &device, &context, &renderTargetView);
::xBasicCreateShader(device, context, L"Effects.fx", &VS_Buffer, &PS_Buffer, &VS, &PS);
::xBasicCreateBuffer(device, D3D11_BIND_CONSTANT_BUFFER, sizeof(CPerObject), &WVP, &constantBuffer);
::xBasicCreateBuffer(device, D3D11_BIND_CONSTANT_BUFFER, , &::isT, &::boolBuffer); XMMATRIX tmpWorld = XMMatrixScaling(0.1, 0.1, 0.1) *XMMatrixTranslation( * , * , );;
XMStoreFloat4x4(&world, tmpWorld); XMVECTOR eye = XMVectorSet(0.0f, 0.0f, -1.0f, 0.0f);
XMVECTOR at = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMStoreFloat4x4(&view, XMMatrixLookAtLH(eye, at, up)); //Create the Input Layout
device->CreateInputLayout(layout, , VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), &vertexLayout); //Set the Input Layout
context->IASetInputLayout(vertexLayout); GeometryProvider provider;
std::vector<Vertex> vertices;
std::vector<UINT> indices;
GeometryProvider::MeshData data;
provider.createCylinder(data, );
for (size_t i = ; i < data.vertices.size(); i++)
{
Vertex tmpV;
tmpV.pos = data.vertices[i].position;
tmpV.color = XMFLOAT4(rand() % , rand() % , rand() % , );
vertices.push_back(tmpV);
} for (size_t i = ; i < data.indices.size(); i++)
{
indices.push_back(data.indices[i]);
} ::xBasicCreateBuffer(device, D3D11_BIND_VERTEX_BUFFER, vertices.size() * sizeof(Vertex), &vertices[], &cylinderVertexBuffer);
::xBasicCreateBuffer(device, D3D11_BIND_INDEX_BUFFER, indices.size() * sizeof(UINT), &indices[], &cylinderIndexBuffer);
} void DWidget::pushWorldMatrix()
{
if (worldStack.empty())
{
worldMatrixIdentity();
}
worldStack.push(worldStack.top());
} void DWidget::multipyWorldMatrix(DirectX::XMMATRIX * matrix)
{
if (worldStack.empty())
{
worldMatrixIdentity();
} XMMATRIX aMatrix = XMLoadFloat4x4(&worldStack.top());
XMMATRIX ansMatrix = *matrix * aMatrix;
XMStoreFloat4x4(&worldStack.top(), ansMatrix); world = worldStack.top();
updateWVP();
} void DWidget::popWorldMatrix()
{
worldStack.pop(); world = worldStack.top(); updateWVP();
} void DWidget::worldMatrixIdentity()
{
while (!worldStack.empty())
{
worldStack.pop();
} worldStack.push(XMFLOAT4X4()); XMStoreFloat4x4(&worldStack.top(), XMMatrixIdentity()); world = worldStack.top();
updateWVP();
} void DWidget::setCurrentWorldMatrix(DirectX::XMMATRIX * matrix)
{
if (worldStack.empty())
{
worldMatrixIdentity();
} XMMATRIX aMatrix = XMLoadFloat4x4(&worldStack.top());
XMMATRIX ansMatrix = *matrix * aMatrix;
XMStoreFloat4x4(&worldStack.top(), ansMatrix); world = worldStack.top();
updateWVP();
}

有些很奇葩的写法就不管了。