qt+gxdi+ffmpeg远程控制(四)

qt+gxdi+ffmpeg远程控制(三)

针对上篇提到的,渲染过程中有很多对象不需要每次都设置一遍,今天测试了一下,确实是这样。

另外我记得看采样器的时候有提到,采样器可以做缩放的,之前一直不成功,原来是viewPort的原因,忘了当初为啥要这么写了...

那么最新的逻辑是,顶点着色器,像素着色器和ShaderResourceView都在初始化阶段创建并设置进管线里,之后用copyResource将资源拷贝到m_outputImage里既可。

const Vertex vertices[] = {
		{-1,	1,	0,	0,	0},
		{1,		1,	0,	1,	0},
		{1,		-1,	0,	1,	1},
		{-1,	-1,	0,	0,	1},
	};
	const UINT16 indices[] = {
		0,1,2, 0,2,3
	};

	D3D11_BUFFER_DESC bd = {};
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.ByteWidth = sizeof(vertices);
	bd.StructureByteStride = sizeof(Vertex);
	D3D11_SUBRESOURCE_DATA sd = {};
	sd.pSysMem = vertices;

	this->m_device->CreateBuffer(&bd, &sd, &this->m_pVertexBuffer);

	D3D11_BUFFER_DESC ibd = {};
	ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	ibd.ByteWidth = sizeof(indices);
	ibd.StructureByteStride = sizeof(UINT16);
	D3D11_SUBRESOURCE_DATA isd = {};
	isd.pSysMem = indices;

	this->m_device->CreateBuffer(&ibd, &isd, &this->m_pIndexBuffer);

    // 新增: 初始化方法中创建Texture与shaderResourceView
	D3D11_TEXTURE2D_DESC tdesc;
	ZeroMemory(&tdesc, sizeof(D3D11_TEXTURE2D_DESC));
	tdesc.Width = this->width();
	tdesc.Height = this->height();
	tdesc.MipLevels = 1;
	tdesc.ArraySize = 1;
	tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	tdesc.SampleDesc.Count = 1;
	tdesc.SampleDesc.Quality = 0;
	tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	tdesc.CPUAccessFlags = 0;
	tdesc.MiscFlags = 0;
	hr = this->m_device->CreateTexture2D(&tdesc, nullptr, &this->m_outputImage);
	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = CD3D11_SHADER_RESOURCE_VIEW_DESC(
		this->m_outputImage,
		D3D11_SRV_DIMENSION_TEXTURE2D,
		DXGI_FORMAT_B8G8R8A8_UNORM
	);
	hr = this->m_device->CreateShaderResourceView(this->m_outputImage, &srvDesc, &this->m_srv);

	// 顶点着色器
	D3D11_INPUT_ELEMENT_DESC ied[] = {
		{"POSITION", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
		{"TEXCOORD", 0, DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
	};
	hr = this->m_device->CreateInputLayout(ied, std::size(ied), g_main, sizeof(g_main), &this->m_pInputLayout);
	hr = this->m_device->CreateVertexShader(g_main, sizeof(g_main), nullptr, &this->m_pVertexShader);


	D3D11_SAMPLER_DESC samplerDesc = {};
	samplerDesc.Filter = D3D11_FILTER::D3D11_FILTER_ANISOTROPIC;
	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.MaxAnisotropy = 16;

	hr = this->m_device->CreateSamplerState(&samplerDesc, &this->m_pSampler);

	// 像素着色器
	hr = this->m_device->CreatePixelShader(g_main_PS, sizeof(g_main_PS), nullptr, &this->m_pPixelShader);
	hr = S_OK;
    
    // 新增: 将原来渲染里的设置着色器、缓存那些移到初始化方法中
	UINT stride = sizeof(Vertex);
	UINT offset = 0u;
	this->m_context->IASetVertexBuffers(0, 1, &this->m_pVertexBuffer, &stride, &offset);
	this->m_context->IASetIndexBuffer(this->m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
	this->m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	this->m_context->IASetInputLayout(this->m_pInputLayout);
	this->m_context->VSSetShader(this->m_pVertexShader, 0, 0);

	this->m_context->PSSetShader(this->m_pPixelShader, 0, 0);
	ID3D11ShaderResourceView* srvs[] = { this->m_srv };
	this->m_context->PSSetShaderResources(0, 1, srvs);

	ID3D11SamplerState* samplers[] = { this->m_pSampler };
	this->m_context->PSSetSamplers(0, 1, samplers);

渲染中只需要进行绘制

    const UINT16 indices[] = {
		0,1,2, 0,2,3
	};
	auto indicesSize = std::size(indices);
	this->m_context->DrawIndexed(indicesSize, 0, 0);

	this->m_swapChain->Present(0, 0);

这里直接用copyResource将资源拷贝到我们之前创建的texture里

void copy_to_render_texture(uint8_t* _buffer, ID3D11Texture2D* _texture)
{
	if (this->m_outputImage != nullptr) {
		this->m_context->CopyResource(this->m_outputImage, _texture);
	}
}

每次渲染就不需要像之前那样创建那么多资源了。

TODO

下一步优化代码结构,与渲染相关的部分移到窗口类中,通过纹理共享句柄进行跨设备拷贝。也就是在创建纹理时将D3D11_TEXTURE2D_DESC的MiscFlags设置为D3D11_RESOURCE_MISC_SHARED。

D3D11_RESOURCE_MISC_SHARED
值: 0x2L
启用两个或多个 Direct3D 设备之间的资源数据共享。 唯一可以共享的资源是 2D 非误入式纹理。


D3D11_RESOURCE_MISC_SHARED 和 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX 是相互排斥的。


WARP 和 REF 设备不支持共享资源。
如果尝试在 WARP 或 REF 设备上使用此标志创建资源,create 方法将返回 E_OUTOFMEMORY 错误代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值