소스 검색

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

ocornut 10 년 전
부모
커밋
698c7cae85
1개의 변경된 파일24개의 추가작업 그리고 14개의 파일을 삭제
  1. 24 14
      examples/directx9_example/imgui_impl_dx9.cpp

+ 24 - 14
examples/directx9_example/imgui_impl_dx9.cpp

@@ -16,8 +16,8 @@ static INT64                    g_TicksPerSecond = 0;
 static LPDIRECT3DDEVICE9        g_pd3dDevice = NULL;
 static LPDIRECT3DVERTEXBUFFER9  g_pVB = NULL;
 static LPDIRECT3DINDEXBUFFER9   g_pIB = NULL;
-static int                      VERTEX_BUFFER_SIZE = 20000;     // TODO: Make buffers smaller and grow dynamically as needed.
-static int                      INDEX_BUFFER_SIZE = 40000;      // TODO: Make buffers smaller and grow dynamically as needed.
+static LPDIRECT3DTEXTURE9       g_FontTexture = NULL;
+static int                      g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
 
 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)
 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
     CUSTOMVERTEX* vtx_dst;
     ImDrawIdx* idx_dst;
@@ -213,24 +229,24 @@ static void ImGui_ImplDX9_CreateFontsTexture()
     io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height, &bytes_per_pixel);
 
     // Create DX9 texture
-    LPDIRECT3DTEXTURE9 pTexture = NULL;
-    if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &pTexture) < 0)
+    g_FontTexture = NULL;
+    if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
     {
         IM_ASSERT(0);
         return;
     }
     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); 
         return; 
     }
     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));
-    pTexture->UnlockRect(0);
+    g_FontTexture->UnlockRect(0);
 
     // 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)
     io.Fonts->ClearInputData();
@@ -242,12 +258,6 @@ bool ImGui_ImplDX9_CreateDeviceObjects()
     if (!g_pd3dDevice)
         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();
     return true;
 }
@@ -275,7 +285,7 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
 
 void ImGui_ImplDX9_NewFrame()
 {
-    if (!g_pVB)
+    if (!g_FontTexture)
         ImGui_ImplDX9_CreateDeviceObjects();
 
     ImGuiIO& io = ImGui::GetIO();