D3D11渲染函数调用device_draw
2024-08-01
22
0
渲染的必要过程
- gs_draw(GS_TRISTRIP, 0, 0);
- void device_draw
device_draw流程如下:
void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode,
uint32_t start_vert, uint32_t num_verts)
{
device->FlushOutputViews();//设置渲染目标OMSetRenderTargets
gs_effect_t *effect = gs_get_effect();
if (effect)
gs_effect_update_params(effect);
device->LoadVertexBufferData();
device->UpdateBlendState();
device->UpdateRasterState();
device->UpdateZStencilState();
device->UpdateViewProjMatrix();
device->curVertexShader->UploadParams();
device->curPixelShader->UploadParams();
D3D11_PRIMITIVE_TOPOLOGY newTopology = ConvertGSTopology(draw_mode);
if (device->curToplogy != newTopology)
{
device->context->IASetPrimitiveTopology(newTopology);// 设置顶点元的组合模式
device->curToplogy = newTopology;
}
//顶点绘制(0,4)
num_verts = (uint32_t)device->curVertexBuffer->numVerts;
device->context->Draw(num_verts, start_vert);
}
设置渲染目标
设置渲染目标功能是由函数device->FlushOutputViews()实现的,其核心是调用OMSetRenderTargets。这里看只有一个渲染视图和深度视图
void gs_device::FlushOutputViews()
{
if (curFramebufferInvalidate)
{
ID3D11RenderTargetView *rtv = nullptr;
if (curRenderTarget)
{
const int i = curRenderSide;
rtv = curFramebufferSrgb ? curRenderTarget->renderTargetLinear[i].Get()
:curRenderTarget->renderTarget[i].Get();
if (!rtv)
{
blog(LOG_ERROR,"device_draw (D3D11): texture is not a render target");
return;
}
}
ID3D11DepthStencilView *dsv = nullptr;
if (curZStencilBuffer)
dsv = curZStencilBuffer->view;
context->OMSetRenderTargets(1, &rtv, dsv);
curFramebufferInvalidate = false;
}
}
而当前的渲染目标是通过函数device_set_render_target实现的。
这里一个比较重要的是会根据curFramebufferSrgb来选择到底是使用那个当前渲染视图中的那一个。该标识是通过函数
gs_enable_framebuffer_srgb(bool enable)来决定的。