使用Mip Map

使用mipmap,用于解决 纹理过大 (屏幕像素对应到纹理的区域包含大量纹素,此时采样结果无法代表整体颜色)闪烁的问题

//ShaderResourceView.h
#pragma once

#include "Bindable.h"
#include <string>
#include <vector>
#include <d3dcompiler.h> //D3DReflect


class ShaderResourceView :public Bindable
{
protected:
	vector<ComPtr<ID3D11ShaderResourceView>> pShaderViews;
	UINT slot;
	vector<wstring> FilesBeenUsed;	// 第一个file对应的图片 放在 register(t slot), 第二个图片 放在 register(t slot+1)


	//构造:输入 可变参数 - 文件名:
public:
	template<typename ...Args>
	ShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, Args... FileNames);
private:
	template<typename ...Args>
	void DealWithMutiArgus(wstring fileName_BitMap, Args... FileNames);
	void DealWithMutiArgus();

	//构造:输入某个VSBlob或PSblob
public:
	ShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, ComPtr<ID3DBlob> blob);
	UINT GetSRVNum();
	void SetFileName(wstring fileName_BitMap, UINT fileArrayIndex);


public:
	virtual void Load() override;
	virtual void Bind() override = 0;
};

template<typename ...Args>
ShaderResourceView::ShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, Args... FileNames)
	:Bindable(gfx), slot{slot}
{
	DealWithMutiArgus(FileNames...);
}
template<typename ...Args>
void ShaderResourceView::DealWithMutiArgus(wstring fileName_BitMap, Args... FileNames)
{
	FilesBeenUsed.push_back(fileName_BitMap);
	DealWithMutiArgus(FileNames...);
}




//子类***********


class VSShaderResourceView :public ShaderResourceView
{
public:
	template<typename ...Args>
	VSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, Args... FileNames);
	VSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, ComPtr<ID3DBlob> blob);

	virtual void Load() override;
	virtual void Bind() override;
};

template<typename ...Args>
VSShaderResourceView::VSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, Args... FileNames)
	:ShaderResourceView(gfx, slot, FileNames...)
{

}

class PSShaderResourceView :public ShaderResourceView
{
public:
	template<typename ...Args>
	PSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, Args... FileNames);
	PSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, ComPtr<ID3DBlob> blob);

	virtual void Load() override;
	virtual void Bind() override;
};

template<typename ...Args>
PSShaderResourceView::PSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, Args... FileNames)
	:ShaderResourceView(gfx, slot, FileNames...)
{

}

//ShaderResourceView.cpp

#include "ShaderResourceView.h"
#include <gdiplus.h>


void ShaderResourceView::DealWithMutiArgus()
{
	return;
}

ShaderResourceView::ShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, ComPtr<ID3DBlob> blob)
	:Bindable(gfx), slot{slot}
{
	UINT sourceViewNum;	//Shader 用到的 SRV 的数量

	ComPtr<ID3D11ShaderReflection> pShaderReflect;
	D3DReflect(blob->GetBufferPointer(), blob->GetBufferSize(), __uuidof(ID3D11ShaderReflection), &pShaderReflect);
	D3D11_SHADER_DESC shaderDesc;
	pShaderReflect->GetDesc(&shaderDesc);
	for (int i = 0; i < shaderDesc.BoundResources; i++)//获取到SRV的数量
	{
		FilesBeenUsed.push_back(wstring{});
	}
}

UINT ShaderResourceView::GetSRVNum()
{
	return FilesBeenUsed.size();
}

void ShaderResourceView::SetFileName(wstring fileName_BitMap, UINT fileArrayIndex)
{
	if (fileArrayIndex > FilesBeenUsed.size())
		return;
	FilesBeenUsed[fileArrayIndex] = fileName_BitMap;
}

void ShaderResourceView::Load()
{
	vector<ComPtr<ID3D11Texture2D> > texs;
	for(auto i : FilesBeenUsed)
	{
		ULONG_PTR token;
		Gdiplus::GdiplusStartupInput input{};
		Gdiplus::GdiplusStartup(&token, &input, NULL);
		Gdiplus::Bitmap tex{ i.c_str() };
		struct mColor
		{
			unsigned char r, g, b, a;
		};
		std::vector<mColor> texPixelArray{ tex.GetWidth() * tex.GetHeight(),mColor{} };
		Gdiplus::Color temp;
		for (unsigned int i = 0; i < tex.GetHeight(); ++i)
		{
			for (unsigned 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 =  0u;															//一整套mipmap
		t2dDesc.ArraySize = 1u;
		t2dDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		t2dDesc.SampleDesc.Count = 1u;
		t2dDesc.SampleDesc.Quality = 0u;
		t2dDesc.Usage = D3D11_USAGE::D3D11_USAGE_DEFAULT;
		t2dDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET;
		t2dDesc.MiscFlags = D3D11_RESOURCE_MISC_FLAG::D3D11_RESOURCE_MISC_GENERATE_MIPS;	//使用 mipmap
		t2dDesc.CPUAccessFlags = 0u;
		//D3D11_SUBRESOURCE_DATA initiaTex{};
		//initiaTex.pSysMem = texPixelArray.data();
		//initiaTex.SysMemPitch = sizeof(mColor) * tex.GetWidth();							//在创建mipTex,不再使用SubresourceData初始化
		ComPtr<ID3D11Texture2D> pTexture;

		gfx->GetDevice()->CreateTexture2D(&t2dDesc, /*&initiaTex*/nullptr, &pTexture);
		gfx->GetContext()->UpdateSubresource(pTexture.Get(), 0u, nullptr, texPixelArray.data(), sizeof(mColor)* tex.GetWidth(), 0u);//创建Tex2D后,再初始化


		//Gdiplus::GdiplusShutdown(token);

		texs.push_back(pTexture);
	}

	if (FilesBeenUsed.empty())
	{
		pShaderViews.clear();
	}
	else
	{
		for (auto i : texs)
		{
			ComPtr<ID3D11ShaderResourceView> temp;
			D3D11_SHADER_RESOURCE_VIEW_DESC shaderViewDesc;
			shaderViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
			shaderViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			shaderViewDesc.Texture2D.MostDetailedMip = 0u;								//要使用的最详细的map
			shaderViewDesc.Texture2D.MipLevels =  -1;									//-1表示:从 MostDetailedMip到最大的mip级别的 map,都可以用。
			gfx->GetDevice()->CreateShaderResourceView(i.Get(), &shaderViewDesc, &temp);
			gfx->GetContext()->GenerateMips(temp.Get());

			pShaderViews.push_back(temp);
		}
	}
}










VSShaderResourceView::VSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, ComPtr<ID3DBlob> blob)
	:ShaderResourceView(gfx, slot, blob)
{

}

void VSShaderResourceView::Load()
{
	ShaderResourceView::Load();
}

void VSShaderResourceView::Bind()
{
	ID3D11ShaderResourceView** viewsArray = new ID3D11ShaderResourceView * [pShaderViews.size()];
	for (int i = 0; i < pShaderViews.size(); i++)
	{
		viewsArray[i] = pShaderViews[i].Get();
	}
	gfx->GetContext()->VSSetShaderResources(slot, pShaderViews.size(), viewsArray);
	delete[] viewsArray;

}


PSShaderResourceView::PSShaderResourceView(shared_ptr<Graphics> gfx, UINT slot, ComPtr<ID3DBlob> blob)
	:ShaderResourceView(gfx, slot, blob)

{

}

void PSShaderResourceView::Load()
{
	ShaderResourceView::Load();
}

void PSShaderResourceView::Bind()
{
	ID3D11ShaderResourceView** viewsArray = new ID3D11ShaderResourceView * [pShaderViews.size()];
	for (int i = 0; i < pShaderViews.size(); i++)
	{
		viewsArray[i] = pShaderViews[i].Get();
	}
	gfx->GetContext()->PSSetShaderResources(slot, pShaderViews.size(), viewsArray);
	delete[] viewsArray;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值