加载纹理
使用 gdiplus::BitMap
#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib") //都在 window sdk中
//读取文件到指定内存
//Pixel Shader Texture
ULONG_PTR token;
Gdiplus::GdiplusStartupInput input{};
Gdiplus::GdiplusStartup(&token,&input,NULL);
Gdiplus::Bitmap tex{ L"Image\\cube.png" };
struct mColor
{
unsigned char r, g, b, a;
};
std::vector<mColor> texPixelArray{ tex.GetWidth() * tex.GetHeight(),mColor{} };
Gdiplus::Color temp;
for (int i = 0; i < tex.GetHeight(); ++i)
{
for (int j = 0; j < tex.GetWidth(); ++j)
{
tex.GetPixel(j, i, &temp);
texPixelArray[tex.GetWidth() * i + j].r = temp.GetR();
texPixelArray[tex.GetWidth() * i + j].g = temp.GetG();
texPixelArray[tex.GetWidth() * i + j].b = temp.GetB();
texPixelArray[tex.GetWidth() * i + j].a = temp.GetA();
}
}
//创建资源
D3D11_TEXTURE2D_DESC t2dDesc{};
t2dDesc.Width = tex.GetWidth();
t2dDesc.Height = tex.GetHeight();
t2dDesc.MipLevels = 1u;
t2dDesc.ArraySize = 1u;
t2dDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
t2dDesc.SampleDesc.Count = 1u;
t2dDesc.SampleDesc.Quality = 0u;
t2dDesc.Usage = D3D11_USAGE_DEFAULT;
t2dDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_SHADER_RESOURCE;
t2dDesc.MiscFlags = 0u;
t2dDesc.CPUAccessFlags = 0u;
D3D11_SUBRESOURCE_DATA initiaTex{};
initiaTex.pSysMem = texPixelArray.data();
initiaTex.SysMemPitch = sizeof(mColor) * tex.GetWidth();
ComPtr<ID3D11Texture2D> pTexture;
gfx->pDevice->CreateTexture2D(&t2dDesc,&initiaTex,&pTexture);
D3D11_SHADER_RESOURCE_VIEW_DESC shaderViewDesc;
shaderViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
shaderViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderViewDesc.Texture2D.MostDetailedMip = 0u;
shaderViewDesc.Texture2D.MipLevels = 1u;
gfx->pDevice->CreateShaderResourceView(pTexture.Get(),&shaderViewDesc,&pShaderview);
//最后绑定
gfx->pContext->PSSetShaderResources(0u, 1u,pShaderview.GetAddressOf());
要先调用这个函数 GdiplusStartupInput::GdiplusStartupInput Microsoft Docs
//Gdiplus::GdiplusShutdown(token);我最后使用这个函数会出错,可能是析构两次
//VertexShader.hlsl
Texture2D _MainTex:register(t0);
SamplerState defaultState
{
};
struct v2f
{
float2 uv:TEXCOORD;
float4 pos:SV_POSITION;
};
float4 main(v2f i) : SV_TARGET
{
return _MainTex.Sample(defaultState,i.uv);
}
加载模型
使用autodesk FBX SDK
先安装 FBX Software Developer Kit 2020.3.1 | Autodesk Developer Network
我安装的版本:FBX SDK 2020.3.1 VS2019
配置,打开项目属性
所有模式和平台
1
2 头文件
3 lib文件
4 C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.1\lib\vs2019\x64\debug\libfbxsdk.dll
文件复制到C:\Users\ [Name] \source\repos\ [ProjectName] \ [ProjectName] 下
#include <fbxsdk.h>
//#pragma comment(lib,"fbxsdk.lib") 如果 项目属性-link中包含该lib 则不用这句
struct VertexInfo
{
DirectX::XMFLOAT3 vertex;
DirectX::XMFLOAT3 normal;
DirectX::XMFLOAT2 texcoord;
};
std::vector<VertexInfo> vertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> pVertexBuffer;
UINT VBstrides[1];
UINT VBoffsets[1];
//vertex buffer
FbxManager* g_pFbxSdkManager = nullptr;
if (g_pFbxSdkManager == nullptr)
{
g_pFbxSdkManager = FbxManager::Create();
FbxIOSettings* pIOsettings = FbxIOSettings::Create(g_pFbxSdkManager, IOSROOT);
g_pFbxSdkManager->SetIOSettings(pIOsettings);
}
FbxImporter* pImporter = FbxImporter::Create(g_pFbxSdkManager, "");
FbxScene* pFbxScene = FbxScene::Create(g_pFbxSdkManager, "");
bool bSuccess = pImporter->Initialize("Modle\\OneCube.fbx", -1, g_pFbxSdkManager->GetIOSettings());
if (!bSuccess) return;
bSuccess = pImporter->Import(pFbxScene);
if (!bSuccess) return;
pImporter->Destroy();
FbxNode* pFbxRootNode = pFbxScene->GetRootNode();
if (pFbxRootNode)
{
for (int i = 0; i < pFbxRootNode->GetChildCount(); i++)
{
FbxNode* pFbxChildNode = pFbxRootNode->GetChild(i);
if (pFbxChildNode->GetNodeAttribute() == NULL)
continue;
FbxNodeAttribute::EType AttributeType = pFbxChildNode->GetNodeAttribute()->GetAttributeType();
if (AttributeType != FbxNodeAttribute::eMesh)
continue;
FbxMesh* pMesh = pFbxChildNode->GetMesh(); //拿到 第一个 mesh的 子节点
FbxVector4* pVertices = pMesh->GetControlPoints();
FbxArray<FbxVector4> pNormal;
pMesh->GetPolygonVertexNormals(pNormal);
FbxArray<FbxVector2> pUVs;
FbxStringList UVSetName;
pMesh->GetUVSetNames(UVSetName);
const char* UVset1Name = (const char*)UVSetName[0];
pMesh->GetPolygonVertexUVs(NULL, pUVs, NULL);
for (int j = 0; j < pMesh->GetPolygonCount(); j++)
{
int iNumVertices = pMesh->GetPolygonSize(j);
assert(iNumVertices == 3);
for (int k = 0; k < iNumVertices; k++) {
int iControlPointIndex = pMesh->GetPolygonVertex(j, k);
FbxVector4 theVertexNormal;
pMesh->GetPolygonVertexNormal(j, k, theVertexNormal);
FbxVector2 theUV;
bool isUnmapped;
pMesh->GetPolygonVertexUV(j, k, UVset1Name, theUV, isUnmapped);
VertexInfo oneVertexInfo;
oneVertexInfo.vertex.x = pVertices[iControlPointIndex][0];
oneVertexInfo.vertex.y = pVertices[iControlPointIndex][1];
oneVertexInfo.vertex.z = pVertices[iControlPointIndex][2];
oneVertexInfo.normal.x = theVertexNormal[0];
oneVertexInfo.normal.y = theVertexNormal[1];
oneVertexInfo.normal.z = theVertexNormal[2];
oneVertexInfo.texcoord.x = theUV[0];
oneVertexInfo.texcoord.y = theUV[1];
vertexBuffer.push_back(oneVertexInfo);
}
}
}
}
D3D11_BUFFER_DESC bufDesc{};
bufDesc.ByteWidth = sizeof(VertexInfo) * vertexBuffer.size();
bufDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_VERTEX_BUFFER;
bufDesc.CPUAccessFlags = 0u;
bufDesc.MiscFlags = 0u;
bufDesc.StructureByteStride = sizeof(VertexInfo);
bufDesc.Usage = D3D11_USAGE_DEFAULT;
D3D11_SUBRESOURCE_DATA initiaVertexBuffer{};
initiaVertexBuffer.pSysMem = vertexBuffer.data();
gfx->pDevice->CreateBuffer(&bufDesc, &initiaVertexBuffer, &pVertexBuffer);
VBstrides[0] = (UINT)sizeof(VertexInfo);
VBoffsets[0] = 0u;
上面的代码参考 DirectX Part 4: Loading FBX Models | The walkerb.net Blog