Examples: DirectX9: resizing vertex and index buffers dynamically (#299)

This commit is contained in:
ocornut 2015-08-13 23:06:11 -06:00
parent ede5956b28
commit 698c7cae85

View File

@ -16,8 +16,8 @@ static INT64 g_TicksPerSecond = 0;
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
static int VERTEX_BUFFER_SIZE = 20000; // TODO: Make buffers smaller and grow dynamically as needed. static LPDIRECT3DTEXTURE9 g_FontTexture = NULL;
static int INDEX_BUFFER_SIZE = 40000; // TODO: Make buffers smaller and grow dynamically as needed. static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct CUSTOMVERTEX struct CUSTOMVERTEX
{ {
@ -32,6 +32,22 @@ struct CUSTOMVERTEX
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
static void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) static void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{ {
// Grow buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
if (g_pVB) g_pVB->Release();
g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
if (g_pd3dDevice->CreateVertexBuffer(g_VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
return;
}
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
{
if (g_pIB) g_pIB->Release();
g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
if (g_pd3dDevice->CreateIndexBuffer(g_IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL) < 0)
return;
}
// Copy and convert all vertices into a single contiguous buffer // Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst; CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_dst; ImDrawIdx* idx_dst;
@ -213,24 +229,24 @@ static void ImGui_ImplDX9_CreateFontsTexture()
io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height, &bytes_per_pixel); io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height, &bytes_per_pixel);
// Create DX9 texture // Create DX9 texture
LPDIRECT3DTEXTURE9 pTexture = NULL; g_FontTexture = NULL;
if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &pTexture) < 0) if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
{ {
IM_ASSERT(0); IM_ASSERT(0);
return; return;
} }
D3DLOCKED_RECT tex_locked_rect; D3DLOCKED_RECT tex_locked_rect;
if (pTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK)
{ {
IM_ASSERT(0); IM_ASSERT(0);
return; return;
} }
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
memcpy((unsigned char *)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, pixels + (width * bytes_per_pixel) * y, (width * bytes_per_pixel)); memcpy((unsigned char *)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, pixels + (width * bytes_per_pixel) * y, (width * bytes_per_pixel));
pTexture->UnlockRect(0); g_FontTexture->UnlockRect(0);
// Store our identifier // Store our identifier
io.Fonts->TexID = (void *)pTexture; io.Fonts->TexID = (void *)g_FontTexture;
// Cleanup (don't clear the input data if you want to append new fonts later) // Cleanup (don't clear the input data if you want to append new fonts later)
io.Fonts->ClearInputData(); io.Fonts->ClearInputData();
@ -242,12 +258,6 @@ bool ImGui_ImplDX9_CreateDeviceObjects()
if (!g_pd3dDevice) if (!g_pd3dDevice)
return false; return false;
if (g_pd3dDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
return false;
if (g_pd3dDevice->CreateIndexBuffer(INDEX_BUFFER_SIZE * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL) < 0)
return false;
ImGui_ImplDX9_CreateFontsTexture(); ImGui_ImplDX9_CreateFontsTexture();
return true; return true;
} }
@ -275,7 +285,7 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
void ImGui_ImplDX9_NewFrame() void ImGui_ImplDX9_NewFrame()
{ {
if (!g_pVB) if (!g_FontTexture)
ImGui_ImplDX9_CreateDeviceObjects(); ImGui_ImplDX9_CreateDeviceObjects();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();