| 327 | } |
| 328 | |
| 329 | void SpriteRenderer::RenderBatch(ID3D11ShaderResourceView* texture, |
| 330 | const SpriteDrawData* drawData, |
| 331 | uint64 numSprites) |
| 332 | { |
| 333 | _ASSERT(context); |
| 334 | _ASSERT(initialized); |
| 335 | |
| 336 | D3DPERF_BeginEvent(0xFFFFFFFF, L"SpriteRenderer RenderBatch"); |
| 337 | |
| 338 | // Set the vertex shader |
| 339 | context->VSSetShader(vertexShaderInstanced, nullptr, 0); |
| 340 | |
| 341 | // Set the input layout |
| 342 | context->IASetInputLayout(inputLayoutInstanced); |
| 343 | |
| 344 | // Set per-batch constants |
| 345 | D3D11_TEXTURE2D_DESC desc = SetPerBatchData(texture); |
| 346 | |
| 347 | // Make sure the draw rects are all valid |
| 348 | for (uint64 i = 0; i < numSprites; ++i) |
| 349 | { |
| 350 | Float4 drawRect = drawData[i].DrawRect; |
| 351 | Assert_(drawRect.x >= 0 && drawRect.x < desc.Width); |
| 352 | Assert_(drawRect.y >= 0 && drawRect.y < desc.Height); |
| 353 | Assert_(drawRect.z > 0 && drawRect.x + drawRect.z <= desc.Width); |
| 354 | Assert_(drawRect.w > 0 && drawRect.y + drawRect.w <= desc.Height); |
| 355 | } |
| 356 | |
| 357 | uint64 numSpritesToDraw = std::min(numSprites, MaxBatchSize); |
| 358 | |
| 359 | // Copy in the instance data |
| 360 | D3D11_MAPPED_SUBRESOURCE mapped; |
| 361 | DXCall(context->Map(instanceDataBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); |
| 362 | CopyMemory(mapped.pData, drawData, static_cast<size_t>(sizeof(SpriteDrawData) * numSpritesToDraw)); |
| 363 | context->Unmap(instanceDataBuffer, 0); |
| 364 | |
| 365 | // Set the constant buffer |
| 366 | ID3D11Buffer* constantBuffers [1] = { vsPerBatchCB }; |
| 367 | context->VSSetConstantBuffers(0, 1, constantBuffers); |
| 368 | |
| 369 | // Set the vertex buffers |
| 370 | UINT strides [2] = { sizeof(SpriteVertex), sizeof(SpriteDrawData) }; |
| 371 | UINT offsets [2] = { 0, 0 }; |
| 372 | ID3D11Buffer* vertexBuffers [2] = { vertexBuffer, instanceDataBuffer }; |
| 373 | context->IASetVertexBuffers(0, 2, vertexBuffers, strides, offsets); |
| 374 | |
| 375 | // Set the texture |
| 376 | context->PSSetShaderResources(0, 1, &texture); |
| 377 | |
| 378 | // Draw |
| 379 | context->DrawIndexedInstanced(6, static_cast<UINT>(numSpritesToDraw), 0, 0, 0); |
| 380 | |
| 381 | D3DPERF_EndEvent(); |
| 382 | |
| 383 | // If there's any left to be rendered, do it recursively |
| 384 | if(numSprites > numSpritesToDraw) |
| 385 | RenderBatch(texture, drawData + numSpritesToDraw, numSprites - numSpritesToDraw); |
| 386 | } |