DirectX 11 加载纹理和模型

加载纹理

使用 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《DirectX 11 3D 游戏编程介绍》是一本探索使用DirectX 11进行3D游戏编程的入门指南。作者在书中详细介绍了使用DirectX 11构建高性能、交互性强的3D游戏的基本原理和技术。 这本书首先向读者介绍了DirectX 11的基本知识,包括如何安装和配置DirectX 11开发环境,以及如何使用DirectX 11的各种工具和函数编写3D游戏程序。接着,作者解释了3D计算机图形学的基础知识,如顶点和像素着色器、纹理贴图和辐射衰减等。通过这些基础知识的介绍,读者可以快速掌握构建3D游戏所需的关键技术。 在介绍了基本概念之后,书中详细介绍了使用DirectX 11来创建各种类型的3D游戏元素,如物体、相机、光照等。通过丰富的示例代码和图文并茂的解释,读者可以了解到如何创建和渲染一个真实感十足的3D场景。 除了基本的游戏元素之外,本书还涵盖了一些高级主题,如阴影、环境映射以及粒子系统等。这些高级技术的介绍,使读者能够在游戏中添加更多的特效和细节,提高游戏的表现力和吸引力。 总之,《DirectX 11 3D 游戏编程介绍》是一本全面而深入的指南,适合对DirectX 11编程感兴趣的读者。通过阅读本书,读者可以快速掌握使用DirectX 11构建3D游戏所需的基本知识和技术,为自己的游戏编程之路打下坚实的基础。 ### 回答2: 《DirectX 11 3D游戏编程入门》是一本介绍使用DirectX 11进行3D游戏编程的书籍。这本书深入探讨了如何使用DirectX 11框架来创建高质量的游戏图形和动画效果。 首先,书中介绍了DirectX 11的基本原理和概念,包括DirectX API、3D渲染管线以及基本的数学知识。读者将学习如何使用DirectX 11的各个组件来创建并控制游戏世界的各个方面,包括场景、模型、光照、纹理和动画等。 其次,书中还涵盖了一些高级主题,如几何处理、阴影技术和物理仿真。通过学习这些技术,读者将能够创建更加真实和逼真的游戏效果。 除了理论知识,这本书还提供了大量的实际编程示例和练习,帮助读者巩固所学的内容。读者将通过实践性的编程项目来运用所学知识,提高自己的编程能力和理解。书中的示例代码和项目都是使用C++语言编写的,读者需要基本的C++编程知识。 总而言之,《DirectX 11 3D游戏编程入门》是一本全面介绍使用DirectX 11进行游戏编程的教材。无论是对于初学者还是已有一定游戏开发经验的读者来说,都是一本不可或缺的学习资源。通过学习这本书,读者将能够掌握使用DirectX 11创建引人入胜的3D游戏的技能。 ### 回答3: 《DirectX 11 3D游戏编程入门》是一本介绍使用DirectX 11进行3D游戏编程的入门教材。DirectX 11是微软的一个图形编程接口,它提供了丰富的功能和工具,方便开发者实现高性能、逼真的图形效果。 本书首先介绍了计算机图形学的基础知识,如顶点、三角形、光照、材质等。然后详细介绍了DirectX 11的各个组件和功能,如绘制2D图形、创建3D模型、使用着色器编程、应用纹理和光照效果等。 书中通过一系列具体的示例代码和案例,手把手地教读者如何使用DirectX 11进行游戏编程。读者可以学会如何加载模型、设置相机视角、实现场景渲染等基本功能。同时,本书还介绍了一些高级的特效技术,如阴影和反射效果的实现。 在学习过程中,本书鼓励读者动手实践,通过编写自己的游戏项目来巩固所学知识。此外,本书还提供了一些调试技巧和最佳实践,帮助读者解决常见的问题,并编写出高效、稳定的游戏程序。 总之,《DirectX 11 3D游戏编程入门》是一本系统、全面介绍DirectX 11游戏编程的教材,适合有一定编程基础和对3D游戏开发感兴趣的读者阅读。通过学习本书,读者可以了解DirectX 11的核心概念和基本功能,掌握基于DirectX 11的3D游戏开发技巧,为进一步深入学习和开发打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值