From 20bb6270bca6ac82f768c2b95ac46cd773ad6231 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 11 Jan 2015 17:17:43 +0000 Subject: [PATCH] Examples: all supports TextureID in renderer, added LoadFontTexture() function. --- examples/directx11_example/main.cpp | 84 ++++++++++++++++------------- examples/directx9_example/main.cpp | 62 +++++++++++++-------- examples/opengl3_example/main.cpp | 33 +++++++----- examples/opengl_example/main.cpp | 33 +++++++----- 4 files changed, 129 insertions(+), 83 deletions(-) diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index e718d14c7..3e3a26548 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -26,7 +26,6 @@ static ID3D11Buffer* g_pVertexConstantBuffer = NULL; static ID3D10Blob * g_pPixelShaderBlob = NULL; static ID3D11PixelShader* g_pPixelShader = NULL; -static ID3D11ShaderResourceView*g_pFontTextureView = NULL; static ID3D11SamplerState* g_pFontSampler = NULL; static ID3D11BlendState* g_blendState = NULL; @@ -122,7 +121,6 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c g_pd3dDeviceImmediateContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); g_pd3dDeviceImmediateContext->PSSetShader(g_pPixelShader, NULL, 0); - g_pd3dDeviceImmediateContext->PSSetShaderResources(0, 1, &g_pFontTextureView); g_pd3dDeviceImmediateContext->PSSetSamplers(0, 1, &g_pFontSampler); // Setup render state @@ -139,6 +137,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c { const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; const D3D11_RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w }; + g_pd3dDeviceImmediateContext->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->texture_id); g_pd3dDeviceImmediateContext->RSSetScissorRects(1, &r); g_pd3dDeviceImmediateContext->Draw(pcmd->vtx_count, vtx_offset); vtx_offset += pcmd->vtx_count; @@ -324,7 +323,8 @@ void CleanupDevice() // InitImGui if (g_pFontSampler) g_pFontSampler->Release(); - if (g_pFontTextureView) g_pFontTextureView->Release(); + if (ID3D11ShaderResourceView* font_texture_view = (ID3D11ShaderResourceView*)ImGui::GetIO().Font->TexID) + font_texture_view->Release(); if (g_pVB) g_pVB->Release(); // InitDeviceD3D @@ -379,6 +379,45 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, msg, wParam, lParam); } +void LoadFontTexture(ImFont* font) +{ + IM_ASSERT(font && font->IsLoaded()); + + // Create texture + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = font->TexWidth; + desc.Height = font->TexHeight; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + + ID3D11Texture2D *pTexture = NULL; + D3D11_SUBRESOURCE_DATA subResource; + subResource.pSysMem = font->TexPixels; + subResource.SysMemPitch = desc.Width * 1; + subResource.SysMemSlicePitch = 0; + g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); + + // Create texture view + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory(&srvDesc, sizeof(srvDesc)); + srvDesc.Format = DXGI_FORMAT_A8_UNORM; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + srvDesc.Texture2D.MostDetailedMip = 0; + ID3D11ShaderResourceView* font_texture_view = NULL; + g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &font_texture_view); + pTexture->Release(); + + // Store ID + font->TexID = (void *)font_texture_view; +} + void InitImGui() { RECT rect; @@ -430,39 +469,7 @@ void InitImGui() io.Font->LoadDefault(); //io.Font->LoadFromFileTTF("myfont.ttf", font_size_px, ImFont::GetGlyphRangesDefault()); //io.Font->DisplayOffset.y += 0.0f; - IM_ASSERT(io.Font->IsLoaded()); - - // Copy font texture - { - D3D11_TEXTURE2D_DESC desc; - ZeroMemory(&desc, sizeof(desc)); - desc.Width = io.Font->TexWidth; - desc.Height = io.Font->TexHeight; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - - ID3D11Texture2D *pTexture = NULL; - D3D11_SUBRESOURCE_DATA subResource; - subResource.pSysMem = io.Font->TexPixels; - subResource.SysMemPitch = desc.Width * 1; - subResource.SysMemSlicePitch = 0; - g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); - - // Create texture view - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - ZeroMemory(&srvDesc, sizeof(srvDesc)); - srvDesc.Format = DXGI_FORMAT_A8_UNORM; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = desc.MipLevels; - srvDesc.Texture2D.MostDetailedMip = 0; - g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); - pTexture->Release(); - } + LoadFontTexture(io.Font); // Create texture sampler { @@ -563,6 +570,11 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int) show_test_window ^= ImGui::Button("Test Window"); show_another_window ^= ImGui::Button("Another Window"); + static ImFont* font2 = NULL; + if (!font2) { font2 = new ImFont(); font2->LoadFromFileTTF("../../extra_fonts/ArialUni.ttf", 30.0f); LoadFontTexture(font2); } + ImGui::Image(font2->TexID, ImVec2((float)font2->TexWidth, (FLOAT)font2->TexHeight)); + //ImGui::GetWindowDrawList()->AddText(font2, 30.0f, ImGui::GetCursorScreenPos(), 0xFFFFFFFF, "Another font"); + // Calculate and show frame rate static float ms_per_frame[120] = { 0 }; static int ms_per_frame_idx = 0; diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index f826d8c9b..afec7ae10 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -14,7 +14,6 @@ static HWND hWnd; static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices -static LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture struct CUSTOMVERTEX { D3DXVECTOR3 pos; @@ -70,16 +69,13 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true ); - - // Setup texture - g_pd3dDevice->SetTexture( 0, g_pTexture ); - g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE ); - g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); - g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); + g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); + g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE ); + g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); + g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); // Setup orthographic projection matrix D3DXMATRIXA16 mat; @@ -99,6 +95,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c { const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; const RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w }; + g_pd3dDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)pcmd->texture_id ); g_pd3dDevice->SetScissorRect(&r); g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3); vtx_offset += pcmd->vtx_count; @@ -133,7 +130,8 @@ void CleanupDevice() if (g_pVB) g_pVB->Release(); // InitDeviceD3D - if (g_pTexture) g_pTexture->Release(); + if (LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)ImGui::GetIO().Font->TexID) + tex->Release(); if (g_pd3dDevice) g_pd3dDevice->Release(); if (g_pD3D) g_pD3D->Release(); } @@ -176,6 +174,31 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, msg, wParam, lParam); } +void LoadFontTexture(ImFont* font) +{ + IM_ASSERT(font && font->IsLoaded()); + + LPDIRECT3DTEXTURE9 pTexture = NULL; + if (D3DXCreateTexture(g_pd3dDevice, font->TexWidth, font->TexHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &pTexture) < 0) + { + IM_ASSERT(0); + return; + } + + // Copy pixels + D3DLOCKED_RECT tex_locked_rect; + if (pTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) + { + IM_ASSERT(0); + return; + } + for (int y = 0; y < font->TexHeight; y++) + memcpy((unsigned char *)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, font->TexPixels + font->TexWidth * y, font->TexWidth); + pTexture->UnlockRect(0); + + font->TexID = (void *)pTexture; +} + void InitImGui() { RECT rect; @@ -219,15 +242,7 @@ void InitImGui() io.Font->LoadDefault(); //io.Font->LoadFromFileTTF("myfont.ttf", font_size_px, ImFont::GetGlyphRangesDefault()); //io.Font->DisplayOffset.y += 0.0f; - IM_ASSERT(io.Font->IsLoaded()); - - // Copy font texture - if (D3DXCreateTexture(g_pd3dDevice, io.Font->TexWidth, io.Font->TexHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &g_pTexture) < 0) { IM_ASSERT(0); return; } - D3DLOCKED_RECT tex_locked_rect; - if (g_pTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) { IM_ASSERT(0); return; } - for (int y = 0; y < io.Font->TexHeight; y++) - memcpy((unsigned char *)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, io.Font->TexPixels + io.Font->TexWidth * y, io.Font->TexWidth); - g_pTexture->UnlockRect(0); + LoadFontTexture(io.Font); } INT64 ticks_per_second = 0; @@ -313,6 +328,11 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int) show_test_window ^= ImGui::Button("Test Window"); show_another_window ^= ImGui::Button("Another Window"); + static ImFont* font2 = NULL; + if (!font2) { font2 = new ImFont(); font2->LoadFromFileTTF("../../extra_fonts/ArialUni.ttf", 30.0f); LoadFontTexture(font2); } + ImGui::Image(font2->TexID, ImVec2((float)font2->TexWidth, (FLOAT)font2->TexHeight)); + //ImGui::GetWindowDrawList()->AddText(font2, 30.0f, ImGui::GetCursorScreenPos(), 0xFFFFFFFF, "Another font"); + // Calculate and show frame rate static float ms_per_frame[120] = { 0 }; static int ms_per_frame_idx = 0; diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index ff8122f9c..ecf31fa90 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -17,7 +17,6 @@ #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) static GLFWwindow* window; -static GLuint fontTex; static bool mousePressed[2] = { false, false }; // Shader variables @@ -43,10 +42,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); - - // Setup texture glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, fontTex); // Setup orthographic projection matrix const float width = ImGui::GetIO().DisplaySize.x; @@ -96,6 +92,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c const ImDrawCmd* pcmd_end = cmd_list->commands.end(); for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++) { + glBindTexture(GL_TEXTURE_2D, (GLuint)pcmd->texture_id); glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); vtx_offset += pcmd->vtx_count; @@ -242,6 +239,19 @@ void InitGL() glBindBuffer(GL_ARRAY_BUFFER, 0); } +void LoadFontTexture(ImFont* font) +{ + IM_ASSERT(font && font->IsLoaded()); + + GLuint tex_id; + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, font->TexWidth, font->TexHeight, 0, GL_RED, GL_UNSIGNED_BYTE, font->TexPixels); + font->TexID = (void *)tex_id; +} + void InitImGui() { ImGuiIO& io = ImGui::GetIO(); @@ -274,15 +284,7 @@ void InitImGui() io.Font->LoadDefault(); //io.Font->LoadFromFileTTF("myfont.ttf", font_size_px, ImFont::GetGlyphRangesDefault()); //io.Font->DisplayOffset.y += 0.0f; - IM_ASSERT(io.Font->IsLoaded()); - - // Copy font texture - glGenTextures(1, &fontTex); - glBindTexture(GL_TEXTURE_2D, fontTex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - IM_ASSERT(io.Font->IsLoaded()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, io.Font->TexWidth, io.Font->TexHeight, 0, GL_RED, GL_UNSIGNED_BYTE, io.Font->TexPixels); + LoadFontTexture(io.Font); } void UpdateImGui() @@ -342,6 +344,11 @@ int main(int argc, char** argv) show_test_window ^= ImGui::Button("Test Window"); show_another_window ^= ImGui::Button("Another Window"); + static ImFont* font2 = NULL; + if (!font2) { font2 = new ImFont(); font2->LoadFromFileTTF("../../extra_fonts/ArialUni.ttf", 30.0f); LoadFontTexture(font2); } + ImGui::Image(font2->TexID, ImVec2((float)font2->TexWidth, (float)font2->TexHeight)); + //ImGui::GetWindowDrawList()->AddText(font2, 30.0f, ImGui::GetCursorScreenPos(), 0xFFFFFFFF, "Another font"); + // Calculate and show frame rate static float ms_per_frame[120] = { 0 }; static int ms_per_frame_idx = 0; diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp index 2ceb6aa11..2edb865c7 100644 --- a/examples/opengl_example/main.cpp +++ b/examples/opengl_example/main.cpp @@ -17,7 +17,6 @@ #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) static GLFWwindow* window; -static GLuint fontTex; static bool mousePressed[2] = { false, false }; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) @@ -41,9 +40,6 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - - // Setup texture - glBindTexture(GL_TEXTURE_2D, fontTex); glEnable(GL_TEXTURE_2D); // Setup orthographic projection matrix @@ -70,6 +66,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; + glBindTexture(GL_TEXTURE_2D, (GLuint)pcmd->texture_id); glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); vtx_offset += pcmd->vtx_count; @@ -151,6 +148,19 @@ void InitGL() glewInit(); } +void LoadFontTexture(ImFont* font) +{ + IM_ASSERT(font && font->IsLoaded()); + + GLuint tex_id; + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, font->TexWidth, font->TexHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, font->TexPixels); + font->TexID = (void *)tex_id; +} + void InitImGui() { ImGuiIO& io = ImGui::GetIO(); @@ -183,15 +193,7 @@ void InitImGui() io.Font->LoadDefault(); //io.Font->LoadFromFileTTF("myfont.ttf", font_size_px, ImFont::GetGlyphRangesDefault()); //io.Font->DisplayOffset.y += 0.0f; - IM_ASSERT(io.Font->IsLoaded()); - - // Copy font texture - glGenTextures(1, &fontTex); - glBindTexture(GL_TEXTURE_2D, fontTex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - IM_ASSERT(io.Font->IsLoaded()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, io.Font->TexWidth, io.Font->TexHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, io.Font->TexPixels); + LoadFontTexture(io.Font); } void UpdateImGui() @@ -250,6 +252,11 @@ int main(int argc, char** argv) show_test_window ^= ImGui::Button("Test Window"); show_another_window ^= ImGui::Button("Another Window"); + static ImFont* font2 = NULL; + if (!font2) { font2 = new ImFont(); font2->LoadFromFileTTF("../../extra_fonts/ArialUni.ttf", 30.0f); LoadFontTexture(font2); } + ImGui::Image(font2->TexID, ImVec2((float)font2->TexWidth, (float)font2->TexHeight)); + //ImGui::GetWindowDrawList()->AddText(font2, 30.0f, ImGui::GetCursorScreenPos(), 0xFFFFFFFF, "Another font"); + // Calculate and show frame rate static float ms_per_frame[120] = { 0 }; static int ms_per_frame_idx = 0;